1. 程式人生 > >MHA+MySQL實現mysql高可用

MHA+MySQL實現mysql高可用

MHA MySQL高可用

1. MHA的簡單介紹

簡介

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

已托管至github,對應地址如下

manager地址,https://github.com/yoshinorim/mha4mysql-manager
node地址,https://github.com/yoshinorim/mha4mysql-node
截止本文檔編寫時間為止,最新版本為0.58

優點

可參考官方文檔詳細介紹 https://github.com/yoshinorim/mha4mysql-manager/wiki/Advantages
大致總結如下:

1、主從切換非常迅速,通常10-30s
2、最大程度上解決數據一致性的問題
3、不需要修改當前已有的MySQL架構和配置
4、不需要另外多余的服務器
5、沒有性能損耗
6、沒有存儲引擎限制

??

2. MHA的搭建概述

數據庫架構:一主兩從

master:192.168.142.48
slave1:192.168.142.49
slave2:192.168.142.50

mha架構:

manager:192.168.142.49
node:192.168.142.48,192.168.142.49,192.168.142.50

keepalived架構

VIP:192.168.142.235
節點:192.168.142.48,192.168.142.49

搭建環境版本

數據庫版本:5.7.18,5.7.18-log MySQL Community Server (GPL)
MHA版本:v0.58,mha4mysql-manager-0.58 + mha4mysql-node-0.58
Keepalived:keepalived-1.4.3
Linux主機:centos7.2

主機和安裝服務列表

主機IP 安裝服務
192.168.142.48 mysql master ; mha node ; keepalived
192.168.142.49 mysql slave ; mha node && mha manager ; keepalived
192.168.142.50 mysql slave ; mha node

搭建大體步驟

1、keepalived的搭建
2、linux機器之間配置互信
3、mysql主從環境的搭建
4、MHA的安裝和配置
5、配置文件測試    
    測試ssh連通性
    測試集群中的主從復制
6、啟動MHA管理節點

?

3. keepalived的搭建

這裏使用rpm方式安裝,分別在192.168.142.48和192.168.142.49上安裝keepalived,也可使用源碼編譯

1、安裝
yum install keepalived -y

2、配置文件修改
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived

global_defs {
   notification_email {
   root@localhost
}
   notification_email_from [email protected]
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id LVS_DEVEL
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 55
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.142.235
    }
}

note:其中主MASTER優先級高(100),BACKUP優先級(90)低一些

3、啟動、關閉、查看
systemctl start keepalived
systemctl stop keepalived
systemctl status keepalived

?

4. linux機器之間配置互信

服務器之間建立ssh互信的方式很多,這裏介紹一種私以為比較便捷的創建方式

1、創建秘鑰(回車連續三次即可)
[root@192-168-142-48]# ssh-keygen -t rsa
2、進入.ssh目錄查看文件
[root@192-168-142-48]# cd /root/.ssh/ && ls
id_rsa
id_rsa.pub
3、修改id_rsa.pub名稱
mv id_rsa.pub authorized_keys
4、將/root/.ssh文件夾拷貝到192.168.142.49和192.168.142.50即可建立三臺機器之間的互信(如果端口不是默認22,需要額外指定參數 -P port)
scp -P 8822 -r /root/.ssh 192.168.142.49:/root/
scp -P 8822 -r /root/.ssh 192.168.142.50:/root/

??

5. mysql主從環境的搭建

1、手動搭建或者自動化腳本分別在三臺主機上配置mysql實例,這裏可參考MySQL單實例搭建的方法,不在贅述

2、每臺主機數據庫實例上配置復制用戶l和監控用戶

1、復制用戶
GRANT SUPER, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO ‘repl‘@‘192.168.142.%‘ IDENTIFIED BY ‘123456‘;FLUSH PRIVILEGES;
2、監控用戶
GRANT ALL PRIVILEGES ON *.* TO ‘root‘@‘192.168.142.%‘ IDENTIFIED BY ‘123456‘;FLUSH PRIVILEGES;

3、配置從同步

1、master上執行
show master status;,記錄對應File名稱和Position列的數字,這裏為 mysql-bin.000001 154
2、slave1和slave2上分別執行
CHANGE MASTER TO MASTER_HOST=‘192.168.142.48‘,MASTER_USER=‘repl‘,MASTER_PASSWORD=‘123456‘,MASTER_PORT=5700,MASTER_LOG_FILE=‘mysql-bin.000001‘,MASTER_LOG_POS=154;

??

6. MHA的安裝和配置

