MySQL5.6 - 基於GTID複製模式搭建主從複製、故障模擬、問題解決!

寫在前面:

本文主要講解,GTID複製模式的參數配置、搭建過程中遇到的一些問題及其解決方法;針對一些常見問題場景,進行故障模擬,然後解決。
如果對GTID的其他方面的知識想要做個瞭解,如:GTID優點、使用限制、實現原理等,可以移步到筆者的另一篇文章 GTID模式介紹


環境:

MySQL5.6.16版本
CentOS release 6.5


主從參數配置:

對於GTID參數的含義,請參閱MySQL官網


Master配置GTID參數:
gtid_mode=on
enforce_gtid_consistency=on

log_slave_updates=1

log_bin = /home/data/mysql3306/binlog

binlog_format = row
server_id=1

... 以上參數是必須的,其他參數自行配置

重啓Master,因爲MySQL5.6不支持動態配置GTID

Slave配置GTID參數:
gtid_mode=on
enforce_gtid_consistency=on

log_slave_updates=1

log_bin = /home/data/mysql3306/binlog

binlog_format = row
server_id=2
relay_log = /home/data/mysql3306/relaylog

replicate_do_db=edusoho_e

 (開啓log_slave_updates參數,是把relay-log裏的日誌內容再記錄到slave本地的binlog裏,MySQL5.7版本以後Slave可以不開啓binlog了,可以節省空間提高性能,5.6版本必須開啓binlog,因爲GTID存儲在binlog中,只有開啓binlog才能使用GTID的功能。5.7中通過GTID系統表來記錄GITD(表mysql.gtid_executed),每個事務提交時,將GTID插入到表中)
... 以上參數是必須的,其他參數自行配置

重啓Slave,因爲MySQL5.6不支持動態配置GTID


授權複製連接用戶:

mysql> grant replication slave on *.*to repliter@'192.168.32.2' identified by PASSWORD '*6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9';
Query OK, 0 rows affected, 2 warnings (0.00 sec)


配置主從複製過濾規則:

[root@slave mysql3306]# cat my.cnf

replicate_do_db=edusoho_e


準備複製數據:

mysql> show master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000001 |      151 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)


創建statistic庫:
mysql> create database statistic;
Query OK, 1 row affected (0.01 sec)

