导读
最近遇到一个mysql主从报错1032的问题. 比较离谱.所以记录一下.
由于比较离谱, 这里没能复现出来(我是在5744上测试的, 后面有机会再测试下5741), 所以没法给出相关截图. 只能简单描述一下.
环境说明
mysql 5.7.41
GTID_MODE = ON
slave_parallel_workers = 4
slave_rows_search_algorithms = TABLE_SCAN,INDEX_SCAN
slave_parallel_type = LOGICAL_CLOCK
binlog_rows_query_log_events = ON # 记录SQL方便问题排查.
问题表无主键, 但有普通索引.
问题
主从报错 sql线程 1032 使用如下SQL查询具体的报错位置和表
select * from performance_schema.replication_applier_status_by_worker\G
分析过程
这个报错很常见, 就是表示数据不存在. 要验证的话, 也比较简单, 直接把该位点的数据解析出来对比即可.
可以使用pymysqlbinlog, 但不一定都有这些工具, 这里还是使用mysqlbinlog来演示.
参考命令:
mysqlbinlog -vvv mysql-bin.00xxxx --start-position=xx --stop-position=yy | grep -A 30 "TABLENAME" | grep '### @' | awk 'ORS=NR%23?"\t":"\n"' > xxx.txt
mysql -NB -e "select * from xx" > yyy.txt # 这里的23 表示这张表有23行
然后使用diff比较两个文件 是否一致. 由于double 精度问题, double字段会显示会不一致. 所以我们可以去掉该列
awk '{$12=""; print $0}' xxx.txt
本次环境测试校验 发现数据是一致的.
所以就把数据恢复到测试环境, 并滚binlog到该点位
mysqlbinlog mysql-bin.000xxx --stop-position=xx | mysql
然后查询出该表的数据 和 从库做校验, 发现也是完全一致的(md5和行数都完全一样)…
这就开始离谱了. 主从数据完全一致, 主库产生的binlog 从库却执行不了. 于是就准备让主库自己去执行看下.
继续回放主库的binlog. 然后就报错了(1032) 240W行左右, 解析发现就是那个 delete_event… 也就是主库产生的binlog, 主库自己都回放不了, 也就不怪从库了.
解决办法
解决起来还是比较简单的, 就是加个主键就行. 所以有主键还是很重要.
其它
本次实验未能复现出来(感觉高版本也可能有这个问题), 后面有空了,再研究.