MySQL MHA詳細搭建過程

ywxj_001發表於2019-08-21

環境:

用3臺伺服器搭建MySQL MHA

主節點:192.168.157.128   CentOS 7.6
資料庫:mysql-5.7.27-linux-glibc2.12-x86_64
從節點:192.168.157.129   CentOS 7.6
資料庫:mysql-5.7.27-linux-glibc2.12-x86_64
管理節點:192.168.157.130   CentOS 7.6
資料庫:mysql-5.7.27-linux-glibc2.12-x86_64


1、3臺伺服器都安裝作業系統 CentOS 7.6


2、 MySQL  安裝以及主從設定


三臺機器都要做:
關閉防火牆:
systemctl stop firewalld.service
systemctl disable firewalld .service
systemctl status firewalld.service


#關閉selinux
setenforce 0
PS:
臨時關閉:
[root@localhost ~]#  getenforce
Enforcing
[root@localhost ~]#  setenforce 0
[root@localhost ~]#  getenforce
Permissive
永久關閉:
[root@localhost ~]# vi /etc/sysconfig/selinux
SELINUX=enforcing 改為 SELINUX=disabled
重啟服務reboot


#刪除預裝mysql

rpm -qa|grep mariadb

rpm -e --nodeps mariadb-libs-5.5.60-1.el7_5.x86_64


#解壓
tar zxvf mysql-5.7.27-linux-glibc2.12-x86_64.tar.gz  -C  /opt
#改名
mv mysql-5.7.27-linux-glibc2.12-x86_64 mysql
#新建mysql使用者
useradd mysql
passwd mysql
#
#初始化
mkdir -p /opt/mysql/data
chown -R mysql:mysql /opt/

chown -R mysql:mysql /opt/


#建立相關資料夾
mkdir -p /opt/mysql/tmp
mkdir -p /opt/mysql/log
#更改資料夾許可權
chown -R mysql:mysql /opt/mysql
#建立mysql.err檔案
[root@mha02 opt]# cd mysql/log
[root@mha02 log]# ll
total 0
[root@mha02 log]# touch mysql.err
[root@mha02 log]# chown -R mysql:mysql mysql.err



#初始化資料庫

mysql/bin/mysqld --initialize --user=mysql --basedir=/opt/mysql/ --datadir=/opt/mysql/data/


#簡單配置
ln -s /opt/mysql/bin/mysql /usr/bin
ln -s /opt/mysql/bin/mysqladmin /usr/bin
ln -s /opt/mysql/bin/mysqldump /usr/bin


#mysql配置檔案,每個伺服器的 server-id要不同
vi /etc/my.cnf
[client]
port=3306
socket=/opt/mysql/tmp/mysql.sock
[mysqld]
user=mysql
datadir=/opt/mysql/data
basedir=/opt/mysql
socket=/opt/mysql/tmp/mysql.sock
log-error=/opt/mysql/log/mysql.err
pid-file=/opt/mysql/tmp/mysqld.pid
#  id每臺機器要不同
server-id = 186
#做雙主時的設定,保證另一個主庫操作能寫入
log_slave_updates
#從庫不會跟著主庫重啟
skip-slave-start
#開啟gtid模式,5.7特有
gtid_mode = on
enforce_gtid_consistency = 1
log_slave_updates = 1
#半同步複製模式
plugin_load = "rpl_semi_sync_master=semisync_master.so;rpl_semi_sync_slave=semisync_slave.so"
loose_rpl_semi_sync_master_enabled = 1
loose_rpl_semi_sync_slave_enabled = 1
loose_rpl_semi_sync_master_timeout = 5000
#指定binlog與relay地址
log-bin   = /opt/mysql/log/mysql-bin
relay-log = /opt/mysql/log/mysql-relay-bin
#不要同步哪些庫,較好的寫法
replicate-wild-ignore-table=mysql.%
replicate-wild-ignore-table=test.%
replicate-wild-ignore-table=information_schema.%


#開啟資料庫
/opt/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf &


#登入資料庫,修改root密碼
mysql -p
之前初始化的密碼
mysql> alter user root@'localhost' identified by '123456';
mysql>flush privileges;


增加root遠端登入使用者:
mysql> create user root@'%' identified by '123456';
Query OK, 0 rows affected (0.01 sec)
mysql> grant all privileges on *.* to root@'%';
mysql> flush privileges;


關閉MySQL服務:
[root@mha01 bin]# mysqladmin -uroot -p -S /opt/mysql/tmp/mysql.sock shutdown

