一 问题
巡检发现mysql5.7的主从库有一个从库与主库断开同步,应该是版本升级时主从不同步,原从库变为主了,而原主库变为从库了,且数据比现在主库多。
2023-11-14T15:23:00.919194+08:00 2 [ERROR] Slave SQL for channel '': Could not execute Write_rows event on table xxxxx.xxxxxxx; Duplicate entry '11913053' for key 'PRIMARY', Error_code: 1062; handler error HA_ERR_FOUND_DUPP_KEY; the event's master log mysql-bin.000016, end_log_pos 10355, Error_code: 1062
2023-11-14T15:23:00.919221+08:00 2 [Warning] Slave: Duplicate entry '11913053' for key 'PRIMARY' Error_code: 1062
2023-11-14T15:23:00.919231+08:00 2 [ERROR] Error running query, slave SQL thread aborted. Fix the problem, and restart the slave SQL thread with "SLAVE START". We stopped at log 'mysql-bin.000016' position 10088.
二 解决
1、清理从库数据,从主库重新导入并同步。
1)、备份从库
便于业务找回。
2)、备份主库
/usr/local/mysql/bin/mysqldump -h127.0.0.1 -P3306 -uroot -pxxxxx --master-data=2 --flush-logs --routines --single-transaction --databases xxxxxxxx --set-gtid-purged=OFF --default-character-set=utf8mb4 > /tmp/mysqldump/3306_all.sql
–single-transaction 启用一个事务来进行备份操作,备份过程中不会对数据库进行锁操作
–master-data=1 备份必须加上此参数。当这个参数的值为1的时候,mysqldump出来的文件就会包括CHANGE MASTER TO这个语句。当这个参数的值为2的时候,CHANGE MASTER TO这个语句是被注销的。
3)、查看备份日志位置
head -100 3306_all.sql 找到日志位置
– CHANGE MASTER TO MASTER_LOG_FILE=‘mysql-bin.000098’, MASTER_LOG_POS=234;
4)、恢复从库
mysql> stop slave;
mysql> reset slave all;
需要加上all,不然同步会报错。ERROR 1776 (HY000): Parameters MASTER_LOG_FILE, MASTER_LOG_POS, RELAY_LOG_FILE and RELAY_LOG_POS cannot be set when MASTER_AUTO_POSITION is active.
mysql> change master to master_host='xx.xxx.xxx.xxx',master_user='repl',master_password='xxxxx',master_port=3306,MASTER_LOG_FILE='mysql-bin.000098', MASTER_LOG_POS=234;
mysql> start slave;
mysql> show slave status\G;
2、跳过事务
我个人建议使用上面第一个方法,因为这个第二个方法虽然能跳过一个事务,后面还可能出现问题,因为我们不知道这个从库比主库多了多少数据。这个方法适合于比较了解从库数据情况下。
1)查看错误事务
查看本机的UUID号
show global variables like ‘server_uuid’;
在下面可以看到错误SQL语句信息。
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: xxxxxxx
Master_User: xxxxx
Master_Port: 3307
Connect_Retry: 60
Master_Log_File: mysql-bin.000030
Read_Master_Log_Pos: 13641849
Relay_Log_File: xxxxxxxx-relay-bin.000006
Relay_Log_Pos: 13634503
Relay_Master_Log_File: mysql-bin.000030
Slave_IO_Running: Yes
Slave_SQL_Running: Yes ###如果是NO就是从库停止同步了。
Exec_Master_Log_Pos: 13641849 ###恢复到那个位置了
Master_UUID: a09e0c1f-0b5b-11ea-9254-005056841e90 ##主的UUID
Retrieved_Gtid_Set: a09e0c1f-0b5b-11ea-9254-005056841e90:1281937-1306359 ###已接收到的事务号
Executed_Gtid_Set: a09e0c1f-0b5b-11ea-9254-005056841e90:1-1306359,
d9980786-0b5b-11ea-8d9d-00505684bc5b:1-677
###已执行过的事务号,根据UUID可以看到a09e0c1f-0b5b-11ea-9254-005056841e90是master节点UUID。d9980786-0b5b-11ea-8d9d-00505684bc5b是本机节点UUID。如果a09e0c1f-0b5b-11ea-9254-005056841e90:1-1306359后面这个1306359小于Retrieved_Gtid_Set后面接收到的号(多刷几次),就证明从节点停止应用主节点日志了。
mysql> stop slave;
mysql> set gtid_next=‘a09e0c1f-0b5b-11ea-9254-005056841e90:1306359’;
mysql> begin;commit;
提交一个空事务,跳过了卡住的问题事务。
mysql> set gtid_next=‘AUTOMATIC’;
恢复GTID自动
mysql> start slave;
开启同步
2)查看binlog内容
如果想查看错误事务前后的事务信息
show binary logs; ##查看binlog日志名称,也可以从上面show slave status看当前问题的日志号。
show binlog events in ‘mysql-bin.000030’ from limit xx;