1. 程式人生 > >使用MHA實現mysql高可用性(centos7.5+mysql5.7.23+MHA0.58)

使用MHA實現mysql高可用性(centos7.5+mysql5.7.23+MHA0.58)

一、MHA概述

1、MHA

         MHA(Master High Availability)事由日本人DeNA開發的一套MySQL高可用性環境下故障切換和主從提升的軟體,目前在MySQL高可用方面是一個相對成熟的解決方案。在MySQL故障切換過程中,MHA能做到在0~30秒之內自動完成資料庫的故障切換操作,並且在進行故障切換的過程中,MHA能在最大程度上保證資料的一致性,以達到真正意義上的高可用。

2、MHA的主要功能

(1)自動故障檢測和自動故障轉移

(2)互動式(手動)故障轉移

(3)線上切換Master到不同的主機

3、MHA的優勢

(1)自動故障轉移快

(2)主庫崩潰不存在資料一致性問題

(3)配置不需要對當前mysql環境做重大修改

(4)不需要新增額外的伺服器(僅一臺manager就可管理上百個replication)

(5)效能優秀,可工作在半同步複製和非同步複製

(6)只要replication支援的儲存引擎,MHA都支援,不會侷限於innodb

4、MHA的組成部分

         MHA由Manager節點和Node節點組成;MHA Manager可以單獨部署在一臺獨立的機器上管理多個master-slave叢集,也可以部署在一臺slave節點上。MHA Node執行在每臺MySQL伺服器上。

5、MHA工作原理

(1)MHA Manager會定時探測叢集中的master節點

(2)當master出現故障時,從宕機崩潰的master儲存二進位制日誌事件(binlog events);

(3)識別含有最新更新的slave;

(4)應用差異的中繼日誌(relay log)到其他的slave;

(5)應用從master儲存的二進位制日誌事件(binlog events);

(6)提升一個slave為新的master,使其他的slave連線新的master進行復制;

二、MHA安裝部署

1、環境準備

(1)環境準備

主機名

IP地址

節點資訊

資料庫版本

系統版本

MYSQL01

192.168.16.151

Mysql主節點

5.7.23

centos7.5

MYSQL02

192.168.16.152

Mysql從節點

5.7.23

centos7.5

MYSQL03

192.168.16.153

Mysql從節點

5.7.23

centos7.5

MANAGER

192.168.16.155

MHA manager節點

 

centos7.5

(2)拓撲結構

(3)設定主機名並互相做祕鑰的認證

         首先需要在各個節點上配置各個主機的主機名,使各節點通過主機名能夠互相解析。

]# tail -4f /etc/hosts
192.168.16.151 MYSQL01
192.168.16.152 MYSQL02
192.168.16.152 MYSQL03
192.168.16.155 MANAGER

         由於MHA manager通過SSH訪問所有的node節點,各個node節點也同樣通過SSH來相互發送不同的relay log 檔案,所以要在每一個node和manager上配置SSH無密碼登陸。

# 在每個節點上分別生成祕鑰對
[[email protected] ~]# ssh-keygen
# 每臺節點分別將自己的公鑰傳送到另外的三臺節點
]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]

2、配置mysql主從環境

(1)配置mysql主節點及從節點

         Mysql主節點的配置如下:

[mysqld]
log-bin=mysql-bin 
server-id=1
replicate-do-db=course
character-set-server=utf8
init_connect='SET AUTOCOMMIT=0;set names utf8'

         mysql兩臺slave節點的配置如下:

[mysqld]
log-bin=mysql-bin 
server-id=2|3     #兩個節點的id配置不同
replicate-do-db=course   # 只同步course庫
# 更新資料的語句也記錄在slave自己的bin log中
log-slave-updates=true
# 設定relay_log的清除方式
relay_log_purge=0 
skip-slave-start=1
# 設定字符集及連線客戶端字符集
character-set-server=utf8
init_connect='SET AUTOCOMMIT=0;set names utf8'

(2)建立用於複製的使用者

         由於同步資料時將所有的資料都同步到了主庫,所有建立用於同步的使用者時只需在主庫建立,如果同步時不同步”mysql”庫,需要在三臺資料庫主機上分別建立用於複製的使用者。

# 建立用於複製的使用者
mysql> CREATE USER 'repl'@'192.168.16.%' IDENTIFIED BY 'replication';   
mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.16.%';

(3)同步資料

         1)獲取主庫的bin log資訊以及備份主庫

# 將主庫鎖定
mysql> FLUSH TABLES WITH READ LOCK;
# 獲取bin log日誌資訊
mysql> show master status\G
*************************** 1. row ***************************
             File: mysql-bin.000006
         Position: 4838
