1. 程式人生 > 實用技巧 >linux系統mysql資料庫MHA高可用

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)