創建statistic.t1表:
CREATE TABLE `statistic`.`t1` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`xname` VARCHAR(20) NOT NULL DEFAULT '',
`address` CHAR(20) NOT NULL DEFAULT '',
`sex` TINYINT(1) NOT NULL DEFAULT '1',
`hobby` VARCHAR(30) NOT NULL DEFAULT '',
`age` TINYINT(2) DEFAULT '18',
PRIMARY KEY (`id`),
KEY `idx_name` (`xname`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

創建edusoho_e庫:
mysql> create database edusoho_e;
Query OK, 1 row affected (0.01 sec)

創建edusoho_e.t1表:
CREATE TABLE `edusoho_e`.`t1` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`xname` VARCHAR(20) NOT NULL DEFAULT '',
`address` CHAR(20) NOT NULL DEFAULT '',
`sex` TINYINT(1) NOT NULL DEFAULT '1',
`hobby` VARCHAR(30) NOT NULL DEFAULT '',
`age` TINYINT(2) DEFAULT '18',
PRIMARY KEY (`id`),
KEY `idx_name` (`xname`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;


插入測試數據:
INSERT INTO `statistic`.`t1` (`xname`, `address`, `hobby`) VALUES ('statistic', '北京', '遊戲');
INSERT INTO `edusoho_e`.`t1` (`xname`, `address`, `hobby`) VALUES ('edusoho_e', '上海', '開發');


mysql> show master status;
+---------------+----------+--------------+------------------+------------------------------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+---------------+----------+--------------+------------------+------------------------------------------+
| binlog.000001 |     2139 |              |                  | b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-6 |
+---------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)


導出複製數據:

[root@master mysql3306]# mysqldump -uroot -p -B edusoho_e > `date +%F`.sql(參數什麼含義自己查閱文檔吧)
Enter password:
Warning: A partial dump from a server that has GTIDs will by default include the GTIDs of all transactions, even those that changed suppressed parts of the database. If you don't want to restore GTIDs, pass --set-gtid-purged=OFF. To make a complete dump, pass --all-databases --triggers --routines --events.


Slave主機導入複製數據:

[root@slave mysql3306]# mysql -uroot -p < 2019-05-28.sql
Enter password:


開啓數據複製:
mysql> CHANGE MASTER TO MASTER_HOST='192.168.32.3',MASTER_PORT=3306,MASTER_AUTO_POSITION=1;
Query OK, 0 rows affected (0.02 sec)
MASTER_AUTO_POSITION=1,表示MySQl會通過內部機制自動找點同步,不在需要人工確認file和position


mysql> start slave user='repliter' password='123456';
Query OK, 0 rows affected, 1 warning (0.03 sec)
爲了複製安全,不在master.info文件保存複製數據時的賬號和密碼


查看主從複製狀態時,如果出現如下的錯誤,則是因爲binlog_format不一致導致。
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_Running: Yes
Slave_SQL_Running: No
Last_Errno: 1666
Last_Error: Error executing row event: 'Cannot execute statement: impossible to write to binary log since statement is in row format and BINLOG_FORMAT = STATEMENT.'


查看Master、Slave的binlog_format是否一致:(因爲筆者的Master上binlog爲ROW格式,而Slave的binlog爲STATEMENT格式,所以語句不能夠被執行)
SELECT @@binlog_format;
STATEMENT


修改Slave my.cnf 文件後,重啓Slave數據庫


再次查看主從複製狀態,如果出現如下錯誤,則是因爲Slave重啓的時候,會自動開啓複製狀態(即 start slave,會根據master.info文件信息進行復制),因爲筆者爲了複製安全,在進行主從複製時才指定了賬號和密碼,所以出現了此錯誤
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_Running: No
Slave_SQL_Running: Yes
Last_IO_Errno: 1593
Last_IO_Error: Fatal error: Invalid (empty) username when attempting to connect to the master server. Connection attempt terminated.


mysql> stop slave;
Query OK, 0 rows affected (0.02 sec)

mysql> start slave user='repliter' password='123456';
Query OK, 0 rows affected, 1 warning (0.05 sec)


數據測試:

INSERT INTO `statistic`.`t1` (`xname`, `address`, `hobby`) VALUES ('GTID-statistic', '北京', '遊戲');
INSERT INTO `edusoho_e`.`t1` (`xname`, `address`, `hobby`) VALUES ('GTID-edusoho_e', '上海', '開發');


至此,基於MySQL5.6的GTID複製模式搭建完成。


主從複製模式常見的一些故障:


針對複製過程中常見的1032和1062錯誤進行故障模擬和恢復


模擬1032(delete或update)故障,原理相通,這裏只模擬delete故障:
Slave主機:
DELETE FROM `edusoho_e`.`t1` WHERE id=29;

mysql> show slave status\G;
*************************** 1. row ***************************
Master_UUID: b6af5b5c-666f-11e9-bed3-000c29b85ea6
Retrieved_Gtid_Set: b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-2
Executed_Gtid_Set: a951db35-340a-11e8-b0e0-000c291e8778:1-3,
b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-2

[root@slave ~]#cat auto.cnf
[auto]
server-uuid=a951db35-340a-11e8-b0e0-000c291e8778
可以看到,在Slave執行了此語句

Master主機:
DELETE FROM `edusoho_e`.`t1` WHERE id=29;

Slave主機:
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_Running: Yes
Slave_SQL_Running: No
Last_Errno: 1032
Last_Error: Could not execute Delete_rows event on table edusoho_e.t1; Can't find record in 't1', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000001, end_log_pos 1044
Exec_Master_Log_Pos: 795


在Master主機上分析日誌:
[root@master mysql3306]# mysqlbinlog -v --base64-output=decode mysql-bin.000001 --start-position=795
/*!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 795
#190518 13:46:06 server id 1  end_log_pos 843 CRC32 0x8e4fa01b  GTID [commit=yes]
SET @@SESSION.GTID_NEXT= 'b6af5b5c-666f-11e9-bed3-000c29b85ea6:3'/*!*/;
# at 843
#190518 13:46:06 server id 1  end_log_pos 920 CRC32 0x757be441  Query   thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1558158366/*!*/;
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=1073741824/*!*/;
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/*!*/;
BEGIN
/*!*/;
# at 920
#190518 13:46:06 server id 1  end_log_pos 981 CRC32 0x7df5817b  Table_map: `edusoho_e`.`t1` mapped to number 216
# at 981
#190518 13:46:06 server id 1  end_log_pos 1044 CRC32 0xcdff2b35     Delete_rows: table id 216 flags: STMT_END_F
### DELETE FROM `edusoho_e`.`t1`
### WHERE
###   @1=29
###   @2='小三'
###   @3='鬥羅'
###   @4=1
###   @5='小舞'
###   @6=18
# at 1044
#190518 13:46:06 server id 1  end_log_pos 1075 CRC32 0xcbc14f3a     Xid = 442
COMMIT/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;


查看Master事件:

mysql> show binlog events in 'mysql-bin.000001' from 795;
+------------------+------+-------------+-----------+-------------+-------------------------------------------------------------------+
| Log_name         | Pos  | Event_type  | Server_id | End_log_pos | Info                                                              |
+------------------+------+-------------+-----------+-------------+-------------------------------------------------------------------+
| mysql-bin.000001 |  795 | Gtid        |         1 |         843 | SET @@SESSION.GTID_NEXT= 'b6af5b5c-666f-11e9-bed3-000c29b85ea6:3' |
| mysql-bin.000001 |  843 | Query       |         1 |         920 | BEGIN                                                             |
| mysql-bin.000001 |  920 | Table_map   |         1 |         981 | table_id: 216 (edusoho_e.t1)                                      |
| mysql-bin.000001 |  981 | Delete_rows |         1 |        1044 | table_id: 216 flags: STMT_END_F                                   |
| mysql-bin.000001 | 1044 | Xid         |         1 |        1075 | COMMIT /* xid=442 */                                              |
+------------------+------+-------------+-----------+-------------+-------------------------------------------------------------------+
5 rows in set (0.01 sec)


在Slave上使用 sql_slave_skip_counter 語句跳過複製錯誤:
mysql> set global sql_slave_skip_counter=1;
ERROR 1858 (HY000): sql_slave_skip_counter can not be set when the server is running with @@GLOBAL.GTID_MODE = ON. Instead, for each transaction that you want to skip, generate an empty transaction with the same GTID as the transaction


結論:

GTID複製模式不支持 sql_slave_skip_counter 語法


根據 "show binlog events in 'mysql-bin.000001' from 795;" 結果,跳過問題GTID語句
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

mysql> set gtid_next='b6af5b5c-666f-11e9-bed3-000c29b85ea6:3';
Query OK, 0 rows affected (0.00 sec)

mysql> begin;commit;
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> set gtid_next='automatic';
Query OK, 0 rows affected (0.00 sec)

mysql> start slave user='repliter' password='123456';
Query OK, 0 rows affected, 1 warning (0.01 sec)


模擬1062(Duplicate entry)故障和1032(delete)故障:

Slave主機:
INSERT INTO `edusoho_e`.`t1` (`xname`, `address`, `hobby`) VALUES ('孫悟空', '西遊記', '吃桃');
DELETE FROM `edusoho_e`.`t1` WHERE id=21;

Master主機:
INSERT INTO `edusoho_e`.`t1` (`xname`, `address`, `hobby`) VALUES ('孫悟空', '西遊記', '吃桃');
DELETE FROM `edusoho_e`.`t1` WHERE id=21;

Slave主機查看主從複製狀態:
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_Running: Yes
Slave_SQL_Running: No
Last_Errno: 1062
Last_Error: Could not execute Write_rows event on table edusoho_e.t1; Duplicate entry '40' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-bin.000001, end_log_pos 1660
Exec_Master_Log_Pos: 1405
Master_UUID: b6af5b5c-666f-11e9-bed3-000c29b85ea6
Retrieved_Gtid_Set: b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-6
Executed_Gtid_Set: a951db35-340a-11e8-b0e0-000c291e8778:1-5,
b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-4

到Master上分析binlog日誌:
[root@master mysql3306]# mysqlbinlog -v --base64-output=decode mysql-bin.000001 --start-position=1405
/*!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 1405
#190518 14:10:11 server id 1  end_log_pos 1453 CRC32 0x82d40d30     GTID [commit=yes]
SET @@SESSION.GTID_NEXT= 'b6af5b5c-666f-11e9-bed3-000c29b85ea6:5'/*!*/;
# at 1453
#190518 14:10:11 server id 1  end_log_pos 1530 CRC32 0x705ae8d6     Query   thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1558159811/*!*/;
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=1073741824/*!*/;
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/*!*/;
BEGIN
/*!*/;
# at 1530
#190518 14:10:11 server id 1  end_log_pos 1591 CRC32 0xb8b8a906     Table_map: `edusoho_e`.`t1` mapped to number 216
# at 1591
#190518 14:10:11 server id 1  end_log_pos 1660 CRC32 0x17c98361     Write_rows: table id 216 flags: STMT_END_F
### INSERT INTO `edusoho_e`.`t1`
### SET
###   @1=40
###   @2='孫悟空'
###   @3='西遊記'
###   @4=1
###   @5='吃桃'
###   @6=18
# at 1660
#190518 14:10:11 server id 1  end_log_pos 1691 CRC32 0xec40ec8e     Xid = 462
COMMIT/*!*/;
# at 1691
#190518 14:10:11 server id 1  end_log_pos 1739 CRC32 0x663e798e     GTID [commit=yes]
SET @@SESSION.GTID_NEXT= 'b6af5b5c-666f-11e9-bed3-000c29b85ea6:6'/*!*/;
# at 1739
#190518 14:10:11 server id 1  end_log_pos 1816 CRC32 0x6fc29929     Query   thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1558159811/*!*/;
BEGIN
/*!*/;
# at 1816
#190518 14:10:11 server id 1  end_log_pos 1877 CRC32 0x640b0fb0     Table_map: `edusoho_e`.`t1` mapped to number 216
# at 1877
#190518 14:10:11 server id 1  end_log_pos 1958 CRC32 0x79ae56b5     Delete_rows: table id 216 flags: STMT_END_F
### DELETE FROM `edusoho_e`.`t1`
### WHERE
###   @1=21
###   @2='我是誰'
###   @3='不知道'
###   @4=1
###   @5='吃了睡睡了吃'
###   @6=18
# at 1958
#190518 14:10:11 server id 1  end_log_pos 1989 CRC32 0xbeb28116     Xid = 471
COMMIT/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;


查看Master事件:

mysql> show binlog events in 'mysql-bin.000001' from 1405;
+------------------+------+-------------+-----------+-------------+-------------------------------------------------------------------+
| Log_name         | Pos  | Event_type  | Server_id | End_log_pos | Info                                                              |
+------------------+------+-------------+-----------+-------------+-------------------------------------------------------------------+
| mysql-bin.000001 | 1405 | Gtid        |         1 |        1453 | SET @@SESSION.GTID_NEXT= 'b6af5b5c-666f-11e9-bed3-000c29b85ea6:5' |
| mysql-bin.000001 | 1453 | Query       |         1 |        1530 | BEGIN                                                             |
| mysql-bin.000001 | 1530 | Table_map   |         1 |        1591 | table_id: 216 (edusoho_e.t1)                                      |
| mysql-bin.000001 | 1591 | Write_rows  |         1 |        1660 | table_id: 216 flags: STMT_END_F                                   |
| mysql-bin.000001 | 1660 | Xid         |         1 |        1691 | COMMIT /* xid=462 */                                              |
| mysql-bin.000001 | 1691 | Gtid        |         1 |        1739 | SET @@SESSION.GTID_NEXT= 'b6af5b5c-666f-11e9-bed3-000c29b85ea6:6' |
| mysql-bin.000001 | 1739 | Query       |         1 |        1816 | BEGIN                                                             |
| mysql-bin.000001 | 1816 | Table_map   |         1 |        1877 | table_id: 216 (edusoho_e.t1)                                      |
| mysql-bin.000001 | 1877 | Delete_rows |         1 |        1958 | table_id: 216 flags: STMT_END_F                                   |
| mysql-bin.000001 | 1958 | Xid         |         1 |        1989 | COMMIT /* xid=471 */                                              |
+------------------+------+-------------+-----------+-------------+-------------------------------------------------------------------+
10 rows in set (0.00 sec)

Slave上先跳過第一個問題GTID:
mysql> set GTID_NEXT= 'b6af5b5c-666f-11e9-bed3-000c29b85ea6:5';begin;commit;
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> set gtid_next='automatic';
Query OK, 0 rows affected (0.00 sec)

mysql> start slave sql_thread;
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_Running: Yes
Slave_SQL_Running: No
Last_Errno: 1032
Last_Error: Could not execute Delete_rows event on table edusoho_e.t1; Can't find record in 't1', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000001, end_log_pos 1958
Exec_Master_Log_Pos: 1691
Master_UUID: b6af5b5c-666f-11e9-bed3-000c29b85ea6
Retrieved_Gtid_Set: b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-6
Executed_Gtid_Set: a951db35-340a-11e8-b0e0-000c291e8778:1-5,
b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-5

從上面主從複製狀態就可以看出已經成功跳過了第一個問題GTID,接下來跳過第二個
mysql> SET GTID_NEXT= 'b6af5b5c-666f-11e9-bed3-000c29b85ea6:6';begin;commit;
Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

Query OK, 0 rows affected (0.00 sec)

mysql> set gtid_next='automatic';
Query OK, 0 rows affected (0.00 sec)

mysql> start slave sql_thread;
Query OK, 0 rows affected (0.01 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Retrieved_Gtid_Set: b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-6
Executed_Gtid_Set: a951db35-340a-11e8-b0e0-000c291e8778:1-5,
b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-6


可以看到,主從間的複製故障已經成功跳過,主從恢復正常的複製狀態


模擬Slave尚未同步Master的GTID前,Master將這部分的GTID清除了(purge):

Master主機:
CREATE TABLE `bbs`.`t1` (
  `id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
  `xname` VARCHAR(20) NOT NULL DEFAULT '',
  `address` CHAR(20) NOT NULL DEFAULT '',
  `sex` TINYINT(1) NOT NULL DEFAULT '1',
  `hobby` VARCHAR(30) NOT NULL DEFAULT '',
  `age` TINYINT(2) DEFAULT '18',
  PRIMARY KEY (`id`),
  KEY `idx_name` (`xname`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

FLUSH LOGS;INSERT INTO `bbs`.`t1` (`xname`, `address`, `hobby`) VALUES ('lzb', '石家莊', 'MySQL');
mysql> show master status;
+------------------+----------+--------------+------------------+------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000002 |      455 |              |                  | b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-2 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)


Slave主機:
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.00 sec)

Master:
FLUSH LOGS;INSERT INTO `bbs`.`t1` (`xname`, `address`, `hobby`) VALUES ('Python', '北京', '遊戲');
mysql> show master status;
+------------------+----------+--------------+------------------+------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000003 |      456 |              |                  | b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-3 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)

FLUSH LOGS;INSERT INTO `bbs`.`t1` (`xname`, `address`, `hobby`) VALUES ('PHP', '上海', '開發');
mysql> show master status;
+------------------+----------+--------------+------------------+------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+------------------+----------+--------------+------------------+------------------------------------------+
| mysql-bin.000004 |      453 |              |                  | b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-4 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)


在Slave主機上GTID只是執行了1-2事務,而Master主機的3-4事務還沒有執行,現在模擬Slave未同步Master的3-4事務前,Master將日誌purge了

Master主機:
mysql> purge binary logs to 'mysql-bin.000004';
Query OK, 0 rows affected (0.04 sec)

mysql> show global variables like '%gtid%';
+--------------------------+------------------------------------------+
| Variable_name            | Value                                    |
+--------------------------+------------------------------------------+
| enforce_gtid_consistency | ON                                       |
| gtid_executed            | b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-4 |
| gtid_mode                | ON                                       |
| gtid_owned               |                                          |
| gtid_purged              | b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-3 |
+--------------------------+------------------------------------------+
5 rows in set (0.00 sec)

Slave主機:
mysql> start slave io_thread user='repliter' password='123456';
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_Running: No
Slave_SQL_Running: Yes
Last_IO_Errno: 1236
Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.'   (Slave未同步Master的3-4事務前,Master將日誌purge了)
Retrieved_Gtid_Set: b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-2
Executed_Gtid_Set: b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-2


現在在Slave主機上忽略掉purge掉的日誌部分,在進行數據複製:
因爲Slave_IO_Running: No 狀態爲NO,所以直接跳過purge掉的日誌部分就好
mysql> set global gtid_purged = 'b6af5b5c-666f-11e9-bed3-000c29b85ea6:3';
ERROR 1840 (HY000): @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.  (想要進行gtid_purged,必須gtid_executed 爲空)

mysql> show global variables like '%gtid%';
+--------------------------+------------------------------------------+
| Variable_name            | Value                                    |
+--------------------------+------------------------------------------+
| enforce_gtid_consistency | ON                                       |
| gtid_executed            | b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-2 |
| gtid_mode                | ON                                       |
| gtid_owned               |                                          |
| gtid_purged              |                                          |
+--------------------------+------------------------------------------+
5 rows in set (0.00 sec)


mysql> show master status;
+------------------+----------+--------------+------------------+------------------------------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+------------------+----------+--------------+------------------+------------------------------------------+
| slave-bin.000001 |      892 |              |                  | b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-2 |
+------------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)

mysql> reset master;(將Slave的 Executed_Gtid_Set 清空)
Query OK, 0 rows affected (0.02 sec)

mysql> set global gtid_purged = 'b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-3';
Query OK, 0 rows affected (0.03 sec)

開始複製:
start slave io_thread user='repliter' password='123456';

測試:
INSERT INTO `bbs`.`t1` (`xname`, `address`, `hobby`) VALUES ('DBA', '石家莊', '電影');


記錄 create dbname.tablename 語句不同步GTID的問題:

爲了更清楚的展示,先將Slave重置

mysql> stop slave;
Query OK, 0 rows affected (0.02 sec)

mysql> reset slave;
Query OK, 0 rows affected (0.02 sec)

mysql> reset master;
Query OK, 0 rows affected (0.03 sec)


SET @@session.sql_log_bin=0;


DROP DATABASE `edusoho_e`;


[root@slave mysql3306]# ls binlog.* relaylog.*
binlog.000001  binlog.index  relaylog.000001  relaylog.index

可以看到Slave已經重置


將Master也重置:

mysql> reset master;
Query OK, 0 rows affected (0.04 sec)

mysql> show master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000001 |      151 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)


SET @@session.sql_log_bin=0;
DROP DATABASE `edusoho_e`;


現在環境重置完了,我們不導出Master的複製數據到SLave,而是直接讓SLave從Master複製數據

創建edusoho_e庫:

mysql> create database edusoho_e;
Query OK, 1 row affected (0.01 sec)


創建edusoho_e.t1表:
mysql> CREATE TABLE `edusoho_e`.`t1` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`xname` VARCHAR(20) NOT NULL DEFAULT '',
`address` CHAR(20) NOT NULL DEFAULT '',
`sex` TINYINT(1) NOT NULL DEFAULT '1',
`hobby` VARCHAR(30) NOT NULL DEFAULT '',
`age` TINYINT(2) DEFAULT '18',
PRIMARY KEY (`id`),
KEY `idx_name` (`xname`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

Query OK, 0 rows affected (0.05 sec)


插入edusoho.t1測試數據:

mysql> INSERT INTO `edusoho_e`.`t1` (`xname`, `address`, `hobby`) VALUES ('edusoho_e', '上海', '開發');
Query OK, 1 row affected (0.01 sec)

mysql> show master status;
+---------------+----------+--------------+------------------+------------------------------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                        |
+---------------+----------+--------------+------------------+------------------------------------------+
| binlog.000001 |     1057 |              |                  | b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-3 |
+---------------+----------+--------------+------------------+------------------------------------------+
1 row in set (0.00 sec)


Slave開始複製:

[root@slave mysql3306]# ls binlog.* relaylog.*
binlog.000001  binlog.index  relaylog.000001  relaylog.index


mysql> change master to master_auto_position=1,master_host='192.168.32.3',master_port=3306;
Query OK, 0 rows affected (0.06 sec)


[root@slave mysql3306]# ls binlog.* relaylog.*
binlog.000001  binlog.index  relaylog.000001  relaylog.index


mysql> start slave user='repliter' password='123456';
Query OK, 0 rows affected, 1 warning (0.01 sec)


[root@slave mysql3306]# ls binlog.* relaylog.*
binlog.000001  binlog.index  relaylog.000001  relaylog.000002  relaylog.index


發生了什麼,你沒看錯,relay log,在開始複製線程之後,自動滾動了一個(至於爲什麼,筆者記得應該是爲了relay log的一致性,開啓了某參數,在重啓Slave之後,自動滾動的)


另外,你就會發現 create dbname.tablename 的GTID沒有同步過去,雖然報 'edusoho_e.t1' doesn't exist' 問題,但是去分析 relaylog.000002 文件然後你會發現是有 create dbname.tablename 的語句的,但是Slave卻沒有執行,Executed_Gtid_Set 已經表明了這一點(關於這一點,筆者也是無意中發現的,不知道是不是bug,筆者用的是5.6.16版本,但是MySQL5.7.24版本的GTID筆者也有測過,也發現了同樣的問題,難道是 create dbname.tablename 被限制使用,而筆者沒發現這方面的說明?對於這個問題,筆者會持續關注,有了結果,也會及時更新此博客,當然了,如果有業內大神路過,也請指點下,不勝感激!)

mysql> show slave status\G;
*************************** 1. row ***************************

Master_Log_File: binlog.000001
Read_Master_Log_Pos: 1057
Relay_Log_File: relaylog.000002
Relay_Log_Pos: 987
Relay_Master_Log_File: binlog.000001
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB: edusoho_e
Last_Errno: 1146
Last_Error: Error executing row event: 'Table 'edusoho_e.t1' doesn't exist'
Exec_Master_Log_Pos: 783
Retrieved_Gtid_Set: b6af5b5c-666f-11e9-bed3-000c29b85ea6:1-3
Executed_Gtid_Set: b6af5b5c-666f-11e9-bed3-000c29b85ea6:1
Auto_Position: 1


[root@slave mysql3306]# mysqlbinlog -v --base64-output=decode relaylog.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
#190528 18:08:48 server id 2  end_log_pos 120 CRC32 0x3d8251a5     Start: binlog v 4, server v 5.6.16-log created 190528 18:08:48
# at 120
#190528 18:08:48 server id 2  end_log_pos 151 CRC32 0x07d0253d     Previous-GTIDs
# [empty]
# at 151
#700101  8:00:00 server id 1  end_log_pos 0 CRC32 0x6ecad2e9     Rotate to binlog.000001  pos: 4
# at 195
#190528 17:59:23 server id 1  end_log_pos 120 CRC32 0x56fa9d7b     Start: binlog v 4, server v 5.6.16-log created 190528 17:59:23 at startup
ROLLBACK/*!*/;
# at 311
#190528 18:08:48 server id 0  end_log_pos 355 CRC32 0xbad86777     Rotate to binlog.000001  pos: 151
# at 355
#190528 18:05:21 server id 1  end_log_pos 199 CRC32 0x82870406     GTID [commit=yes]
SET @@SESSION.GTID_NEXT= 'b6af5b5c-666f-11e9-bed3-000c29b85ea6:1'/*!*/;
# at 403
#190528 18:05:21 server id 1  end_log_pos 308 CRC32 0x56a02447     Query    thread_id=8    exec_time=0    error_code=0
SET TIMESTAMP=1559037921/*!*/;
SET @@session.pseudo_thread_id=8/*!*/;
SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1/*!*/;
SET @@session.sql_mode=1073741824/*!*/;
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 database edusoho_e
/*!*/;
# at 512
#190528 18:05:37 server id 1  end_log_pos 356 CRC32 0xf5ec3898     GTID [commit=yes]
SET @@SESSION.GTID_NEXT= 'b6af5b5c-666f-11e9-bed3-000c29b85ea6:2'/*!*/;
# at 560
#190528 18:05:37 server id 1  end_log_pos 783 CRC32 0x366e81af     Query    thread_id=8    exec_time=0    error_code=0
SET TIMESTAMP=1559037937/*!*/;
CREATE TABLE `edusoho_e`.`t1` (
`id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT,
`xname` VARCHAR(20) NOT NULL DEFAULT '',
`address` CHAR(20) NOT NULL DEFAULT '',
`sex` TINYINT(1) NOT NULL DEFAULT '1',
`hobby` VARCHAR(30) NOT NULL DEFAULT '',
`age` TINYINT(2) DEFAULT '18',
PRIMARY KEY (`id`),
KEY `idx_name` (`xname`)
) ENGINE=INNODB DEFAULT CHARSET=utf8

/*!*/;
# at 987
#190528 18:05:48 server id 1  end_log_pos 831 CRC32 0xcc4e2884     GTID [commit=yes]
SET @@SESSION.GTID_NEXT= 'b6af5b5c-666f-11e9-bed3-000c29b85ea6:3'/*!*/;
# at 1035
#190528 18:05:48 server id 1  end_log_pos 899 CRC32 0x852bcbf9     Query    thread_id=8    exec_time=0    error_code=0
SET TIMESTAMP=1559037948/*!*/;
BEGIN
/*!*/;
# at 1103
#190528 18:05:48 server id 1  end_log_pos 960 CRC32 0xe8f450ec     Table_map: `edusoho_e`.`t1` mapped to number 544
# at 1164
#190528 18:05:48 server id 1  end_log_pos 1026 CRC32 0xe0c91caf     Write_rows: table id 544 flags: STMT_END_F
### INSERT INTO `edusoho_e`.`t1`
### SET
###   @1=1
###   @2='edusoho_e'
###   @3='上海'
###   @4=1
###   @5='開發'
###   @6=18
# at 1230
#190528 18:05:48 server id 1  end_log_pos 1057 CRC32 0xa0f363ed     Xid = 1431
COMMIT/*!*/;
DELIMITER ;
# End of log file
ROLLBACK /* added by mysqlbinlog */;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_T


好了,至此基於GTID複製模式搭建、故障模擬、問題解決全部講解完畢,對於其中不當之處,還請留言指正!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章