记一次主从复制错误处理和修复过程(mysql5.7 gtid)

作者:51ak

MYSQL的复制会在极端条件下出现主从不一致的问题 原因有很多种,这里记一下比较完整的处理过程 网上的很多处理方法都是基于早期版本的没有GIID环境

stop slave;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1 ;
start slave;

这篇会介绍GIID下的复制错误快速恢复和修复过程

##收到报警 收到报警,一个从节点Slave_SQL_Running状态异常 当时是周末的晚上,看到报警时已经DOWN了10分钟了 联VPN到线上又花了几分钟 上线确认以下信息,确认是有问题

show slave status \G
#得到以下关键信息
Last_SQL_Error_Timestamp: 报错时间
Slave_SQL_Running: 报错进程
Slave_SQL_Running_State: 报错信息
 Could not execute Delete_rows event on table \*; Can't find record in '\*', Error_code: 1032; handler error HA_ERR_KEY_NOT_FOUND; the event's master log mysql-bin.002339, end_log_pos 162227594

##问题已确认,第二步确定影响 因为这个从库已经不同步了,需要保证业务没有影响 show processlist; 发现正常读业务已经被中件间切走了,只有BI的一个业务线因为用了DNS直连没有切走, 比较坑的是这个BI线不确定是谁负责的,但考虑BI应用读脏数据影响不大,就直接把问题交给值班人员让他联系了.(这里提一下,我们只有BI类应用会出现这种问题,业务类的访问已经都对接了具体的人)

##开始尝试修复复制 这里说的尝试修复是快速的修复问题,不能保证100%成功 使用的方法还是跳过报错的事务,使整个复制进行下去

show slave status \G
#找关键的Slave_SQL_Running_State 列的Error_code 内容 ,这里面是1032
#查系统表找到这个GTID:ed3e8c5d-b102-11e8-9dbc-1418773c97b3:534249277 并跳过它
select LAST_SEEN_TRANSACTION from performance_schema.replication_applier_status_by_worker where LAST_ERROR_NUMBER=1032;
stop slave ;
set @@session.gtid_next='ed3e8c5d-b102-11e8-9dbc-1418773c97b3:534249277';begin;commit;
set @@session.gtid_next=automatic;
start slave;

执行以后,观察复制开始往前走,过一段又报这个错(也就是说出错的信息不止一条) 多次跳过修复好(大约6次),复制终于稳定运行并同步上了线上数据

这里如果多次跳过都不好的话,建议直接放弃 保留现场继续排查问题,或者直接覆盖数据,重做从库

这个案例中我们修复了数据后,复制一直没再报错.但是很明显主从数据已经有不一致了,因为当时是周末 我们这个从库上没有业务访问(BI的已明确表示不在意延时数据的影响). 所以后面的修复从库历史数据的留到了周一

##修补从库的数据和定位问题 因为跳过了一些事务.暂时复制是好的,但是为了数据一致性.还是需要对比一下主从数据

只有一个从库有问题,对比了下和其他从库发现出问题的从库没有开 read_only True 因为已知问题我们的核心业务访问已经在中件间方式 但一些PYTHON脚本用了LVS来连接DB, lvs主探测脚本有BUG,需要在从库设置这个READ_ONLY来避免 不幸的是这台从库漏改了.所以原因已经基本定位了 接下来我们需要找到主从数据的异常 1.修复 2.跟业务确认时间段是否由上面推测的原因引起

对比数据可以用PT的checksum工具 我们这里已经明确定位了有异常 直接生成了修补脚本

pt-table-sync --print  --sync-to-master --charset=utf8mb4 --ignore-databases=mysql,sys,performance_schema,information_schema    h='ip地址',u='username',p='password',P=端口号 > pt201905.log

为了不影响主库,我们在这一步之前还把master change 到了一台确定没问题的从上(这个不是必须的)

运行以上脚本 log中的脚本发给RD确定问题 同时在问题从库

stop slave;
set sql_log_bin=0;
#要修补的数据
set sql_log_bin=1;

start slave;

完成修补 观察复制正常,历史数据修复完成.

故障处理完

以上是一次基本的简单的主从复制流程 .

发布日期:2019/05/27

Categories: mysql复制 mysql高可用 mysql 故障处理 Tags: 原创