修改 server_id 前必须停掉从库复制,否则主从会报错 1236 或卡在 Waiting for master to send event;需 STOP SLAVE 后修改配置,再用 CHANGE MASTER TO 重设复制坐标并验证状态。

修改 server_id 前必须停掉从库复制
直接改 server_id 并重启 MySQL,主从很可能立刻报错 Got fatal error 1236 或卡在 Waiting for master to send event。因为从库的 Relay_Log_File 和 Master_Log_File 位置信息是和旧 server_id 绑定的,MySQL 不会自动重置复制坐标。
实操建议:
- 先在从库执行
STOP SLAVE;,再改配置 - 改完后用
CHANGE MASTER TO ... MASTER_AUTO_POSITION = 1;(如果启用了 GTID)或显式指定MASTER_LOG_FILE和MASTER_LOG_POS重新拉起复制 - 确认
SHOW SLAVE STATUS\G中Seconds_Behind_Master回归正常,且无IO_Running/SQL_Running为No
server_id 必须是整数,且集群内全局唯一
MySQL 不接受 server_id = 0(5.7+ 会拒绝启动),也不接受字符串、小数或重复值。设成 1 看似省事,但一旦加新从库就必然冲突——主从链、多源复制、MGR 都依赖这个 ID 做事务路由和冲突检测。
推荐做法:
- 用机器 IP 最后一段 + 实例端口组合,比如
192.168.5.12:3307→server_id = 123307 - 避免用纯递增序列(如 1, 2, 3),否则扩容时容易误配
- 检查是否已有其他实例占用了相同
server_id:在所有节点执行SELECT @@server_id;
my.cnf 里改了不生效?检查加载顺序和动态权限
常见错误是改了 /etc/my.cnf 却没生效,或者改了 [mysqld] 段落却写到了 [client] 下。MySQL 启动时只读取 [mysqld] 下的 server_id,且不支持运行时 SET(SET GLOBAL server_id = ... 会报错)。
排查步骤:
- 用
mysqld --verbose --help | grep "Default options"确认实际读取的配置文件路径 - 检查配置文件中是否有多个
[mysqld]段,后出现的会覆盖前一个 - 确认没有被 Docker entrypoint、systemd 环境变量或启动脚本里的
--server-id参数覆盖 - 改完必须
sudo systemctl restart mysqld(或对应服务名),仅 reload 不生效
GTID 模式下改 server_id 的额外约束
启用 gtid_mode = ON 时,MySQL 要求每个实例的 server_uuid 也必须唯一,而 server_uuid 是首次启动时生成并写入 auto.cnf 的。如果只是复制了一份数据目录又改了 server_id,但没删 auto.cnf,两个实例会共用同一个 server_uuid,导致 GTID 复制拒绝连接,错误类似 The slave I/O thread stops because the master has UUIDs which are not in the UUID set of the slave。
安全操作:
- 改
server_id前,先删掉数据目录下的auto.cnf(MySQL 重启时会自动生成新 UUID) - 确保
enforce_gtid_consistency = ON和gtid_mode = ON已正确启用 - 不要跳过 GTID 事务校验(例如用
SET GLOBAL gtid_purged = ...手动注入),除非你完全清楚 binlog 位点与 GTID 集合的映射关系
真正麻烦的不是改 ID 这一行配置,而是它牵扯的复制状态、GTID 集合、日志文件偏移这三者的同步一致性。少一步验证,后面追日志可能花半天。