可參考官方文檔詳細介紹 https://github.com/yoshinorim/mha4mysql-manager/wiki/Installation
?
1、每臺主機上安裝node節點,這裏使用rpm方式安裝,也可使用源碼編譯

1、下載
https://github.com/yoshinorim/mha4mysql-node/releases  選擇對應的rpm包下載
2、安裝依賴
yum install perl-DBD-MySQL -y
3、安裝node節點
rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm

?
2、其中一臺主機(192.168.142.49)安裝manager節點即可,這裏使用rpm方式安裝,也可使用源碼編譯

1、下載
https://github.com/yoshinorim/mha4mysql-manager/releases  選擇對應的rpm包下載
2、安裝依賴
yum install perl-DBD-MySQL perl-Config-Tiny perl-Log-Dispatch perl-Parallel-ForkManager -y
3、安裝manager節點
rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm

??
3、創建MHA的配置文件
app1.cnf,個人安裝配置實例完整版已經放置到github,可參考查看,如下為鏈接
https://github.com/dwwang1992/configs-of-MHA/blob/master/app1.cnf
??
4、master_ip_failover_script對應的腳本
master_ip_failover,個人安裝配置實例完整版已經放置到github,可參考查看,如下為鏈接
https://github.com/dwwang1992/configs-of-MHA/blob/master/master_ip_failover
??
5、master_ip_online_change_script對應的腳本
master_ip_online_change,個人安裝配置實例完整版已經放置到github,可參考查看,如下為鏈接
https://github.com/dwwang1992/configs-of-MHA/blob/master/master_ip_online_change
??
6、report_script對應的腳本
send_report,個人安裝配置實例完整版已經放置到github,可參考查看,如下為鏈接
https://github.com/dwwang1992/configs-of-MHA/blob/master/send_report
?

7. 配置文件測試

測試ssh連通性

[root@hz-192-168-142-49 scripts]# masterha_check_ssh --conf=/data/mha/app1.cnf 
Fri May 25 14:24:34 2018 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.
Fri May 25 14:24:34 2018 - [info] Reading application default configuration from /data/mha/app1.cnf..
Fri May 25 14:24:34 2018 - [info] Reading server configuration from /data/mha/app1.cnf..
Fri May 25 14:24:34 2018 - [info] Starting SSH connection tests..
Fri May 25 14:24:37 2018 - [debug] 
Fri May 25 14:24:34 2018 - [debug]  Connecting via SSH from [email protected](192.168.142.48:8822) to [email protected](192.168.142.49:8822)..
Fri May 25 14:24:35 2018 - [debug]   ok.
Fri May 25 14:24:35 2018 - [debug]  Connecting via SSH from [email protected](192.168.142.48:8822) to [email protected](192.168.142.50:8822)..
Fri May 25 14:24:36 2018 - [debug]   ok.
Fri May 25 14:24:38 2018 - [debug] 
Fri May 25 14:24:35 2018 - [debug]  Connecting via SSH from [email protected](192.168.142.49:8822) to [email protected](192.168.142.48:8822)..
Fri May 25 14:24:35 2018 - [debug]   ok.
Fri May 25 14:24:35 2018 - [debug]  Connecting via SSH from [email protected](192.168.142.49:8822) to [email protected](192.168.142.50:8822)..
Fri May 25 14:24:37 2018 - [debug]   ok.
Fri May 25 14:24:39 2018 - [debug] 
Fri May 25 14:24:35 2018 - [debug]  Connecting via SSH from [email protected](192.168.142.50:8822) to [email protected](192.168.142.48:8822)..
Fri May 25 14:24:37 2018 - [debug]   ok.
Fri May 25 14:24:37 2018 - [debug]  Connecting via SSH from [email protected](192.168.142.50:8822) to [email protected](192.168.142.49:8822)..
Fri May 25 14:24:39 2018 - [debug]   ok.
Fri May 25 14:24:39 2018 - [info] All SSH connection tests passed successfully.

測試集群中的主從復制

[root@hz-192-168-142-49 scripts]# masterha_check_repl --conf=/data/mha/app1.cnf 
......
......
192.168.142.48(192.168.142.48:5700) (current master)
 +--192.168.142.49(192.168.142.49:5700)
 +--192.168.142.50(192.168.142.50:5700)