開啟MySQL服務:

/opt/mysql/bin/mysqld_safe --defaults-file=/etc/my.cnf &


同樣在其餘兩個伺服器上安裝MySQL服務。


#登入mysql,在三個mysql中都配置賬號,注意,不能把mysql庫作為binlog複製庫,否則新建的slave賬號會報錯
#建立slave賬號
mysql> grant replication slave,replication client on *.* to 'repl'@'%' identified by '123456';
#建立mha管理賬號
mysql> grant all on *.* to 'monitor'@'%' identified by '123456';
#在slave節點上執行
mysql> set global read_only=1;
#由於從庫隨時會提升成主庫,不能寫在配置檔案裡
#MHA需要透過relay-log去校驗slave是否資料讀寫一致,不要寫進配置檔案,所有mysql節點執行
mysql>set global relay_log_purge=0;
#設定主從
1、主庫檢視master
mysql> show master status;
+------------------+----------+--------------+------------------+------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000002 |      932 |              |                  | 58d16735-bdae-11e9-b8d3-000c29f97b79:1-8 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)
2、slave庫執行
mysql> change master to  
master_host='192.168.157.128',
master_user='repl',
master_password='123456',
master_log_file='mysql-bin.000002',
master_log_pos=932;
用GTID啟動slave:
mysql>change master to
master_host='192.168.157.128',
master_user='repl',
master_password='123456',
master_auto_position=1;
mysql> start slave;
Query OK, 0 rows affected (0.02 sec)
mysql> show slave status\G;
             Relay_Master_Log_File: mysql-bin.000003
             Slave_IO_Running: Yes
             Slave_SQL_Running: Yes
看到兩個YES,即代表主從成功。


3、搭建MHA

三臺主機ssh互信
注意:三臺主機都要做,並且要本機對本機的SSH認證
#因為mha需要manager對自己ssh免密登入
ssh-keygen -t rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub  root@192.168.157.128
ssh-copy-id -i ~/.ssh/id_rsa.pub  192.168.157.129
ssh-copy-id -i ~/.ssh/id_rsa.pub  192.168.157.130



MHA安裝配置:

三臺機器都要做:
在/opt目錄下安裝:
在所有節點安裝MHA node所需的perl模組,如下:
#CentOS 6 下載點
rpm -ivh http: // dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
#CentOS 7 下載點
rpm -ivh 
#安裝所需控制元件
#yum  install  -y  perl-DBD-MySQL  perl-Config-Tiny  perl-Log-Dispatch  perl-Parallel-ForkManager  perl-Time-HiRes   
yum install -y perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager perl-YAML-Tiny perl-PAR-Dist perl-Module-ScanDeps perl-Module-CoreList perl-Module-Build perl-CPAN perl-CPANPLUS perl-File-Remove perl-Module-Install
#下載node和manager軟體
# node git 地址:
# manager git 地址:
# node 所有機器都要安裝
# manager 只需要管理節點安裝
yum -y install git
git clone .git
#管理節點安裝
git clone 
安裝MHA
cd /opt/mha4mysql-node
perl Makefile.PL
make && make install
cd /opt/mha4mysql-manager
perl Makefile.PL
make && make install
注意:在perl Makefile.PL時,可能會出現類似Can't locate inc/Module/XXX.pm in @INC的報錯
          這是由於缺少元件造成的,只需要安裝相應附件
          例: yum -y install perl-Module-XXX  一般有對應的名字外掛,安裝就好
#node方面的都已經配好了,然後是manager節點的操作
配置 Manager 節點,以下步驟都是Manager節點操作
#新建MHA配置檔案
mkdir /var/log/mha/app1 -p
touch /var/log/mha/app1/manager.log
vi /etc/masterha.cnf
[server default]
#監控使用者
user=monitor
password=123456
#ssh 使用者
ssh_user=root
#slave 使用者
repl_user=repl
repl_password=123456
#ping 三次不通判斷失聯
ping_interval=3
#使用其他主機去ping,判斷是否主機本身故障
secondary_check_script=masterha_secondary_check -s 192.168.157.128 -s 192.168.157.129 -s 192.168.157.130
#相關指令碼位置,都要自建,預設是沒有的
master_ip_failover_script=/usr/local/bin/master_ip_failover
master_ip_online_change_script= /usr/local/bin/master_ip_online_change
report_script=/usr/local/bin/send_report
#指定MHA日誌目錄
manager_workdir=/var/log/mha/app1
manager_log=/var/log/mha/app1/manager.log
#指定bin-log位置
master_binlog_dir=/opt/mysql/log/
remote_workdir=/var/log/mha/mysqltmp
[server1]
hostname=192.168.157.128
port=3306
[server2]
hostname=192.168.157.129
port=3306
#是否無視落後進度讓他成為master
candidate_master=1
check_repl_delay=0
[server3]
hostname=192.168.157.130
#永遠不會成為master。多用於manager
no_master=1
port=3306


