1. 问题背景

在 MySQL 主从架构中,从库(Slave)的数据与主库(Master)出现严重不一致(Data Drift),导致复制线程报错停止。

典型报错信息:

Could not execute Update_rows event on table ...; 
Can't find record in '...', Error_code: 1032; 
handler error HA_ERR_END_OF_FILE;

这表示主库要更新某行数据,但从库找不到该行,说明从库已经丢失了数据或数据严重过时。

环境信息:

  • 版本:MySQL 8.0
  • 架构:一主一从
  • 复制方式:传统 Binlog 文件名 + 位置(非 GTID 模式)
  • 操作系统:Linux

2. 为什么选择“重做从库”?

面对主从数据不一致,通常有三种解法:

  1. 跳过错误 (sql_slave_skip_counter):仅适用于临时跳过少量错误,无法解决数据丢失问题,会导致数据差异越来越大。
  2. 在线修复 (pt-table-checksum / pt-table-sync):适用于数据差异较小、业务允许一定负载的情况。当差异巨大时,修复耗时极长且影响性能。
  3. 重做从库 (Rebuild Slave):最彻底、最可靠的方案。通过全量备份覆盖,保证从库与主库绝对一致。

在“大量数据不一致”的场景下,重做从库是最佳选择。

3. 修复实战步骤

第一步:在主库进行全量备份

我们需要一个包含“同步点信息”的全量备份。使用 mysqldump 是最通用的方法(适合数据量 < 50GB)。

在主库执行:

# 创建备份目录
mkdir -p /tmp/backup

# 导出全量数据
# --master-data=2:关键参数!会在备份文件中记录当前的 Binlog File 和 Position
# --single-transaction:保证 InnoDB 表备份期间不锁表
mysqldump -u root -p \
  --all-databases \
  --single-transaction \
  --master-data=2 \
  --routines --triggers --events \
  --hex-blob \
  > /tmp/backup/full_dump.sql

第二步:获取主从同步点

备份完成后,我们需要从备份文件的头部提取出主库刚才的 Binlog 位置。

在主库执行:

head -n 50 /tmp/backup/full_dump.sql | grep "CHANGE MASTER TO"

记录输出结果(示例):

MASTER_LOG_FILE=‘binlog.000102’, MASTER_LOG_POS=387108738

第三步:将备份传输到从库

使用 scp 命令将 SQL 文件发送到从库服务器。

在主库执行:

scp /tmp/backup/full_dump.sql root@<从库IP>:/tmp/

第四步:重置从库并导入数据

警告:此操作会清空从库现有数据。

1. 登录从库 MySQL,停止并重置复制:

STOP SLAVE;
RESET SLAVE ALL;
-- 建议开启只读,防止误写入
SET GLOBAL super_read_only = ON;

2. 在从库 Shell 导入数据:

# 如果开启了 super_read_only,导入前可能需要临时关闭,导入后再开启
mysql -u root -p < /tmp/full_dump.sql

第五步:重新配置主从同步

使用第二步获取的 FilePosition,以及专用的复制账号(建议新建)。

在从库 MySQL 执行:

-- 配置主库连接
CHANGE MASTER TO 
  MASTER_HOST='<主库IP>',
  MASTER_PORT=3306,
  MASTER_USER='repl_user',              -- 复制账号
  MASTER_PASSWORD='StrongPassword123!', -- 复制密码
  MASTER_LOG_FILE='binlog.000102',      -- 填入第二步获取的文件名
  MASTER_LOG_POS=387108738;             -- 填入第二步获取的位置

-- 启动复制
START SLAVE;

第六步:验证同步状态

SHOW SLAVE STATUS\G

检查重点:

  • Slave_IO_Running: Yes
  • Slave_SQL_Running: Yes
  • Last_IO_Error / Last_SQL_Error: 为空
  • Seconds_Behind_Master: 0(表示已追平)

4. 避坑与防范指南

  1. 账号权限:如果忘记复制账号密码,不要犹豫,直接在主库新建一个(CREATE USER ... GRANT REPLICATION SLAVE ...)。
  2. 只读模式:从库必须永久开启 read_onlysuper_read_only,防止业务误写导致再次不同步。
  3. GTID 模式:如果条件允许,建议未来升级为 GTID 模式(gtid_mode=ON),它能自动定位同步点,运维更简单且抗风险能力更强。
  4. 定期巡检:定期运行 SHOW SLAVE STATUS 监控主从状态,或使用 Prometheus + Grafana 进行监控报警。
Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