[toc]
1、概述
使用gtid跳过事务有两种方法:
- set gtid_next,可以跳过单个事务
- set GTID_PURGED,可以跳过多个事务
2、跳过单个事物
情景:
主新建了test.t1 表,从误操作删掉了test.t1;
主往test.t1中插入一条数据,从库报错
- 主:
mysql> begin;
mysql> insert into test.t1 values (1,1);
mysql> commit;
mysql> show master status \G
*************************** 1. row ***************************
File: mysql-bin.000002
Position: 3286
Binlog_Do_DB:
Binlog_Ignore_DB:
Executed_Gtid_Set: 59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:1-17
1 row in set (0.00 sec)
- 从:
mysql> show slave status \G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.234.130
Master_User: repl
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 3286
Relay_Log_File: ser2-relay-bin.000006
Relay_Log_Pos: 1141
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 1146
Last_Error: Worker 3 failed executing transaction '59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:17' at master log mysql-bin.000002, end_log_pos 3255; Error executing row event: 'Table 'test.t1' doesn't exist'
Skip_Counter: 0
Exec_Master_Log_Pos: 3045
Relay_Log_Space: 2699
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 1146
Last_SQL_Error: Worker 3 failed executing transaction '59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:17' at master log mysql-bin.000002, end_log_pos 3255; Error executing row event: 'Table 'test.t1' doesn't exist'
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: 59fe7a3e-9dd6-11e7-9d6c-000c29e57c69
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State:
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp: 170922 00:30:21
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: 59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:1-17
Executed_Gtid_Set: 29bd8c99-9e4d-11e7-a072-000c29d00b2d:1,
59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:1-16
Auto_Position: 1
1 row in set (0.00 sec)
通过查看我们得知:
从库在执行59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:17 这个事务时,因为从库没有这个表而报错了。
2. 解决思路:
- root用户手动重建test.t1表
- root用户手动在59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:17 这个事务上执行一个空事务
3. 解决步骤:
- 在从库上重建 test.t1 表
主库备份
# mysqldump -uroot -p123123 -h127.0.0.1 --single-transaction --set-gtid-purged=off --triggers --routines --events test t1 >/tmp/t1.sql
从库恢复
# cat t1.sql |mysql -uroot -p123123 test
- 从库在冲突事务号执行空事务
> stop slave;
> SET @@SESSION.GTID_NEXT= '59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:17'/*!*/;
> show variables like '%gtid%_next';
> BEGIN;COMMIT;
> SET gtid_next = 'AUTOMATIC';
> START SLAVE;
3、批量跳过
1. 情景模拟
由于数据不一致严重,跳过单个事务不能继续正常复制。
从库删掉单表,然后跳过批量sql,继续复制
- 从:
mysql> truncate table test.t1;
- 主:
mysql>
mysql> begin;
mysql> update test.t1 set age=11 where id=1; //如果只跳过这个事务,下个事务还是会出错
mysql> commit;
mysql> begin;
mysql> update test.t1 set age=33 where id=3;
mysql> commit;
2. 操作步骤
- 主库备份表
set-gtid-purged ==> SQL_LOG_BIN= 0、SET @@GLOBAL.GTID_PURGED
# mysqldump -uroot -p123123 -h127.0.0.1 --single-transaction --set-gtid-purged=on --triggers --routines --events test t1 >/tmp/t1.sql
# cat /tmp/t1.sql |egrep SET |egrep -v "^/"
SET @MYSQLDUMP_TEMP_LOG_BIN = @@SESSION.SQL_LOG_BIN;
SET @@SESSION.SQL_LOG_BIN= 0;
SET @@GLOBAL.GTID_PURGED='59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:1-22';
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
SET @@SESSION.SQL_LOG_BIN = @MYSQLDUMP_TEMP_LOG_BIN;
- 从库恢复
> reset master; //清空GTID_EXECUTED
# cat t1.sql |mysql -uroot -p123123 test
会执行备份文件中的SET @@GLOBAL.GTID_PURGED。 @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.
> show slave status \G
Retrieved_Gtid_Set: 59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:1-22
Executed_Gtid_Set: 59fe7a3e-9dd6-11e7-9d6c-000c29e57c69:1-22
> start slave;