#配置VIP
#為了防止腦裂發生,推薦生產環境採用指令碼的方式來管理虛擬 ip,而不是使用 keepalived來完成


vi /usr/local/bin/master_ip_failover
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
       $command,       $ssh_user,      $orig_master_host,
       $orig_master_ip,$orig_master_port, $new_master_host, $new_master_ip,$new_master_port
);
#定義VIP變數
#此處修改VIP地址,預先選擇的VIP地址
my $vip = '192.168.157.197/24';
my $key = '1';
#修改ifconfig之後的網路卡名,其他地方都不要改動
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";
GetOptions(
       'command=s'             => \$command,
       'ssh_user=s'            => \$ssh_user,
       'orig_master_host=s'    => \$orig_master_host,
       'orig_master_ip=s'      => \$orig_master_ip,
       'orig_master_port=i'    => \$orig_master_port,
       'new_master_host=s'     => \$new_master_host,
       'new_master_ip=s'       => \$new_master_ip,
       'new_master_port=i'     => \$new_master_port,
);
exit &main();
sub main {
       print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";
       if ( $command eq "stop" || $command eq "stopssh" ) {
               my $exit_code = 1;
               eval {
                       print "Disabling the VIP on old master: $orig_master_host \n";
                       &stop_vip();
                       $exit_code = 0;
               };
               if ($@) {
                       warn "Got Error: $@\n";
                       exit $exit_code;
               }
               exit $exit_code;
       }
       elsif ( $command eq "start" ) {
       my $exit_code = 10;
       eval {
               print "Enabling the VIP - $vip on the new master - $new_master_host \n";
               &start_vip();
               $exit_code = 0;
       };
       if ($@) {
               warn $@;
               exit $exit_code;
               }
       exit $exit_code;
       }
       elsif ( $command eq "status" ) {
               print "Checking the Status of the script.. OK \n";
               exit 0;
       }
       else {
               &usage();
               exit 1;
       }
}
sub start_vip() {
       `ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
sub stop_vip() {
       return 0 unless ($ssh_user);
       `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}
