集群信息 角色 IP地址 ServerID 類型 Master 192.168.244.10 1 寫入 Candicate master 192.168.244.20 2 讀 Slave 192.168.244.30 3 讀 Monitor host 192.168.244.40 監控集群組 MHA ...
集群信息
角色 IP地址 ServerID 類型
Master 192.168.244.10 1 寫入
Candicate master 192.168.244.20 2 讀
Slave 192.168.244.30 3 讀
Monitor host 192.168.244.40 監控集群組
MHA具體的搭建步驟和原理,可參考另外一篇博客:
自動Failover
為了通過MHA的日誌清晰判斷MHA自動Failover的實現原理,需模擬如下場景:
當主庫發生故障時,master中還有一部分binlog日誌沒有傳輸到Candicate master和Slave上,且Slave上的二進位日誌多於Candicate master上。
嘗試了幾種方案,總算如願以償。
方案一:
1. 關閉Candicate master和Slave的主從複製。
2. 通過存儲過程生成測試數據
3. 開啟Candicate master和Slave的主從複製並kill掉master的mysqld進程,模擬主庫發生故障,進行自動failover操作
為此,還特意寫了個腳本,可惜的是,效果並不理想,在自動Failover的過程中,顯示MHA Manager到master的“SSH is NOT reachable”。
方案二:
通過tc命令對Candicate master和Slave的網卡分別設置不同的傳輸速率,確保發送到Candicate master的日誌量小於Slave上的。
很可惜,效果同方案一一樣。
方案三:
在主從複製中,直接關閉master的mysqld資料庫。
但是,通過這樣方式,並不會實現Slave上的二進位日誌多於Candicate master的效果。
方案四:
通過截取relay log,在關掉slave的情況下,修改master.info和relay-log.info的位置點來人為製造Candicate master的日誌量小於Slave的。
事後想想,其實這樣的方法就等同於先關閉Candicate master的主從複製,再在master上執行一段操作,再關閉slave上的主從複製,再在master上執行一段操作。
這樣不就實現了master的binlog > slave 的relay log > Candicate master的relay log。
方案四總算如願以償
下麵通過方案四看看MHA的實現原理
1. 創建測試表,並插入測試數據
mysql> create table sbtest.b(id int,name varchar(10)); Query OK, 0 rows affected (0.12 sec) mysql> insert into sbtest.b values(1,'a'); Query OK, 1 row affected (0.00 sec) mysql> insert into sbtest.b values(2,'b'); Query OK, 1 row affected (0.01 sec) mysql> insert into sbtest.b values(3,'c'); Query OK, 1 row affected (0.00 sec) mysql> insert into sbtest.b values(4,'d'); Query OK, 1 row affected (0.00 sec) mysql> insert into sbtest.b values(5,'e'); Query OK, 1 row affected (0.01 sec)
2. 分別查看master上binlog的內容,slave上relay log的內容
Master
mysql> show binlog events; +------------------+------+-------------+-----------+-------------+------------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +------------------+------+-------------+-----------+-------------+------------------------------------------------+ | mysql-bin.000001 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.31-log, Binlog ver: 4 | | mysql-bin.000001 | 120 | Query | 1 | 238 | create table sbtest.b(id int,name varchar(10)) | | mysql-bin.000001 | 238 | Query | 1 | 315 | BEGIN | | mysql-bin.000001 | 315 | Query | 1 | 421 | insert into sbtest.b values(1,'a') | | mysql-bin.000001 | 421 | Xid | 1 | 452 | COMMIT /* xid=102 */ | | mysql-bin.000001 | 452 | Query | 1 | 529 | BEGIN | | mysql-bin.000001 | 529 | Query | 1 | 635 | insert into sbtest.b values(2,'b') | | mysql-bin.000001 | 635 | Xid | 1 | 666 | COMMIT /* xid=103 */ | | mysql-bin.000001 | 666 | Query | 1 | 743 | BEGIN | | mysql-bin.000001 | 743 | Query | 1 | 849 | insert into sbtest.b values(3,'c') | | mysql-bin.000001 | 849 | Xid | 1 | 880 | COMMIT /* xid=104 */ | | mysql-bin.000001 | 880 | Query | 1 | 957 | BEGIN | | mysql-bin.000001 | 957 | Query | 1 | 1063 | insert into sbtest.b values(4,'d') | | mysql-bin.000001 | 1063 | Xid | 1 | 1094 | COMMIT /* xid=105 */ | | mysql-bin.000001 | 1094 | Query | 1 | 1171 | BEGIN | | mysql-bin.000001 | 1171 | Query | 1 | 1277 | insert into sbtest.b values(5,'e') | | mysql-bin.000001 | 1277 | Xid | 1 | 1308 | COMMIT /* xid=106 */ | +------------------+------+-------------+-----------+-------------+------------------------------------------------+ 17 rows in set (0.01 sec)
Slave
mysql> show relaylog events in 'mysqld-relay-bin.000002'; +-------------------------+------+-------------+-----------+-------------+------------------------------------------------+ | Log_name | Pos | Event_type | Server_id | End_log_pos | Info | +-------------------------+------+-------------+-----------+-------------+------------------------------------------------+ | mysqld-relay-bin.000002 | 4 | Format_desc | 2 | 120 | Server ver: 5.6.31-log, Binlog ver: 4 | | mysqld-relay-bin.000002 | 120 | Rotate | 1 | 0 | mysql-bin.000001;pos=120 | | mysqld-relay-bin.000002 | 167 | Format_desc | 1 | 0 | Server ver: 5.6.31-log, Binlog ver: 4 | | mysqld-relay-bin.000002 | 283 | Query | 1 | 238 | create table sbtest.b(id int,name varchar(10)) | | mysqld-relay-bin.000002 | 401 | Query | 1 | 315 | BEGIN | | mysqld-relay-bin.000002 | 478 | Query | 1 | 421 | insert into sbtest.b values(1,'a') | | mysqld-relay-bin.000002 | 584 | Xid | 1 | 452 | COMMIT /* xid=102 */ | | mysqld-relay-bin.000002 | 615 | Query | 1 | 529 | BEGIN | | mysqld-relay-bin.000002 | 692 | Query | 1 | 635 | insert into sbtest.b values(2,'b') | | mysqld-relay-bin.000002 | 798 | Xid | 1 | 666 | COMMIT /* xid=103 */ | | mysqld-relay-bin.000002 | 829 | Query | 1 | 743 | BEGIN | | mysqld-relay-bin.000002 | 906 | Query | 1 | 849 | insert into sbtest.b values(3,'c') | | mysqld-relay-bin.000002 | 1012 | Xid | 1 | 880 | COMMIT /* xid=104 */ | | mysqld-relay-bin.000002 | 1043 | Query | 1 | 957 | BEGIN | | mysqld-relay-bin.000002 | 1120 | Query | 1 | 1063 | insert into sbtest.b values(4,'d') | | mysqld-relay-bin.000002 | 1226 | Xid | 1 | 1094 | COMMIT /* xid=105 */ | | mysqld-relay-bin.000002 | 1257 | Query | 1 | 1171 | BEGIN | | mysqld-relay-bin.000002 | 1334 | Query | 1 | 1277 | insert into sbtest.b values(5,'e') | | mysqld-relay-bin.000002 | 1440 | Xid | 1 | 1308 | COMMIT /* xid=106 */ | +-------------------------+------+-------------+-----------+-------------+------------------------------------------------+ 19 rows in set (0.00 sec)
通過對比master中的binlog event,可以看到show relaylog events中的End_log_pos實際上指的是對應的二進位事件在binlog的位置。
再來查看Candicate master中對應的relay log的內容
[root@node2 mysql]# mysqlbinlog mysqld-relay-bin.000002
[root@node2 mysql]# mysqlbinlog mysqld-relay-bin.000002 /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; DELIMITER /*!*/; # at 4 #170524 17:16:37 server id 2 end_log_pos 120 CRC32 0x4faba9ae Start: binlog v 4, server v 5.6.31-log created 170524 17:16:37 BINLOG ' dU8lWQ8CAAAAdAAAAHgAAABAAAQANS42LjMxLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXAAEGggAAAAICAgCAAAACgoKGRkAAa6p q08= '/*!*/; # at 120 #700101 8:00:00 server id 1 end_log_pos 0 CRC32 0x74c6d70c Rotate to mysql-bin.000001 pos: 120 # at 167 #170524 17:15:49 server id 1 end_log_pos 0 CRC32 0xed2672eb Start: binlog v 4, server v 5.6.31-log created 170524 17:15:49 BINLOG ' RU8lWQ8BAAAAdAAAAAAAAAAAAAQANS42LjMxLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXAAEGggAAAAICAgCAAAACgoKGRkAAety Ju0= '/*!*/; # at 283 #170524 17:17:20 server id 1 end_log_pos 238 CRC32 0xdd48c118 Query thread_id=2 exec_time=0 error_code=0 SET TIMESTAMP=1495617440/*!*/; SET @@session.pseudo_thread_id=2/*!*/; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/; SET @@session.sql_mode=1075838976/*!*/; SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; /*!\C utf8 *//*!*/; SET @@session.character_set_client=33,@@session.collation_connection=33,@@session.collation_server=33/*!*/; SET @@session.lc_time_names=0/*!*/; SET @@session.collation_database=DEFAULT/*!*/; create table sbtest.b(id int,name varchar(10)) /*!*/; # at 401 #170524 17:17:27 server id 1 end_log_pos 315 CRC32 0xae393750 Query thread_id=2 exec_time=0 error_code=0 SET TIMESTAMP=1495617447/*!*/; BEGIN /*!*/; # at 478 #170524 17:17:27 server id 1 end_log_pos 421 CRC32 0x28a781ae Query thread_id=2 exec_time=0 error_code=0 SET TIMESTAMP=1495617447/*!*/; insert into sbtest.b values(1,'a') /*!*/; # at 584 #170524 17:17:27 server id 1 end_log_pos 452 CRC32 0x680f1bfe Xid = 29 COMMIT/*!*/; # at 615 #170524 17:17:33 server id 1 end_log_pos 529 CRC32 0x6a1aae7e Query thread_id=2 exec_time=0 error_code=0 SET TIMESTAMP=1495617453/*!*/; BEGIN /*!*/; # at 692 #170524 17:17:33 server id 1 end_log_pos 635 CRC32 0x117786ca Query thread_id=2 exec_time=0 error_code=0 SET TIMESTAMP=1495617453/*!*/; insert into sbtest.b values(2,'b') /*!*/; # at 798 #170524 17:17:33 server id 1 end_log_pos 666 CRC32 0xa8400ec6 Xid = 30 COMMIT/*!*/; # at 829 #170524 17:17:38 server id 1 end_log_pos 743 CRC32 0x24f9a1d2 Query thread_id=2 exec_time=0 error_code=0 SET TIMESTAMP=1495617458/*!*/; BEGIN /*!*/; # at 906 #170524 17:17:38 server id 1 end_log_pos 849 CRC32 0x56fa9e89 Query thread_id=2 exec_time=0 error_code=0 SET TIMESTAMP=1495617458/*!*/; insert into sbtest.b values(3,'c') /*!*/; # at 1012 #170524 17:17:38 server id 1 end_log_pos 880 CRC32 0x2ac656d4 Xid = 31 COMMIT/*!*/; # at 1043 #170524 17:17:44 server id 1 end_log_pos 957 CRC32 0x73a903bf Query thread_id=2 exec_time=0 error_code=0 SET TIMESTAMP=1495617464/*!*/; BEGIN /*!*/; # at 1120 #170524 17:17:44 server id 1 end_log_pos 1063 CRC32 0x171b9b27 Query thread_id=2 exec_time=0 error_code=0 SET TIMESTAMP=1495617464/*!*/; insert into sbtest.b values(4,'d') /*!*/; # at 1226 #170524 17:17:44 server id 1 end_log_pos 1094 CRC32 0x47d6fe57 Xid = 32 COMMIT/*!*/; # at 1257 #170524 17:17:49 server id 1 end_log_pos 1171 CRC32 0x2d37da37 Query thread_id=2 exec_time=0 error_code=0 SET TIMESTAMP=1495617469/*!*/; BEGIN /*!*/; # at 1334 #170524 17:17:49 server id 1 end_log_pos 1277 CRC32 0xd2201fa2 Query thread_id=2 exec_time=0 error_code=0 SET TIMESTAMP=1495617469/*!*/; insert into sbtest.b values(5,'e') /*!*/; # at 1440 #170524 17:17:49 server id 1 end_log_pos 1308 CRC32 0xac1b464e Xid = 33 COMMIT/*!*/; DELIMITER ; # End of log file ROLLBACK /* added by mysqlbinlog */; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;View Code
mysql中binlog有個有意思的地方是,位置點其實是也是位元組的大小。
譬如,上面這個relay log中,最後一個位點是# at 1440,算上最後一個commit操作需占用31個位元組,所以整個文件的大小是1471,與實際大小吻合。
[root@node2 mysql]# ll mysqld-relay-bin.000002 -rw-rw---- 1 mysql mysql 1471 May 24 17:17 mysqld-relay-bin.000002
3. 通過show slave status查看io thread和sql thread的位置信息
mysql> show slave status\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.244.10 Master_User: repl Master_Port: 3306