Fri May 25 14:25:57 2018 - [info] Checking replication health on 192.168.142.49..
Fri May 25 14:25:57 2018 - [info]  ok.
Fri May 25 14:25:57 2018 - [info] Checking replication health on 192.168.142.50..
Fri May 25 14:25:57 2018 - [info]  ok.
Fri May 25 14:25:57 2018 - [info] Checking master_ip_failover_script status:
Fri May 25 14:25:57 2018 - [info]   /data/mha/scripts/master_ip_failover --command=status --ssh_user=root --orig_master_host=192.168.142.48 --orig_master_ip=192.168.142.48 --orig_master_port=5700  --orig_master_ssh_port=8822
Unknown option: orig_master_ssh_port

IN SCRIPT TEST====systemctl stop keepalived==systemctl start keepalived===

Checking the Status of the script.. OK 
Fri May 25 14:25:57 2018 - [info]  OK.
Fri May 25 14:25:57 2018 - [warning] shutdown_script is not defined.
Fri May 25 14:25:57 2018 - [info] Got exit code 0 (Not master dead).

MySQL Replication Health is OK.

?

8. 啟動MHA管理節點

啟動命令

nohup masterha_manager --conf=/data/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /data/mha/mha/app1/manager.log 2>&1 &
參數含義具體可參照官網說明  https://github.com/yoshinorim/mha4mysql-manager/wiki/masterha_manager,此處簡單說明
--remove_dead_master_conf,發生failover後,MHA會自動從配置文件裏移除dead master的相關信息
--ignore_last_failover,默認情況下,之前如果存在failover,那麽再次啟動MHA是不成功的,必須刪除對應目錄下的failover error文件, (manager_workdir)/(app_name).failover.error;設置此參數,就可以忽略上次是否錯誤而可以繼續進行failover

關閉命令

masterha_stop --conf=/data/mha/app1.cnf

查看狀態

masterha_check_status --conf=/data/mha/app1.cnf

?

9. 在線手動切換過程

1、首先需要保證mha manager處於關閉狀態

masterha_stop --conf=/data/mha/app1.cnf

2、手動切換主master

masterha_master_switch --conf=/data/mha/app1.cnf --master_state=alive --new_master_host=192.168.142.48 --new_master_port=5700 --orig_master_is_new_slave --running_updates_limit=10000 --interactive=0
參數解釋:
new_master_host:指定哪臺成為新的主庫
new_master_port:指定對應的數據庫端口
orig_master_is_new_slave:將原來的主庫變為從庫
running_updates_limit:指定復制延遲在10000s內的都可切換
interactive:表示不需要人工幹預,自動執行

3、切換過程

1、檢查當前的配置信息及主從服務器的信息
            包括讀取MHA的配置文件以及檢查當前slave的健康狀態
2、阻止對當前master的更新
            主要通過如下步驟:
            1> 等待1.5s($time_until_kill_threads*100ms),等待當前連接斷開
            2> 執行 read_only=1,阻止新的DML操作
            3> 等待0.5s,等待當前DML操作完成
            4> kill掉所有連接
            5> FLUSH NO_WRITE_TO_BINLOG TABLES
            6> FLUSH TABLES WITH READ LOCK
3、等待新master執行完所有的relay log,執行完之後記錄下對應的日誌位點
            Waiting to execute all relay logs on 192.168.142.49(192.168.142.49:5700)..
            Getting new master‘s binlog name and position..
            mysql-bin.000001:2488
4、將新master的read_only設置為off,並添加VIP
5、slave切換到新master上
            1、等待slave應用完原主從復制產生的relay log,然後執行change master操作切換到新master上
            Waiting to execute all relay logs on 192.168.142.50(192.168.142.50:5700)..
            Resetting slave 192.168.142.50(192.168.142.50:5700) and starting replication from the new master 192.168.142.49(192.168.142.49:5700)..
            2、釋放原master上的鎖
            Unlocking all tables on the orig master:
            Executing UNLOCK TABLES..
            3、因masterha_master_switch命令行中帶有--orig_master_is_new_slave參數,故原master也切換為新master的從
            Starting orig master as a new slave..
            Resetting slave 192.168.142.48(192.168.142.48:5700) and starting replication from the new master 192.168.142.49(192.168.142.49:5700)..
6、清理新master的相關信息
            192.168.142.49: Resetting slave info succeeded

??

10. 自動故障切換過程

1、首先需要保證mha manager處於運行狀態

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

2、一旦主master出現宕機,會自動檢測和選取新的主master

3、切換的過程

