log_slave_updates=on是级联复制的硬性前提,它使从库b将主库a的中继日志事件写入自身二进制日志,从而让下游从库c可从中拉取并同步;若未开启,c无法获取任何变更,即使b已完整同步a。

log_slave_updates=ON 是级联复制的硬性门槛
没开这个参数,B 节点再怎么同步 A,C 也永远收不到 A 的变更。它不是“可选优化”,而是链路成立的前提——因为 MySQL 默认只把 relay log 重放进本地数据,不写入自己的 binlog,C 就没有东西可拉。
常见误判:C 上 SHOW REPLICA STATUS\G 显示 Slave_IO_Running: Yes,但 Retrieved_Gtid_Set 为空或 Relay_Master_Log_File 指向一个空 binlog 文件,基本就是 B 没开 log_slave_updates。
- 必须写进配置文件(如
/etc/my.cnf的[mysqld]段),不能只靠SET GLOBAL log_slave_updates = ON临时开启——重启后失效 - 该参数仅对启用了
relay_log的实例生效(即已配置为 slave 角色的节点) - 开启后,B 的 binlog 里会出现 server_id 来自 A 的 event,这是 C 能正确识别源头事务的关键
中间节点 B 必须同时开启 log_bin 和唯一 server_id
B 不是“纯从库”,它是 A 的 slave、C 的 master,必须能生成并提供 binlog。如果只开 log_slave_updates 却没开 log_bin,C 执行 CHANGE REPLICATION SOURCE TO 时会直接报错:ERROR 3021 (HY000): This server is not configured as a replication source。
-
log_bin必须在配置文件中显式设置(如log_bin = mysql-bin),无法动态启用 -
server_id必须全局唯一:A、B、C 三者不能重复,且不能为 0 或 1(某些旧版本有兼容限制) - 建议搭配
binlog_format = ROW,避免语句级复制在 B 上因函数/临时表等导致执行失败,中断整条链路
下游 C 连接的是 B,不是 A —— 别配错 SOURCE_HOST
C 的复制源必须指向 B 的 IP 和端口,不是 A。配成 C 直连 A,会导致:GTID 冲突、MASTER_LOG_FILE 位置错乱、甚至主键冲突(尤其在非幂等写入场景)。
实操时容易踩坑的点:
- 用脚本批量初始化从库,却忘了区分层级,统一填了最上层 A 的地址
- B 刚重启,
SHOW MASTER STATUS的Position还是 4(初始值),但 C 用这个位置去连,实际会跳过 B 已应用的 relay event - 确认 B 已稳定同步 A:
Seconds_Behind_Master = 0且Exec_Master_Log_Pos持续前进后再操作 C - C 上执行:
CHANGE REPLICATION SOURCE TO SOURCE_HOST='B的IP', SOURCE_USER='repl', SOURCE_PASSWORD='xxx', SOURCE_LOG_FILE='mysql-bin.000001', SOURCE_LOG_POS=12345(注意是SOURCE_*前缀,MySQL 8.0.23+ 语法)
GTID 模式下,B 的 gtid_purged 必须继承自 A
如果 A/B/C 全开 GTID,B 故障重建后用 mysqldump 恢复,却没保留 gtid_purged,C 启动复制就会卡住:ERROR 1236 (HY000): The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires。
关键动作只有两个:
- B 备份时加
--set-gtid-purged=ON(默认行为),确保 dump 文件开头有SET @@GLOBAL.GTID_PURGED='...' - B 恢复后,先查
SELECT @@gtid_purged;,确认值包含 A 的全部 GTID 范围;若缺失,需手动SET GLOBAL gtid_purged = 'A的gtid_purged值'(仅当gtid_executed为空时允许)
级联复制真正的脆弱点不在配置步骤,而在于 B 成为单点瓶颈后,它的 binlog 写放大、网络抖动、磁盘 IO 延迟都会被逐级传递并放大——监控 Seconds_Behind_Master 在 C 上已经没意义,得盯紧 B 的 Read_Master_Log_Pos 和 Exec_Master_Log_Pos 差值。











