有同事反馈他们搭建的MySQL库主从同步报错了,需要协助帮忙修复。检查同步报错如下

image.png

可以看到是由于两边数据不一致,主库host表的某条数据在从库不存在,导致同步时执行update报错。

修复的原理很简单,找到主从不一致的这条数据,在从库补上,让update能执行就好。由于需要从binlog里找数据,需要确保中断之后的binlog没被删除,否则就只能重搭了。

1. 主库查询对应binlog记录

注意如果装了多个版本的mysql,mysqlbinlog命令需要写全路径。其中stop-position和binlog名就对应的是前面报错中的信息。生成的文件可能比较大,最慢的情况下会跟这个binlog文件一样大,需要等一会。

mysqlbinlog -v --stop-position=537973695 /binlog_path/mysql-bin.000001 > /tmpbinlog.log

2. 查询记录end_log_pos=537973695所在位置,找到对应update语句

当然如果生成的文件很小可以直接打开搜索,但处理的时候文件有2G,显然不合适

cat tmpbinlog.log | awk '/end_log_pos 537973695/ {print NR}'
#输出所在行数为:68381343
#查看其前后行(50行左右差不多够了),找出其对应的sql语句
cat tmpbinlog.log | awk 'NR==68381330,NR==68381380'

image.png

image.png

hosts表第一个字段是主键hostid,拿该条件来查即可,查完发现从库果然没有

--从库查询
select hostid from hosts where hostid = 18013;
Empty set (0.00 sec)

3. 数据修复

如果表结构和值特别简单,可以直接写insert语句在从库插入。

如果较为复杂,则在主库创建临时表并dump,在从库执行dump文件中的insert语句。

主库执行

create table tmphost like hosts;
insert into tmphost select * from hosts where hostid=18013;
commit

dump数据

mysqldump -uroot -p zabbix tmphost > tmphost.sql

image.png

找到对应insert语句并在从库执行

image.png

4. 恢复同步

stop slave;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;  -- 跳过一个事务,可选
start slave;
 
show slave status\G;

如果没有其他报错,主从同步就顺利恢复啦~