首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >面试高频题:哪些情况会导致MySQL主从复制异常?今天就遇到一种

面试高频题:哪些情况会导致MySQL主从复制异常?今天就遇到一种

作者头像
俊才
发布2026-04-28 13:16:17
发布2026-04-28 13:16:17
180
举报
文章被收录于专栏:数据库干货铺数据库干货铺

主从复制相关问题是面试中的高频面试题,而哪些场景会引起主从复制异常呢?

今天就遇到了一种主从复制中断的情况(SQL线程中断),查看日志报错是典型的1032错误,遇到这种开启别急着跳过事务!这可能是MySQL8.0并行复制与无主键表共同埋下的“定时炸弹”。本文带你深挖根源,从Binlog机制到Hash冲突,彻底解决这一顽疾。

一、异常现象

监控告警突然响起MySQL从库的SQL线程挂了。查看SHOW SLAVE STATUS,一行刺眼的报错映入眼帘:

代码语言:javascript
复制
Worker 1 failed executing transaction ...
Could not execute Update_rows_v1 event on table testdb.tb1;
Can't find record in '
tb1
', Error_code: 1032;
handler error HA_ERR_KEY_NOT_FOUND

典型的1032错误。意思是:主库发来一条更新指令,但从库在表里翻遍了也找不到这条记录。

很多DBA的第一反应是:“数据不一致嘛,跳过这个事务不就行了?”

慢着!如果你只是简单地使用sql_slave_skip_counter跳过,可能只是治标不治本。更有趣的是,报错的是Worker 1,这意味着你开启了并行复制。在MySQL8.0环境下,结合“无主键表”这一特征,这背后隐藏着一个更深层的机制陷阱。

二、为什么会找不到记录?

1032错误的字面意思是“找不到记录”,但在MySQL8.0的并行复制场景下,原因远比“被误删了”要复杂。

1. 直接原因:数据不一致

最直接的可能性是,这行数据在主库存在,但在从库被误删了(比如有人手抖在从库执行了DELETE,或者之前的某个事务同步失败)。当主库发来UPDATE指令时,从库拿着“更新前的镜像”去比对,发现查无此人,于是报错。

2. 根本原因:无主键表的“大海捞针”

报错的表tb1没有主键。主键是数据库用来快速、准确定位一行数据的“身份证号”。没有主键,从库在重放数据更新时,就只能进行低效且不可靠的“大海捞针”。

在binlog_format=ROW模式下,Binlog记录了行变更的完整前后镜像。

  • 有主键时:从库直接通过主键索引定位行,精准、快速。
  • 无主键时:从库被迫进行全表扫描,逐行比对所有字段,试图找到与Binlog中“旧值”完全一致的那一行。

3. 隐形杀手:MySQL8.0的Hash Scan算法缺陷

这是MySQL8.0的“坑”之一(或者说是一种策略)。为了优化无主键表在并行复制下的全表扫描性能,MySQL8.0引入了HASH_SCAN算法。

机制:它计算表中每一行数据的CRC32校验和,建立哈希映射来快速定位。

风险:如果表数据量大且没有主键,极易发生哈希冲突(不同的数据算出了相同的CRC32值)。一旦冲突,从库的SQL线程就会“看走眼”,要么匹配错行(比如多删除或更新),要么直接判定找不到行(被之前的操作处理或者匹配不上),从而抛出1032错误。

三、Binlog参数:是敌是友?

很多同学在排查时会问:这和Binlog参数有关吗?答案是:密切相关。

参数名

作用

推荐值

影响说明

slave_parallel_workers

并行复制工作线程数

4-16(根据CPU 核数)

>0启用并行复制,问题触发的前提条件

slave_parallel_type

并行复制类型

LOGICAL_CLOCK(8.0默认)

WRITESET模式下冲突检测更严格

binlog_format

二进制日志格式

ROW

基于行复制是无主键问题的核心场景

binlog_row_image

行镜像记录内容

FULL

MINIMAL模式会减少定位所需信息,加剧问题