當master_manager監控到主庫mysqld服務停止後,首先對主庫進行SSH登錄檢查(save_binary_logs --command=test),然後對mysqld服務進行健康檢查(PING(SELECT)每隔3秒檢查一次,持續3次),參數secondary_check_script可用於double check,最後作出Master is down!的判斷,master failover開始
1、先根據配置文件檢測當前的復制環境中有哪些服務器,MHA也會校驗諸如復制異常以及是否存在一些從庫有不同的主庫,啟動failover(排除上次failover失敗或者failover時間間隔太短)
?
2、隔離master server,把故障主庫的VIP停掉(前提是你需要指定相關的腳本,比如:如果有master_ip_failover_script則會調用腳本停掉VIP、如果有shutdown_script腳本則調用腳本關閉master避免腦裂,具體在配置文件中app1.cnf)
??
3、選舉新主庫並盡量補全新主庫的數據
            1、獲取同步位置最靠前的從庫:對比所有從庫的master_log_file和read_master_log_pos位置找出執行位置最新和最舊的從庫對應的故障主庫的binlog位置
            2、保存dead master的binlog:在故障主庫上執行save_binary_logs命令獲得lastest slave同步位置與master間的binlog差異(使用3.1步驟找到的同步最靠前的從庫binlog位置,如果故障主庫系統沒掛的情況下)並scp到mha manager server上
            scp from [email protected]:/data/mha/mha/tmp/saved_master_binlog_from_192.168.142.48_5700_20180525155119.binlog to local:/data/mha/mha/app1/saved_master_binlog_from_192.168.142.48_5700_20180525155119.binlog succeeded.
            3、確定和決定新的主庫
            確定新的主庫:先使用命令apply_diff_relay_logs --command=find把前面3.1步驟中找出的同步位置最靠前和最靠後的對應主庫的binlog位置作為參數,在同步位置最靠前的從庫上執行這個命令在其中繼日誌中找出兩個binlog位置之間的relay log並生成文件用於恢復其他從庫(這裏就是檢查同步最靠前的從庫是否有從最老的位置開始的中繼日誌,這也是為什麽MHA環境中執行過的中繼日誌不能刪除的原因,否則這個對比就比較麻煩)
            接著尋找及決定新的主庫,根據配置選擇如何提升新主庫(檢查是否有設置candidate_master=1和no_master=1,如果有設置候選主庫,那麽候選主庫中標,但候選庫不一定就是有最新數據的slave,所以需要跟其他從庫進行比較,當然如果候選主庫恰好是同步位置最靠前的從庫,就不需要跟其他從庫進行relay log比較了;如果沒有設置候選主庫,那麽同步位置最靠前的從庫中標)。mha manager server也會將之前復制的差異binlog復制到新主庫上
            4、新的主庫應用日誌(如果有任何錯誤從這個階段會發生,需要手動恢復)
            新的主庫首先需要對比master_log_file=relay_master_log_file,read_master_log_pos=exec_master_log_pos確認自己已經執行完成復制,如果新的主庫不是同步位置最靠前的從庫,那麽需要使用apply_diff_relay_logs --command=generate_and_send命令比較自己和同步位置最靠前的從庫之間的relay log是否存在差異,如果存在則需要生成一個差異relay log(如果新主庫就是同步位置最靠前的從庫,那麽只需要執行mha manager server發過來的差異日誌即可),然後使用這兩個差異日誌進行恢復數據(apply_diff_relay_logs --command=apply命令)。恢復完成後獲取binlog位置並生成change master語句準備用於其他從庫change master到新的主庫上,並設置read_only=0。然後把VIP綁定到新的主庫上。到這步驟新的主庫切換完成
?
4、其他從庫恢復:將其他從庫數據盡量補全(所有從庫並行執行)
並行使用apply_diff_relay_logs --command=generate_and_send命令判斷各個從庫的relay log位置和同步位置最靠前的從庫之間的relay log差異,並把差異文件從同步位置最靠前的從庫上發送到對應的各個從庫上
並行使用兩個差異日誌進行恢復:mha manager server上的binlog差異拷貝到各個從庫上,然後各個從庫通過master_log_file=relay_master_log_file,read_master_log_pos=exec_master_log_pos先確認自己已經執行完成復制,再應用兩個差異日誌恢復數據。最後,執行reset slave,並重新CHANG MASTER到新主庫上
??
5、清理新master的相關信息,到這裏故障主庫切換到新主庫完成
            Resetting slave info on the new master..

?

11. 故障後的主機新加入資源組

第一種方法