sub usage {
       print
       "Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}



#配置報警郵件指令碼
#安裝郵件
yum install mailx -y
vi /etc/mail.rc
#修改mail配置檔案,在配置檔案最後新增
#郵箱地址
set from=ywzj_002
#郵箱的smtp地址
set smtp=smtp.163.com
#郵箱的使用者名稱
set smtp-auth-user=ywzj_002
#這個並非郵箱密碼,而是授權碼
set smtp-auth-password=pousheng123
set smtp-auth=login
vi /usr/local/bin/send_report
#!/bin/bash
source /root/.bash_profile
orig_master_host=`echo "$1" | awk -F = '{print $2}'`
new_master_host=`echo "$2" | awk -F = '{print $2}'`
new_slave_hosts=`echo "$3" | awk -F = '{print $2}'`
subject=`echo "$4" | awk -F = '{print $2}'`
body=`echo "$5" | awk -F = '{print $2}'`
email="ywzj_001@163.com"
tac /var/log/mha/app1/manager.log | sed -n 2p | grep 'successfully' > /dev/null
if [ $? -eq 0 ]
       then
       messages=`echo -e "MHA $subject 主從切換成功\n master:$orig_master_host -->
$new_master_host \n $body \n 當前從庫:$new_slave_hosts"`
       echo "$messages" | mail -s "Mysql 例項宕掉,MHA $subject 切換成功" $email >
>/tmp/mailx.log 2>&1
       else
       messages=`echo -e "MHA $subject 主從切換失敗\n master:$orig_master_host -->
$new_master_host \n $body" `
       echo "$messages" | mail -s ""Mysql 例項宕掉,MHA $subject 切換失敗"" $email
>>/tmp/mailx.log 2>&1
fi


#配置VIP更換指令碼
vi /usr/local/bin/master_ip_online_change
#預先選擇的VIP地址
vip=`echo '192.168.157.197/24'`
key=`echo '1'`
command=`echo "$1" | awk -F = '{print $2}'`
orig_master_host=`echo "$2" | awk -F = '{print $2}'`
new_master_host=`echo "$7" | awk -F = '{print $2}'`
orig_master_ssh_user=`echo "${12}" | awk -F = '{print $2}'`
new_master_ssh_user=`echo "${13}" | awk -F = '{print $2}'`
#修改網路卡名稱
stop_vip=`echo "ssh root@$orig_master_host /usr/sbin/ifconfig ens33:$key down"`
start_vip=`echo "ssh root@$new_master_host /usr/sbin/ifconfig ens33:$key $vip"`
if [ $command = 'stop' ]
 then
   echo -e "\n\n\n****************************\n"
   echo -e "Disabled thi VIP - $vip on old master: $orig_master_host \n"
   $stop_vip
   if [ $? -eq 0 ]
     then
       echo "Disabled the VIP successfully"
     else
       echo "Disabled the VIP failed"
   fi
   echo -e "***************************\n\n\n"
 fi
       if [ $command = 'start' -o $command = 'status' ]
 then
   echo -e "\n\n\n*************************\n"
   echo -e "Enabling the VIP - $vip on new master: $new_master_host \n"
   $start_vip
   if [ $? -eq 0 ]
     then
       echo "Enabled the VIP successfully"
     else
       echo "Enabled the VIP failed"
   fi
   echo -e "***************************\n\n\n"
fi
#賦予指令碼許可權
#*代表之前建立的三個指令碼
chmod 555 /usr/local/bin/*
chmod 555 /usr/local/bin/master_ip_failover
chmod 555 /usr/local/bin/master_ip_online_change
chmod 555 /usr/local/bin/send_report
#測試MHA設定是否正確
masterha_check_repl --conf=/etc/masterha.cnf



。。。

MySQL Replication Health is OK.

最後 顯示OK,才算正常,否則就要看報錯資訊,按照之前的操作配置,基本不會有錯誤。



#在主庫,而不是Manager管理口,配置VIP到網口
/usr/sbin/ifconfig ens33:1 192.168.157.197/24
注意:如果是最小化安裝,需yum ifconfig
          yum -y install net-tools



#在Manager節點操作
#啟動MHA
nohup masterha_manager --conf=/etc/masterha.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &
#檢查狀態
[root@mha03 bin]# masterha_check_status --conf=/etc/masterha.cnf
masterha (pid:15546) is running(0:PING_OK), master:192.168.157.128
#顯示OK則正常



測試切換功能以及主庫當機上線:

1、線上切換
#MHA 線上切換是 MHA 除了自動監控切換換提供的另外一種方式,多用於諸如硬體升級,MySQL 資料庫遷移等等。該方式提供快速切換和優雅的阻塞寫入,無需關閉原有伺服器,整個切換過程在 0.5-2s 的時間左右,大大減少了停機時間
注意:需要關閉mha監控才能執行
          A、老master上的vip已經正確生效了
          B、各個salve節點資料庫的sql_IO和sql_sql程式都正常(即YES)
                    show slave status\G;
          C、MHA指令碼不能執行,若已處於監控狀態,需要停掉它
                    masterha_stop --conf=/etc/masterha.cnf
#執行切換
#需要填寫新的master的IP
masterha_master_switch --conf=/etc/masterha.cnf --master_state=alive  --new_master_host=192.168.157.129  --orig_master_is_new_slave --running_updates_limit=10000 --interactive=0
masterha_master_switch --conf=/etc/masterha.cnf --master_state=alive  --new_master_host=192.168.157.128  --orig_master_is_new_slave --running_updates_limit=10000 --interactive=0
#MHA 線上切換基本步驟:
    a、檢測 MHA 配置置及確認當前 master
    b、決定新的 master
    c、阻塞寫入到當前 master
    d、等待所有從伺服器與現有 master 完成同步
    e、在新 master 授予寫許可權,以及並行切換從庫
    f、重置原 master 為新 master 的 slave
     g、線上切換不會刪除 /etc/masterha.cnf 配置檔案中原來老的 master 配置
注意:如果手動切換後,原來的配置如果想直接執行,需要在配置檔案中將master的地址改成新的IP,原Master主機的IP寫到slave中


2、自動切換
    第一:要實現自動 Failover,必須先啟動 MHA Manager,否則無法自動切換
     A、殺掉主庫 mysql 程式,模擬主庫發生故障,進行自動 failover 操作
    B、看 MHA 切換日誌,瞭解整個切換過程
        tailf  /var/log/mha/app1/manager.log
    第二:從上面的輸出可以看出整個 MHA 的切換過程,共包括以下的步驟:
    1).配置檔案檢查階段,這個階段會檢查整個叢集配置檔案配置
    2).當機的 master 處理,這個階段包括虛擬 ip 摘除操作,主機關機操作(由於沒有定義power_manager指令碼,不會關機)
    3).複製 dead maste 和最新 slave 相差的 relay log,並儲存到 MHA Manger 具體的目錄下
    4).識別含有最新更新的 slave
    5).應用從 master 儲存的二進位制日誌事件(binlog events)(這點資訊對於將故障master修復後加入叢集很重要)
    6).提升一個 slave 為新的 master 進行復制
    7).使其他的 slave 連線新的 master 進行復制
    第三:切換完成後,關注如下變化:
    1、 vip 自動從原來的 master 切換到新的 master,同時,manager 節點的監控程式自動退出。
    2、在日誌目錄(/var/log/mha/app1)產生一個 app1.failover.complete 檔案
   3、/etc/mha/app1.cnf 配置檔案中原來老的 master 配置被刪除。


4、切換一次後,MHA監控程式會stop,需要重新修改配置檔案後再次重啟
#會發現此時192.168.157.129從庫已經提升為主庫,並且MHA Manager已停止執行。
重要:將主庫重新恢復加入到佇列的操作
1)、修改 manager 配置檔案(只針對自動切換的,線上切換不會刪除配置)
    #將如下內容新增到/etc/masterha.cnf中
    [server1]
    hostname=192.168.157.128
    candidate_master=1
   port=3306
    master_binlog_dir=/opt/mysql/log/
#由於之前主庫當機後,MHA會自動將配置檔案內當機的主庫資訊刪除
#主庫恢復如需重新加入,需要在配置檔案新增原主庫資訊,並作為從庫加入
2)、修復老的 master,然後設定為 slave
    從自動切換時刻的 MHA 日誌上可以發現類似如下資訊:
    #意思是說,如果 Master 主機修復好了,可以在修復好後的 Master 上執行 CHANGE MASTER操作,作為新的 slave 庫。
[root@mha03 app1]# cat  manager.log|grep CHANGE
[root@mha03 app1]# pwd
/var/log/mha/app1
# GTID沒有開啟
    Sat May 27 14:59:17 2017 - [info] All other slaves should start replication from here. Statement
    should be: CHANGE MASTER TO MASTER_HOST='10.0.40.187', MASTER_PORT=3306,
    MASTER_LOG_FILE='mysql-bin.000009',  MASTER_LOG_POS=120 , MASTER_USER='repl',
    MASTER_PASSWORD='xxx';
 # GTID開啟
    Sat May 19 05:00:48 2018 - [info]  All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='10.0.40.187', MASTER_PORT=3306,  MASTER_AUTO_POSITION=1 , MASTER_USER='repl', MASTER_PASSWORD='xxx';
Thu Aug 15 15:31:18 2019 - [info]  All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='192.168.157.129', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='xxx';
Thu Aug 15 15:31:19 2019 - [info]  Executed CHANGE MASTER.

    

在老的 master 執行如下命令:(具體執行哪條,根據上面輸出來確定,區別是一個有日誌的定位,一個是自動定位)
   # GTID沒有開啟,按照日誌的log-file和log-pos填寫
    mysql> change master to master_host='10.0.40.187',master_user='repl',master_password='123456',master_log_file='mysql-bin.0000124',master_log_pos=120;
   # GTID開啟,只能使用 MASTER_AUTO_POSITION=1 ,否則報錯
    mysql> change master to master_host='10.0.40.187',master_user='repl',master_password='123456', MASTER_AUTO_POSITION=1 ;
CHANGE MASTER TO MASTER_HOST='192.168.157.129', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123456';
mysql> CHANGE MASTER TO MASTER_HOST='192.168.157.129', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123456';
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G;


 #這樣,資料就開始同步到老的 master 上了。此時老的 master 已經重新加入叢集,變成 mha叢集中的一個 slave 角色了。


(3)、在 manger 節點上重新啟動監控程式

nohup masterha_manager --conf=/etc/masterha.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &


Done.



來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/22996654/viewspace-2654437/,如需轉載,請註明出處,否則將追究法律責任。

相關文章