根本原因是AUTO_INCREMENT计数器未对齐,需停写、校准MAX(id)+1、配对设置auto_increment_increment与offset;SHOW SLAVE STATUS的Exec_Master_Log_Pos仅表示binlog位置追平,不反映自增计数器状态。

主从复制中断时出现 Duplicate entry 错误,基本就是 AUTO_INCREMENT 没对齐
不是同步线程卡住了,也不是网络延迟导致的;根本原因是新插入的记录主键值在从库上已存在。MySQL 的 AUTO_INCREMENT 计数器是本地维护的,不随 binlog 同步——主库生成了 ID=1001,从库回放这条语句时,自己也准备生成下一个 ID,但它“以为”下一个是 1001,而该值早已被之前误写、迁移或切换残留的数据占用了。
SHOW SLAVE STATUS 显示已追平,但 Exec_Master_Log_Pos 不代表自增值已同步
Exec_Master_Log_Pos 只表示从库 SQL 线程已执行到主库 binlog 的哪个位置,完全不反映 AUTO_INCREMENT 当前值是否与主库一致。MySQL 启动或重启时,InnoDB 表的 AUTO_INCREMENT 值由 SELECT MAX(id) + 1 初始化(5.7 及之前),8.0 默认行为类似,且不读取 binlog 中的历史分配记录。所以即使复制位置追平了,两台机器的计数器仍可能差几百甚至几万。
auto_increment_offset 单独设置无效,必须和 auto_increment_increment 配对生效
只在 my.cnf 里加 auto_increment_offset = 2 是没用的。因为 offset 只决定第一个自增值,后续仍按默认步长 +1 递增。真正起作用的是二者的组合逻辑:
- 双节点场景:统一设
auto_increment_increment = 2,主库auto_increment_offset = 1(生成 1,3,5…),从库auto_increment_offset = 2(生成 2,4,6…) - offset 必须在 1 到 increment 之间,否则 MySQL 启动时静默重置为 1
- 配置必须写进
my.cnf并重启,SET GLOBAL对已有复制线程无效
主从切换后不校准 AUTO_INCREMENT,第一笔插入就报错
从库升主后,它的 AUTO_INCREMENT 值仍是旧状态(比如刚从主库同步来,最大 ID 是 999,计数器设为 1000),但原主库(现从库)可能已写到 1050。此时新主库插入下一条无指定 ID 的记录,会尝试用 1000,而该值在原主库上已被占用,同步过来就触发 Duplicate entry '1000' for key 'PRIMARY'。
安装、修复、更新或打包一个基于 Python 和 PyMySQL 实现的 Windows `mysql` 命令。适用于用户希望在 PowerShell/CMD 中输入 `mysql` 时重定向到 Python 实现、需要交互式输入 MySQL 连接信息、需要同步到当前用户本地 bin 目录,或需要将该能力封装成可公开复用的 Codex skill。
必须立刻执行:
- 暂停所有写入(尤其防应用双写)
- 查所有节点该表的
MAX(id),取最大值 +1 - 在新主库上执行
ALTER TABLE tbl_name AUTO_INCREMENT = N - 用
SHOW CREATE TABLE tbl_name确认输出中AUTO_INCREMENT已更新
最容易被忽略的是:只查本机 MAX(id),没比对其他节点;或者改了配置但没重启,复制线程还在用旧步长;还有历史跨库写入数据没清理,校准后照样撞。