# 備份庫
]# mysqldump --all-databases --master-data -u root -p > course.sql
# 登入主庫釋放鎖
mysql>  unlock tables;
# 將備份檔案傳到從庫
]# scp course.sql [email protected]:/data/
]# scp course.sql [email protected]:/data/

         2)在從庫上匯入資料並開啟主從複製

# 在兩臺slave上分別匯入資料
]# mysql -uroot -p </data/mysql.sql
# 登入兩臺從庫分別配置同步
mysql> CHANGE MASTER TO
    -> MASTER_HOST='192.168.16.151',
    -> MASTER_PORT=3306,
    -> MASTER_USER='repl',
    -> MASTER_PASSWORD='replication',
    -> MASTER_LOG_FILE='mysql-bin.000006',
    -> MASTER_LOG_POS=4838;
# 開啟同步
mysql> start slave;

(4)設定mysql程式及binglog程式的軟連線

         雖然mysql程式已經加入了環境變數,如果預設路徑下mysql客戶端不存在在使用MHA時會報錯。

]# ln -s /usr/local/mysql/bin/mysql /usr/bin/mysql
]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/local/bin/mysqlbinlog

3、安裝MHA

(1)在各節點上安裝mha4mysql-node

         在四臺機器上上分別安裝mha4mysql-node。

         mha4mysql-node下載地址:https://github.com/yoshinorim/mha4mysql-node/releases/tag/v0.58

         mha4mysql-manager下載地址:https://github.com/yoshinorim/mha4mysql-manager/releases/tag/v0.58

# 安裝net-tools,最小化安裝的centos7中沒有一些網路管理工具
]# yum install –y net-tools
# 安裝epel yum源
]# yum install epel-release
# 在安裝前先安依賴軟體
]# yum install –y perl-DBD-MySQL
# 安裝mha4mysql-node
]# rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm

(3)在管理節點上安裝manage節點

# 在管理節點安裝依賴軟體
]# yum install -y perl-Config-Tiny perl-Log-Dispatch  perl-Parallel-ForkManager
# 在管理節點安裝mha4mysql-manager
]# rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

(4)manager管理工具

         在manager節點安裝完成後會生成一些管理工具,manager的主要管理工具有:

         masterha_check_ssh:檢查MHA的SSH配置狀況

         masterha_check_repl:檢查MySQL複製狀況

         masterha_manger:啟動MHA

         masterha_check_status:檢測當前MHA執行狀態

         masterha_master_monitor:檢測master是否宕機

         masterha_master_switch:控制故障轉移(自動或者手動)

         masterha_conf_host:新增或刪除配置的server資訊

4、配置MHA

(1)配置MHA

         MHA管理端和客戶端安裝完成後,在管理端需要建立MHA的配置檔案,配置檔案內容如下:

# 建立manager工作目錄
]# mkdir /data/manager –p
# manager的配置檔案
[[email protected] ~]# cat /etc/manager/manager.conf 
[server default] 
user=root 
password=dayi123
ssh_user=root 
manager_workdir=/data/manager
remote_workdir=/tmp
repl_user=repl 
repl_password=replication 
[server1] 
hostname=MYSQL01
port=3306 
master_binlog_dir=/data/mysql/data

[server2] 
hostname=MYSQL02
port=3306 
master_binlog_dir=/data/mysql/data
[server3] 
hostname=MYSQL03
port=3306 
master_binlog_dir=/data/mysql/data

(2)MHA主要配置檔案說明

         manager_workdir=/var/log/masterha/app1.log:設定manager的工作目錄     

         manager_log=/var/log/masterha/app1/manager.log:設定manager的日誌檔案  

         master_binlog_dir=/data/mysql:設定master 儲存binlog的位置,以便MHA可以找到master的日誌                      

         master_ip_failover_script= /usr/local/bin/master_ip_failover:設定自動failover時候的切換指令碼

         master_ip_online_change_script= /usr/local/bin/master_ip_online_change:設定手動切換時候的切換指令碼 

         user=root:設定監控mysql的使用者

         password=dayi123:設定監控mysql的使用者,需要授權能夠在manager節點遠端登入

         ping_interval=1:設定監控主庫,傳送ping包的時間間隔,預設是3秒,嘗試三次沒有迴應的時候自動進行railover    

         remote_workdir=/tmp:設定遠端mysql在發生切換時binlog的儲存位置

         repl_user=repl :設定mysql中用於複製的使用者密碼

         repl_password=replication:設定mysql中用於複製的使用者        

         report_script=/usr/local/send_report:設定發生切換後傳送的報警的指令碼 

         shutdown_script="":設定故障發生後關閉故障主機指令碼(該指令碼的主要作用是關閉主機放在發生腦裂,這裡沒有使用)

         ssh_user=root //設定ssh的登入使用者名稱

         candidate_master=1:在節點下設定,設定當前節點為候選的master

         slave check_repl_delay=0 :在節點配置下設定,預設情況下如果一個slave落後master 100M的relay logs的話,MHA將不會選擇該slave作為一個新的master;這個選項對於對於設定了candidate_master=1的主機非常有用