require_table_primary_key_check

表主键检查

ON(8.0.20+)

强制检查无主键表,提前发现问题

transaction_write_set_extraction

事务哈希提取

XXHASH64

WRITESET模式必需,用于冲突检测

binlog_transaction_dependency_tracking

依赖关系跟踪

WRITESET(8.0.26+推荐)

提高并行度,但无主键表会失效

关键参数说明

  • binlog_format=ROW:这是“罪魁祸首”,也是最佳实践建议设置的参数设置值。虽然STATEMENT格式不会报1032(因为它重放SQL语句),但它会导致更多的主从不一致。ROW格式记录了数据的物理变化,对于无主键表,它要求从库必须能精确匹配所有列的值
  • slave_exec_mode:这是一个可以“救火”的参数。默认是STRICT(严格模式),遇到1032就报错。修复主从同步状态时可以将其设置为IDEMPOTENT(幂等模式)。在该模式下,从库会自动忽略1032(找不到行)和1062(主键冲突)错误。幂等性意味着“执行一次和执行多次效果一样”。如果找不到行要更新,幂等模式认为“既然没有,那就不更新了”,从而跳过报错。但是风险是这会掩盖数据不一致的真相,导致从库数据永久性缺失。

巧设slave_exec_mode参数的方法你还不会?

  • slave_parallel_workers:并行复制加剧了问题。多个Worker线程同时扫描无主键表,不仅消耗巨大的CPU和I/O,还增加了Hash冲突的概率。不过正常情况下还是建议开启并行复制

四、如何优雅地填坑?

面对这种情况,不要慌张,按以下步骤操作:

1. 临时止血(恢复业务)

如果业务不能停,可以先临时跳过错误,或者开启幂等模式。

代码语言:javascript
复制
-- 方法A:开启幂等模式(仅建议在 ROW 格式下临时使用)
SET GLOBAL slave_exec_mode = 'IDEMPOTENT';
START SLAVE;
-- 方法B:如果是 GTID 模式,精准跳过该事务
STOP SLAVE;
SET GTID_NEXT='1ce64ba5-716d-11ef-8a7f-fa163eeec86c:1196639450';
BEGIN;COMMIT;
SET GTID_NEXT='AUTOMATIC';
START SLAVE;

巧设slave_exec_mode参数的方法你还不会?

2. 定位问题

确认报错的表是否真的没有主键。

代码语言:javascript
复制
SHOW CREATE TABLE testdb.tb1;

同时,检查主库该条记录是否存在,确认是否发生了数据不一致。

3. 根治方案

给表加上主键!给表加上主键!给表加上主键!

这是解决此类问题的唯一长久之计。

  • 方案A(推荐):添加业务主键或自增主键。
代码语言:javascript
复制
ALTER TABLE testdb.tb1 ADD COLUMN id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY;
  • 方案B(MySQL8.0.30+特性):如果你不想破坏现有表结构,可以开启“不可见主键”功能。但是不推荐,因为出现过很多次问题。例如:

踩坑!MySQL这个参数让应用直接崩了,90%的DBA都忽略了!

如果有勇士敢于设置,那可以在配置文件中设置sql_generate_invisible_primary_key=ON,MySQL会自动为无主键表生成一个隐藏的row_id,既能满足复制需求,又不影响业务SQL。

4. 数据修复

加上主键后,建议重建从库,或者使用pt-table-sync工具进行主从数据一致性修复,确保从库不再因为“找不到行”而报错。

MySQL数据库主从数据对比及修复

五、总结

MySQL8.0的并行复制虽然提升了性能,但也对表结构设计提出了更高的要求。

1032错误不仅仅是数据不一致的信号,更是表结构缺陷的警报。在MySQL8.0中,无主键表就是并行复制的“地雷”。请检查你的数据库,消灭所有没有主键的表,这才是DBA的自我修养。

大家还遇到哪些情况导致主从复制中断的情况呢,欢迎留言区讨论~~~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-04-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据库干货铺 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档