1、數據庫版本
mysql> select version()
-> ;
+-------------------------------------------+
| version() |
+-------------------------------------------+
| 5.7.17 |
+-------------------------------------------+
1 row in set (0.00 sec)
--主從同步
10.10.6.87 主
10.10.90 從
2、產生問題過程
(1)主從庫開啓了GTID模式
(2)在從庫某表添加了唯一索引,然後去主庫給某表添加索引,導致問題 (此處爲了測試,故意爲之,製造問題)
'Duplicate key name 'i_index'' on query. Default database: 'test'. Query: 'create unique index i_index on t(id)'
(3) 查看從庫狀態,發現Slave_SQL_Running: No
mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 10.10.6.87
Master_User: rep
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000028
Read_Master_Log_Pos: 1113
Relay_Log_File: mysql-bin.000007
Relay_Log_Pos: 1151
Relay_Master_Log_File: mysql-bin.000028
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB: mysql,information_schema
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 1061
Last_Error: Error 'Duplicate key name 'i_index'' on query. Default database: 'test'. Query: 'create unique index i_index on t(id)'
Skip_Counter: 0
Exec_Master_Log_Pos: 938
Relay_Log_Space: 2301
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: 1061
Last_SQL_Error: Error 'Duplicate key name 'i_index'' on query. Default database: 'test'. Query: 'create unique index i_index on t(id)'
Replicate_Ignore_Server_Ids:
Master_Server_Id: 2
Master_UUID: 8f9e146f-0a18-11e7-810a-0050568833c8
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0 #SQL延遲同步
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State:
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp: 170421 15:44:05
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: 8f9e146f-0a18-11e7-810a-0050568833c8:1-4
Executed_Gtid_Set: 8f9e146f-0a18-11e7-810a-0050568833c8:1-3, #多出了一個GTID(本身實例執行的事務)
f7c86e19-24fe-11e7-a66c-005056884f03:1-9
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
ERROR:
No query specified
3、解決問題過程:
mysql> stop slave sql_thread;
Query OK, 0 rows affected, 1 warning (0.00 sec)
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
mysql> stop slave;
Query OK, 0 rows affected (0.01 sec)
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原因
3.1 分析出現問題時候GTID值
通過分析法獲取gtid值
通過查看mysql> show slave status \G;
查看一下信息並記錄下來:
Retrieved_Gtid_Set: 8f9e146f-0a18-11e7-810a-0050568833c8:1-4 --跳過此事務
Executed_Gtid_Set: 8f9e146f-0a18-11e7-810a-0050568833c8:1-3,f7c86e19-24fe-11e7-a66c-005056884f03:1-9
通過上面的信息可以知道已經執行的gtid是8f9e146f-0a18-11e7-810a-0050568833c8:1-3,準備要執行8f9e146f-0a18-11e7-810a-0050568833c8:4的時候出問題了,所以條跳過此步驟
或者 通過日誌查看 (推薦)
#170421 15:36:28 server id 2 end_log_pos 938 CRC32 0x9f9f38d8 Xid = 140
COMMIT/*!*/;
# at 938
#170421 15:39:10 server id 2 end_log_pos 1003 CRC32 0x20f00692 GTID last_committed=3sequence_number=4
SET @@SESSION.GTID_NEXT= '8f9e146f-0a18-11e7-810a-0050568833c8:4'/*!*/;
# at 1003
#170421 15:39:10 server id 2 end_log_pos 1113 CRC32 0x4b10f015 Query thread_id=25420exec_time=0error_code=0
use `test`/*!*/;
SET TIMESTAMP=1492760350/*!*/;
create unique index i_index on t(id)
/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
解決辦法一:跳過錯誤
(1)停止slave進程
mysql> STOP SLAVE;
(2)設置事務號,事務號從Retrieved_Gtid_Set獲取
在session裏設置gtid_next,即跳過這個GTID
mysql> SET @@SESSION.GTID_NEXT= '8f9e146f-0a18-11e7-810a-0050568833c8:4'
(3)設置空事物
mysql> BEGIN; COMMIT;
(4)恢復事物號
mysql> SET SESSION GTID_NEXT = AUTOMATIC;
(5)啓動slave進程
mysql> START SLAVE;
解決辦法二:重置master方法跳過錯誤(推薦)
mysql> STOP SLAVE;
mysql> RESET MASTER;
mysql> SET @@GLOBAL.GTID_PURGED ='8f9e146f-0a18-11e7-810a-0050568833c8:1-4'
mysql> START SLAVE;
上面這些命令的用意是,忽略8f9e146f-0a18-11e7-810a-0050568833c8:1-4 這個GTID事務,下一次事務接着從 5 這個GTID開始,即可跳過上述錯誤。
解決辦法三:使用pt-slave-restart工具
pt-slave-restart工具的作用是監視某些特定的複製錯誤,然後忽略,並且再次啓動SLAVE進程(Watch and restart MySQL replication after errors)。
忽略所有1062錯誤,並再次啓動SLAVE進程
[root@dgt mysql]# pt-slave-resetart -S /var/lib/mysql/mysql.sock —error-numbers=1062
檢查到錯誤信息只要包含 test.t1,就一概忽略,並再次啓動 SLAVE 進程
[root@dgt mysql]# pt-slave-resetart -S /var/lib/mysql/mysql.sock —error-text=”test.t1”
下面舉例解決錯誤問題號
Last_SQL_Error: Could not execute Delete_rows event on table test.t; Can't find record in 't', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.000028, end_log_pos 1862
Replicate_Ignore_Server_Ids:
Master_Server_Id: 2
Master_UUID: 8f9e146f-0a18-11e7-810a-0050568833c8
Master_Info_File: /var/lib/mysql/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: 170421 17:45:11
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: 8f9e146f-0a18-11e7-810a-0050568833c8:1-7
Executed_Gtid_Set: 8f9e146f-0a18-11e7-810a-0050568833c8:1-6,
f7c86e19-24fe-11e7-a66c-005056884f03:1
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
[root@dgt mysql]# pt-slave-restart -S /var/lib/mysql/mysql.sock --error-numbers=1032 --user=root --password='bc.123456'
2017-04-21T17:53:27 S=/var/lib/mysql/mysql.sock,p=...,u=root mysql-bin.000015 620 1032
2017-04-21T17:54:31 S=/var/lib/mysql/mysql.sock,p=...,u=root mysql-bin.000015 1140 1032
參數解釋:
--slave-password=s Sets the password to be used to connect to the slaves
--slave-user=s Sets the user to be used to connect to the slaves
--sleep=i Initial sleep seconds between checking the slave ( default 1)
--socket=s -S Socket file to use for connection=
--password=s -p Password to use when connecting
pt-slave-resetart -S./mysql.sock —error-numbers=1032
--error-numbers=h Only restart this comma-separated list of errors
--host=s -h Connect to host
--user=s -u User for login if not current user