5、檢查MHA的環境是否工作正常

(1)通過masterha_check_ssh指令碼檢測SSH連線是否配置正常

]# masterha_check_ssh --conf=/etc/app1.cnf 
Mon Oct 29 12:05:48 2018 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Mon Oct 29 12:05:48 2018 - [info] Reading application default configuration from /etc/app1.cnf..
Mon Oct 29 12:05:48 2018 - [info] Reading server configuration from /etc/app1.cnf..
Mon Oct 29 12:05:48 2018 - [info] Starting SSH connection tests..
Mon Oct 29 12:05:53 2018 - [debug] 
…….
Mon Oct 29 12:05:52 2018 - [debug]  Connecting via SSH from [email protected](192.168.16.153:22) to [email protected](192.168.16.152:22)..
Mon Oct 29 12:05:52 2018 - [debug]   ok.
Mon Oct 29 12:05:53 2018 - [info] All SSH connection tests passed successfully.

(2)在管理節點檢查複製配置

         為了讓MHA正常工作,所有的master和slave必須在配置檔案中正確配置,MHA可通過masterha_check_repl 指令碼檢測複製是否正確配置。

]# masterha_check_repl --conf=/etc/app1.cnf 
Fri Nov  2 16:27:47 2018 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Fri Nov  2 16:27:47 2018 - [info] Reading application default configuration from /etc/app1.cnf..
……
Fri Nov  2 16:27:53 2018 - [info] Got exit code 0 (Not master dead).
MySQL Replication Health is OK.

三、MHA的管理

         Mysql中主從的工作狀態監測及切換事由manager節點來完成的,MHA安裝完成以及檢測通過後就可以根據自己的需求開啟以及停止manager,讓manager工作起來。

1、啟動Manager

         Manager是通過 masterha_manager 命令開啟,啟動後需要將它放在後臺執行。

         當MHA manager啟動監控以後,如果沒有異常則不會列印任何資訊。我們可通過masterha_check_status命令檢查manager的狀態。

# 啟動Manager
]# nohup masterha_manager --conf=/etc/app1.cnf > /var/log/mha_manager.log < /dev/null &
# 檢測manager的工作狀態
]# masterha_check_status --conf=/etc/app1.cnf
app1 (pid:22330) is running(0:PING_OK), master:MYSQL0

2、停止MHA manager

         當需要停止manager時,可以通過 masterha_stop命令來停止manager。

# 停止manager
]#  masterha_stop --conf=/etc/app1.cnf 
Stopped app1 successfully.

3、故障的切換

(1)自動故障切換

         Manager啟動後,manager會自動去監測主從同步的狀態,當主節點故障時,會自動進行故障的轉移將從節點提升為主節點,讓其他的從節點去新的主節點同步。

# 將主庫192.168.16.151關閉後,檢視manager的日誌,主要的切換記錄如下:
]# tail -100f /var/log/mha_manager.log
……
app1: MySQL Master failover MYSQL01(192.168.16.151:3306) to MYSQL02(192.168.16.152:3306) succeeded
Master MYSQL01(192.168.16.151:3306) is down!
Check MHA Manager logs at MANAGER for details.
Started automated(non-interactive) failover.
The latest slave MYSQL02(192.168.16.152:3306) has all relay logs for recovery.
Selected MYSQL02(192.168.16.152:3306) as a new master.
MYSQL02(192.168.16.152:3306): OK: Applying all logs succeeded.
MYSQL03(192.168.16.153:3306): This host has the latest relay log events.
Generating relay diff files from the latest slave succeeded.
MYSQL03(192.168.16.153:3306): OK: Applying all logs succeeded. Slave started, replicating from MYSQL02(192.168.16.152:3306)
MYSQL02(192.168.16.152:3306): Resetting slave info succeeded.
Master failover to MYSQL02(192.168.16.152:3306) completed successfully.

(2)手動故障切換

         當在業務上沒有啟用MHA自動切換功能,當主伺服器故障時,需要人工手動呼叫MHA來進行故障切換操作。