1、vim /data/mha/app1.cnf 添加server1主機信息
[server1]
candidate_master=1
client_bindir=/usr/local/mysql-5.7.18/bin/
client_libdir=/usr/local/mysql-5.7.18/lib/
hostname=192.168.142.48
port=5700

2、將server1指向當前的master充當從的角色
CHANGE MASTER TO MASTER_HOST=‘192.168.142.49‘,MASTER_USER=‘repl‘,MASTER_PASSWORD=‘123456‘,MASTER_PORT=5700,MASTER_LOG_FILE=‘mysql-bin.000001‘,MASTER_LOG_POS=2488;

3、啟動mha manager
nohup masterha_manager --conf=/data/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /data/mha/mha/app1/manager.log 2>&1 &

?
第二種方法

1、通過masterha_conf_host將server1主機信息添加進資源組
masterha_conf_host --command=add --conf=/data/mha/app1.cnf --block=server1 --hostname=192.168.142.48 --params="candidate_master=1;client_bindir=/usr/local/mysql-5.7.18/bin/;client_libdir=/usr/local/mysql-5.7.18/lib/;port=5700"
參數解釋:
command:添加或者刪除一個主機信息到配置文件
conf:配置文件的路徑
hostname:主機信息ip
block:新添加的塊名
params:額外參數列表,(key1=value1;key2=value2;...)

2、將server1指向當前的master充當從的角色
CHANGE MASTER TO MASTER_HOST=‘192.168.142.49‘,MASTER_USER=‘repl‘,MASTER_PASSWORD=‘123456‘,MASTER_PORT=5700,MASTER_LOG_FILE=‘mysql-bin.000001‘,MASTER_LOG_POS=2488;

3、啟動mha manager
nohup masterha_manager --conf=/data/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /data/mha/mha/app1/manager.log 2>&1 &

?

12. MHA 清理relay log(purge_relay_logs)

1、說明:

MySQL數據庫主從復制在缺省情況下從庫的relay logs會在SQL線程執行完畢後被自動刪除
但是對於MHA場景下,對於某些滯後從庫的恢復依賴於其他從庫的relay log,因此采取禁用自動刪除功能以及定期清理的辦法
對於清理過多過大的relay log需要註意引起的復制延遲資源開銷等。MHA可通過purge_relay_logs腳本及配合cronjob來完成此項任務

2、purge_relay_logs的功能

a、為relay日誌創建硬鏈接(最小化批量刪除大文件導致的性能問題)
b、SET GLOBAL relay_log_purge=1; FLUSH LOGS; SET GLOBAL relay_log_purge=0;
c、刪除relay log(rm –f  /path/to/archive_dir/*)

3、purge_relay_logs的用法及相關參數

###用法
# purge_relay_logs --help
Usage:
    purge_relay_logs --user=root --password=rootpass --host=127.0.0.1

###參數描述
--user:mysql用戶名,缺省為root
--password:mysql密碼
--port:端口號
--host:主機名,缺省為127.0.0.1
--workdir:指定創建relay log的硬鏈接的位置,默認是/var/tmp,成功執行腳本後,硬鏈接的中繼日誌文件被刪除由於系統不同分區創建硬鏈接文件會失敗,故需要執行硬鏈接具體位置,建議指定為relay log相同的分區
--disable_relay_log_purge:默認情況下,參數relay_log_purge=1,腳本不做任何處理,自動退出,設定該參數,腳本會將relay_log_purge設置為0,當清理relay log之後,最後將參數設置為OFF(0)

4、定制清理relay log cronjob(每臺主機均設置)

purge_relay_logs腳本在不阻塞SQL線程的情況下自動清理relay log。對於不斷產生的relay log直接將該腳本部署到crontab以實現按天或按小時定期清理
1、編輯腳本,vim /data/mha/mha/purge_relay_logs.sh
#!/bin/bash
user=root
passwd=123456
port=5700
host=127.0.0.1
work_dir=‘/data/mha/mha/data‘
purge=‘/bin/purge_relay_logs‘
log_dir=‘/data/mha/mha/log‘

if [ ! -d $log_dir ]
then
   mkdir $log_dir -p
fi

if [ ! -d $work_dir ]
then
   mkdir $work_dir -p
fi

$purge --user=$user --password=$passwd --port=$port --host=$host --workdir=$work_dir --disable_relay_log_purge >> $log_dir/purge_relay_logs.log 2>&1

2、最後添加到計劃任務:
##每2天淩晨1點清空relay log
00 01 * * * /bin/bash /data/mha/mha/purge_relay_logs.sh

MHA+MySQL實現mysql高可用