linux系統mysql資料庫MHA高可用
目錄
1.MHA簡介
MHA(Master High Availability)目前在MySQL高可用方面是一個相對成熟的解決方案,它由日本DeNA公司youshimaton(現就職於Facebook公司)開發,是一套優秀的作為MySQL高可用性環境下故障切換和主從提升的高可用軟體。在MySQL故障切換過程中,MHA能做到在0~30秒之內自動完成資料庫的故障切換操作,並且在進行故障切換的過程中,MHA能在較大程度上保證資料的一致性,以達到真正意義上的高可用。
該軟體由兩部分組成:MHA Manager(管理節點)和MHA Node(資料節點)。MHA Manager可以單獨部署在一臺獨立的機器上管理多個master-slave叢集,也可以部署在一臺slave節點上。MHA Node執行在每臺MySQL伺服器上,MHA Manager會定時探測叢集中的master節點,當master出現故障時,它可以自動將資料的slave提升為新的master,然後將所有其他的slave重新指向新的master。整個故障轉移過程對應用程式完全透明。
在MHA自動故障切換過程中,MHA試圖從宕機的主伺服器上儲存二進位制日誌,較大程度的保證資料的不丟失,但這並不總是可行的。例如,如果主伺服器硬體故障或無法通過ssh訪問,MHA沒法儲存二進位制日誌,只進行故障轉移而丟失了的資料。使用MySQL 5.5的半同步複製,可以大大降低資料丟失的風險。MHA可以與半同步複製結合起來。如果只有一個slave已經收到了的二進位制日誌,MHA可以將的二進位制日誌應用於其他所有的slave伺服器上,因此可以保證所有節點的資料一致性。
2.MHA原理
1)把宕機的master二進位制日誌儲存下來。
2)找到binlog位置點最新的slave。
3)在binlog位置點最新的slave上用relay log(差異日誌)修復其它slave。
4)將宕機的master上儲存下來的二進位制日誌恢復到含有最新位置點的slave上。
5)將含有最新位置點binlog所在的slave提升為master。
6)將其它slave重新指向新提升的master,並開啟主從複製。
3.MHA工具介紹
MHA軟體由兩部分組成,Manager工具包和Node工具包
1.Manager工具:
- masterha_check_ssh : 檢查MHA的SSH配置。
- masterha_check_repl : 檢查MySQL複製。
- masterha_manager : 啟動MHA。
- masterha_check_status : 檢測當前MHA執行狀態。
- masterha_master_monitor : 監測master是否宕機。
- masterha_conf_host : 新增或刪除配置的server資訊。
- masterha_master_switch : 控制故障轉移(自動或手動)。
- masterha_secondary_check:建立TCP連線從遠端伺服器
- masterha_stop:停止MHA
2. Node工具
- save_binary_logs : 儲存和複製master的二進位制日誌。
- apply_diff_relay_logs : 識別差異的中繼日誌事件並應用於其它slave。
- filter_mysqlbinlog : 去除不必要的ROLLBACK事件(防止回滾事件,MHA已不再使用這個工具)。
- purge_relay_logs : 清除中繼日誌(不會阻塞SQL執行緒)。
注意:Node這些工具通常由MHA Manager的指令碼觸發,無需人手操作。
MHA優點總結
1)自動故障轉移快
2) 主庫崩潰不存在資料一致性問題
3)不需要對當前mysql環境做重大修改
4) 不需要新增額外的伺服器(僅一臺manager就可管理上百個replication)
5) 效能優秀,可工作在半同步複製和非同步複製,當監控mysql狀態時,僅需要每隔N秒向master傳送ping包(預設 3秒),所以對效能無影響。你可以理解為MHA的效能和簡單的主從複製框架效能一樣。
6) 只要replication支援的儲存引擎,MHA都支援,不會侷限於innodb
4.基於GTID的主從複製
GTID原理介紹
GTID又叫全域性事務ID(Global Transaction ID),是一個已提交事務的編號,並且是一個全域性唯一的編號。MySQL5.6版本之後在主從複製型別上新增了GTID複製。
GTID是由server_uuid和事務id組成的,即GTID = server_uuid:transaction_id。 server_uuid是在資料庫啟動過程中自動生成的,每臺機器的server-uuid不一樣。uuid存放在資料目錄的auto.cnf檔案下。而transaction_id就是事務提交時由系統順序分配的一個不會重複的序列號。
GTID存在的價值
(1)GTID使用master_auto_position=1代替了基於binlog和position號的主從複製搭建方式,更便於主從複製的搭建。
(2)GTID可以知道事務在最開始是在哪個例項上提交的。
(3)GTID方便實現主從之間的failover,再也不用不斷地去找position和binlog 了。
主從複製中GTID的管理與維護
GTID帶來最方便的一點就是主從複製的搭建過程了。它跟非同步複製、半同步複製類似,只不過不再利用傳統複製模式的binlog檔案和position號了,而是在從庫“change master to”時使用master_auto_position=1的方式進行搭建,這就讓操作變得更加方便和可靠。
先決條件
1.主庫和從庫開啟binlog
2.主庫和從庫server-id不同
3.建立主從複製使用者
主庫操作
修改配置檔案
#編輯mysql配置檔案
[root@mysql-db01 ~]# vim /etc/my.cnf
#在mysqld標籤下配置
[mysqld]
server_id =1 #主庫server-id為1,從庫不等於1
log_bin=mysql-bin #開啟binlog日誌
#重啟mysql
[root@mysql-db01 ~]# /etc/init.d/mysqld restart
建立主從複製使用者
#登入資料庫
[root@mysql-db01 ~]# mysql -uroot -poldboy123
#建立rep使用者(做MHA每個機器都要建立這個使用者)
mysql> grant replication slave on *.* to rep@'172.16.1.5%' identified by '123';
從庫操作
修改配置檔案
#修改mysql-db02配置檔案
[root@mysql-db02 ~]# vim /etc/my.cnf
#在mysqld標籤下配置
[mysqld]
server_id = 2 #主庫server-id為1,從庫必須大於1
log_bin=mysql-bin #開啟binlog日誌
#重啟mysql
[root@mysql-db02 ~]# /etc/init.d/mysqld restart
#修改mysql-db03配置檔案
[root@mysql-db03 ~]# vim /etc/my.cnf
#在mysqld標籤下配置
[mysqld]
server_id = 3 #主庫server-id為1,從庫必須大於1
log_bin=mysql-bin #開啟binlog日誌
#重啟mysql
[root@mysql-db03 ~]# /etc/init.d/mysqld restart
開啟GID
#編輯mysql配置檔案(主庫從庫都需要修改)
[root@mysql-db01 ~]# vim /etc/my.cnf
#在[mysqld]標籤下新增
[mysqld]
gtid_mode=ON
log_slave_updates
enforce_gtid_consistency
#重啟資料庫
[root@mysql-db01 ~]# /etc/init.d/mysqld restart
[root@mysql-db02 ~]# vim /etc/my.cnf
#在[mysqld]標籤下新增
[mysqld]
gtid_mode=ON
log_slave_updates
enforce_gtid_consistency
#重啟資料庫
[root@mysql-db02 ~]# /etc/init.d/mysqld restart
[root@mysql-db03 ~]# vim /etc/my.cnf
#在[mysqld]標籤下新增
[mysqld]
gtid_mode=ON
log_slave_updates
enforce_gtid_consistency
#重啟資料庫
[root@mysql-db03 ~]# /etc/init.d/mysqld restart
#檢查GTID狀態
mysql> show global variables like '%gtid%';
+--------------------------+-------+
| Variable_name | Value |
+--------------------------+-------+
| enforce_gtid_consistency | ON | #執行GTID一致
| gtid_executed | |
| gtid_mode | ON | #開啟GTID模組
| gtid_owned | |
| gtid_purged | |
+--------------------------+-------+
配置主從複製
#所有從庫執行 chang master to語句,配置複製主機資訊
mysql> change master to
-> master_host='172.16.1.51',
-> master_user='rep',
-> master_password='123',
-> master_auto_position=1;
#開啟slave
mysql> start slave;
#檢視slave狀態
mysql> show slave status\G
5.部署MHA
部署MHA之前的配置:
1.只有從庫配置:
#從庫設定只讀
mysql> set global read_only=1;
2.主庫和從庫都執行:
#在配置檔案中設定,關閉MySQL自動清除relaylog的功能,跳過反向解析
[root@mysql-db01 ~]# vim /etc/my.cnf
[mysqld]
relay_log_purge = 0
skip_name_resolve
#關閉MySQL自動清除relaylog的功能
mysql> set global relay_log_purge = 0;
環境準備:
#每臺機器上傳MHA的rpm包
[root@mysql-db01 ~]# ll
mha4mysql-manager-0.56-0.el6.noarch.rpm
mha4mysql-node-0.56-0.el6.noarch.rpm
部署node節點(3臺):
#安裝依賴包
[root@mysql-db01 ~]# yum install perl-DBD-MySQL -y
#安裝node包(3臺):
[root@db-01 ~]# yum localinstall -y mha4mysql-node-0.56-0.el6.noarch.rpm
[root@db-02 ~]# yum localinstall -y mha4mysql-node-0.56-0.el6.noarch.rpm
[root@db-03 ~]# yum localinstall -y mha4mysql-node-0.56-0.el6.noarch.rpm
部署manager節點(1臺:10.0.0.53)
#安裝manager依賴包
[root@mysql-db03 ~]# yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes
#安裝manager包
[root@db-03 ~]# yum localinstall -y mha4mysql-manager-0.56-0.el6.noarch.rpm
#新增mha管理賬號(所有節點)
mysql> grant all on *.* to mha@'172.16.1.5%' identified by 'mha';
命令軟連線(所有節點)
#如果不建立命令軟連線,檢測mha複製情況的時候會報錯
[root@db-01 ~]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/bin/
[root@db-01 ~]# ln -s /usr/local/mysql/bin/mysql /usr/bin/
配置ssh免密登入
#做ssh 免密登入(下面4條命令,所以節點都執行)
#建立祕鑰對
[root@db-01 ~]## ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa >/dev/null 2>&1
#傳送公鑰,包括自己
[root@db-01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub [email protected]
[root@db-01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub [email protected]
[root@db-01 ~]# ssh-copy-id -i /root/.ssh/id_dsa.pub [email protected]
編輯配置檔案
#在安裝manager節點的機器上,建立mha配置檔案目錄
[root@db-03 ~]# mkdir /etc/mha/
#編輯mha配置檔案
[root@mysql-db03 ~]# vim /etc/mha/app1.cnf
[server default]
manager_log=/etc/mha/manager.log #manager的日誌
manager_workdir=/etc/mha/app1/ #manager的工作目錄
master_binlog_dir=/usr/local/mysql/data #master儲存binlog的位置,以便MHA可找到master的日誌
password=mha #MHA管理賬號的密碼
ping_interval=2 #監控主庫傳送ping包的時間間隔,嘗試三次沒有迴應則切換主庫
repl_password=123 #主從複製環境中的使用者的密碼
repl_user=rep #主從複製環境中的使用者名稱
ssh_user=root #ssh的登入使用者名稱
user=mha #MHA管理賬號
[server1]
hostname=172.16.1.51
port=3306
[server2]
hostname=172.16.1.52
port=3306
[server3]
hostname=172.16.1.53
port=3306
MHA啟動前檢測
#測試ssh
[root@db03 ~]# masterha_check_ssh --conf=/etc/mha/app1.cnf
#看到如下字樣,則測試成功
Tue Mar 7 01:03:33 2017 - [info] All SSH connection tests passed successfully.
#測試複製
[root@db03 ~]# masterha_check_repl --conf=/etc/mha/app1.cnf
#看到如下字樣,則測試成功
MySQL Replication Health is OK.
啟動MHA
#啟動MHA
[root@db03 ~]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /etc/mha/manager.log 2>&1 &
#檢測MHA啟動狀態
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:10434) is running(0:PING_OK), master:172.16.1.52
#啟動命令分析
nohup
masterha_manager #MHA的啟動程式
--conf=/etc/mha/app1.cnf #指定配置檔案
--remove_dead_master_conf #移除宕機的server標籤從配置檔案裡
--ignore_last_failover #忽略上一次的切換
< /dev/null > /etc/mha/manager.log 2>&1 &
MHA的工作機制:
1.完成一次切換後,會生成一個鎖檔案在工作目錄中
2.下次切換之前,會檢測鎖檔案是否存在
3.如果鎖檔案存在,8個小時之內不允許第二次切換
切換主庫測試
#STOP主庫
[root@db01 ~]# /etc/init.d/mysqld stop
#在STOP主庫同時可以看著manager日誌
[root@db03 ~]# tail -f /etc/mha/manager.log
#在db03上可以看到主庫以切換成db02
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 172.16.1.52
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000009
Read_Master_Log_Pos: 231
Relay_Log_File: db03-relay-bin.000002
Relay_Log_Pos: 361
Relay_Master_Log_File: mysql-bin.000009
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
MHA環境修復
1.修復宕機的主庫
[root@db01 ~]# /etc/init.d/mysqld start
2.在MHA的日誌中,找到change master 語句
[root@db-03 ~]# grep -i 'change master to' /etc/mha/manager.log
Thu Jul 25 04:38:35 2019 - [info] All other slaves should start replication from here. Statement should be: CHANGE MASTER TO MASTER_HOST='172.16.1.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='rep', MASTER_PASSWORD='xxx';
3.在宕機的主庫中執行change master語句
mysql> CHANGE MASTER TO MASTER_HOST='172.16.1.52', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='rep', MASTER_PASSWORD='123';
4.開啟IO和SQL執行緒,將宕機的主庫重新加入叢集變成從庫
mysql> start slave;
5.在manager配置檔案中,將server標籤重新新增
[root@db03 ~]# vim /etc/mha/app1.cnf
[server1]
hostname=172.16.1.51
port=3306
6.啟動MHA
[root@db03 ~]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /etc/mha/manager.log 2>&1 &
7.檢測MHA啟動狀態
[root@db03 ~]# masterha_check_status --conf=/etc/mha/app1.cnf
app1 (pid:10434) is running(0:PING_OK), master:172.16.1.52
6.配置VIP漂移
修改MHA主配置檔案
[root@db03 ~]# vim /etc/mha/app1.cnf
#在[server default]標籤下新增
master_ip_failover_script=/etc/mha/master_ip_failover #使用MHA自帶指令碼
編輯指令碼
#根據配置檔案中指令碼路徑編輯
[root@db03 ~]# vim /etc/mha/master_ip_failover
#修改以下幾行內容
my $vip = '172.16.1.55/24';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig eth0:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig eth0:$key down";
#新增執行許可權,否則mha無法啟動
[root@db03 ~]# chmod +x /etc/mha/master_ip_failover
手動繫結VIP
#繫結vip
[root@db01 ~]# ifconfig eth1:1 172.16.1.55/24
7.配置binlog-server
修改mha配置檔案
[root@db03 ~]# vim /etc/mha/app1.cnf
[binlog1]
no_master=1
hostname=10.0.0.53
master_binlog_dir=/data/mysql/binlog/
備份binlog
#建立備份binlog目錄
[root@db03 ~]# mkdir -p /data/mysql/binlog/
#進入該目錄
[root@db03 ~]# cd /data/mysql/binlog/
#備份binlog
[root@db03 binlog]# mysqlbinlog -R --host=172.16.1.51 --user=mha --password=mha --raw --stop-never mysql-bin.000001 &
#啟動mha
[root@mysql-db03 binlog]# nohup masterha_manager --conf=/etc/mha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/mha/app1/manager.log 2>&1 &
8.Atlas
Atlas主要功能
1.讀寫分離
2.從庫負載均衡
3.IP過濾
4.自動分表
5.DBA可平滑上下線DB
6.自動摘除宕機的DB
下載安裝Atlas
#下載Atlas
[root@db03 ~]#
wget httpss://github.com/Qihoo360/Atlas/releases/download/2.2.1/Atlas-2.2.1.el6.x86_64.rpm
#安裝
[root@db03 ~]# rpm -ivh Atlas-2.2.1.el6.x86_64.rpm
Preparing... ########################################### [100%]
1:Atlas ########################################### [100%]
編輯配置檔案
#進入Atlas工具目錄
[root@db03 ~]# cd /usr/local/mysql-proxy/bin/
#生成密碼
[root@db03 bin]# ./encrypt 123
#修改Atlas配置檔案
[root@db03 ~]# vim /usr/local/mysql-proxy/conf/test.cnf
#Atlas後端連線的MySQL主庫的IP和埠,可設定多項,用逗號分隔
proxy-backend-addresses = 172.16.1.51:3306
#Atlas後端連線的MySQL從庫的IP和埠
proxy-read-only-backend-addresses = 10.0.0.52:3306,10.0.0.53:3306
#使用者名稱與其對應的加密過的MySQL密碼
pwds = rep:3yb5jEku5h4=
#SQL日誌的開關
sql-log = ON
#Atlas監聽的工作介面IP和埠
proxy-address = 0.0.0.0:1234
#預設字符集,設定該項後客戶端不再需要執行SET NAMES語句
charset = utf8
啟動
[root@db03 ~]# /usr/local/mysql-proxy/bin/mysql-proxyd test start
OK: MySQL-Proxy of test is started
Atlas管理操作
#用atlas管理使用者登入
[root@db03 ~]# mysql -uuser -ppwd -h127.0.0.1 -P2345
#檢視可用命令幫助
mysql> select * from help;
#檢視後端代理的庫
mysql> SELECT * FROM backends;
+-------------+----------------+-------+------+
| backend_ndx | address | state | type |
+-------------+----------------+-------+------+
| 1 | 10.0.0.51:3307 | up | rw |
| 2 | 10.0.0.53:3307 | up | ro |
| 3 | 10.0.0.52:3307 | up | ro |
+-------------+----------------+-------+------+
#平滑摘除mysql
mysql> REMOVE BACKEND 2;
Empty set (0.00 sec)
#檢查是否摘除成功
mysql> SELECT * FROM backends;
+-------------+----------------+-------+------+
| backend_ndx | address | state | type |
+-------------+----------------+-------+------+
| 1 | 10.0.0.51:3307 | up | rw |
| 2 | 10.0.0.52:3307 | up | ro |
+-------------+----------------+-------+------+
#儲存到配置檔案中
mysql> SAVE CONFIG;
Empty set (0.06 sec)