# 進行配置停掉的主節點,讓成新的從節點;並manager程序時停掉的,否則會影響手動故障轉移
]#  masterha_stop --conf=/etc/app1.cnf
# 切換時需要將master停掉,否則會報錯,在切換命令中使用主機名,不要使用ip,否則也會報錯,在切換時也需要確認切換
]# masterha_master_switch --master_state=dead --conf=/etc/app1.cnf --dead_master_host=MYSQL02 --dead_master_port=3306 --new_master_host=MYSQL01 --new_master_port=3306 --ignore_last_failover……..
Started manual(interactive) failover.
The latest slave MYSQL01(192.168.16.151:3306) has all relay logs for recovery.
Selected MYSQL01(192.168.16.151:3306) as a new master.
MYSQL01(192.168.16.151:3306): OK: Applying all logs succeeded.
MYSQL03(192.168.16.153:3306): This host has the latest relay log events.
Generating relay diff files from the latest slave succeeded.
MYSQL03(192.168.16.153:3306): OK: Applying all logs succeeded. Slave started, replicating from MYSQL01(192.168.16.151:3306)
MYSQL01(192.168.16.151:3306): Resetting slave info succeeded.
Master failover to MYSQL01(192.168.16.151:3306) completed successfully.

(3)線上切換

         為了保證資料完全一致性,在最快的時間內完成切換,MHA的線上切換必須滿足以下條件才會切換成功,否則會切換失敗。

         1)所有slave的IO執行緒都在執行       

         2)所有slave的SQL執行緒都在執行    

         3)所有的show slave status的輸出中Seconds_Behind_Master引數小於或者等於running_updates_limit秒,如果在切換過程中不指定running_updates_limit,那麼預設情況下running_updates_limit為1秒。

         4)在master端,通過show processlist輸出,沒有一個更新花費的時間大於running_updates_limit秒。

# 在切換前先停掉manage,同時也恢復上面手動切換時停掉的MYSQL02為MYSQL01的從節點
]# masterha_stop --conf=/etc/app1.cnf
# 線上切換MYSQL03為主節點,切換時不需要停掉現有的主節點,在切換的過程中需要確認
]# masterha_master_switch --conf=/etc/app1.cnf --master_state=alive --new_master_host=MYSQL03 --new_master_port=3306 --orig_master_is_new_slave --running_updates_limit=10000
…..
Sat Nov  3 11:17:27 2018 - [info]  Executed CHANGE MASTER.
Sat Nov  3 11:17:27 2018 - [info]  Slave started.
Sat Nov  3 11:17:27 2018 - [info] All new slave servers switched successfully.
Sat Nov  3 11:17:27 2018 - [info] 
Sat Nov  3 11:17:27 2018 - [info] * Phase 5: New master cleanup phase..
Sat Nov  3 11:17:27 2018 - [info] 
Sat Nov  3 11:17:27 2018 - [info]  MYSQL03: Resetting slave info succeeded.
Sat Nov  3 11:17:27 2018 - [info] Switching master to MYSQL03(192.168.16.153:3306) completed successfully.

         線上切換完成後,從節點MYSQL03成為了主節點,原來的主節點MYSQL01變為從節點,兩個從節點會去新的主節點MYSQL03複製。

         在切換過程中的引數說明:

         -orig_master_is_new_slave:切換時加上此引數是將原 master 變為 slave 節點,如果不加此引數,原來的 master 將不啟動

         --running_updates_limit=10000:故障切換時,候選master 如果有延遲的話, mha 切換不能成功,加上此引數表示延遲在此時間範圍內都可切換(單位為s),但是切換的時間長短是由recover 時relay 日誌的大小決定。

4、在MHA環境中配置VIP

         通過MHA進行故障轉以後,連線Mysql資料庫的服務並不知道Mysql複製環境中進行了故障的轉移,同時連線mysql的服務也無法知曉主節點是哪一個,此時,可以通過配置VIP的方式讓所有的應用程式連線VIP,當mysql故障切換時,VIP會自動漂移到新的主節點。vip配置可以採用兩種方式,一種通過keepalived的方式管理;另外一種通過指令碼方式啟動VIP,下面以指令碼的方式進行演示。

# 為mysql主節點在配置一個IP地址
]# ifconfig eno16777736:2 192.168.16.156/24
# 修改manager配置檔案,新增VIP漂移指令碼配置檔案
master_ip_failover_script=/usr/local/bin/master_ip_failover
# 建立指令碼/usr/local/bin/master_ip_failover,內容如下
]# cat /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
);

my $vip = '192.168.16.156/24';
my $key = '2';
my $ssh_start_vip = "/sbin/ifconfig eno16777736:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eno16777736:$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 ([email protected]) {
            warn "Got Error: [email protected]\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 ([email protected]) {
            warn [email protected];
            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";
}
# 為指令碼賦予執行的許可權
]# chmod a+x master_ip_failover

         切換指令碼中的去連線mysql各節點配置vip是通過”user”@”hostname”的方式去連線各節點配置vip的,所以在配置完各節點配置完ssh祕鑰認證後,要通過”ssh [email protected]”的方式去連線各個節點建立快取(第一次通過祕鑰登入需要輸入”yes”確認);否則指令碼在執行到”Disabling the VIP on old master”會執行不下去。