1. 问题背景与现象描述
最近在维护一个MySQL级联复制环境时,遇到了一个典型的同步异常问题。环境拓扑是这样的:旧集群主库(Server A)→ 新集群主库(Server B)→ 新集群从库(Server C)。最初搭建时一切正常,但运行15天后发现,Server B能正常从Server A同步数据,而Server C却无法从Server B同步任何更新。
通过监控binlog位置发现:
- 在Server A执行写操作后,Server A和Server B的binlog位置都会变化
- Server C的binlog位置始终不变
- 检查show slave status显示没有报错信息
- 复制线程状态显示为正常运行
这种"静默失败"最让人头疼——没有错误日志,复制状态显示正常,但数据就是不同步。作为DBA,这种问题往往需要更深入的排查。
2. 关键参数排查过程
2.1 基础配置检查
首先确认了基础复制配置:
-- 在所有节点执行 SHOW VARIABLES LIKE 'log_bin'; -- 均为ON SHOW VARIABLES LIKE 'log_slave_updates'; -- 均为ON SHOW VARIABLES LIKE 'server_id'; -- 这里发现了异常2.2 server_id冲突验证
通过对比三台服务器的my.cnf配置,发现:
- Server A的server_id=1
- Server B的server_id=2
- Server C的server_id=1
这就形成了Server A和Server C的server_id冲突。但奇怪的是,最初搭建复制时并没有报错,这引出了级联复制的一个特殊行为。
2.3 级联复制的server_id传播机制
在标准主从复制中,server_id冲突会立即报错。但在级联复制中:
- Server B从Server A接收binlog事件时,会记录事件原始server_id(1)
- Server B将这些事件写入自己的binlog时,会保留原始server_id(1)
- Server C接收到这些事件时,发现事件的server_id(1)与自己的server_id(1)相同
- MySQL默认会跳过server_id相同的事件(视为自己产生的事件)
这就是为什么没有报错但数据不同步的原因。可以通过以下命令验证:
SHOW BINLOG EVENTS IN 'mysql-bin.000001' LIMIT 10;3. 问题重现与验证
为了确认这个结论,我在测试环境搭建了相同的拓扑:
准备三台MySQL实例:
- 主库:server_id=1
- 级联主库:server_id=2
- 从库:server_id=1
建立级联复制关系后,在主库创建测试数据:
CREATE DATABASE test_cascade; USE test_cascade; CREATE TABLE t(id INT PRIMARY KEY); INSERT INTO t VALUES(1);- 观察数据同步情况:
- 级联主库有数据
- 从库没有数据
- 查看从库的relay log:
会发现事件被标记为"skipped"SHOW RELAYLOG EVENTS IN 'relay-bin.000001';
4. 解决方案与实施步骤
4.1 紧急处理方案
由于生产环境已经运行15天,而binlog只保留14天,我们采取以下步骤:
- 停止所有写入操作
- 修改Server C的server_id为3并重启
- 在Server B上执行:
STOP SLAVE; RESET SLAVE ALL; CHANGE MASTER TO ...; -- 重新配置复制 START SLAVE; - 重新搭建Server C的复制关系
4.2 长期解决方案
建立server_id分配规范:
- 使用IP地址最后一段+固定偏移量
- 或者使用自动化工具统一分配
在配置模板中加入检查:
[mysqld] server-id = {{ unique_id }}增加监控项:
- 检查集群内server_id唯一性
- 监控级联复制的延迟
5. 经验总结与最佳实践
5.1 级联复制的注意事项
server_id必须全局唯一:
- 不仅是直接主从之间
- 整个复制拓扑中的所有节点都必须唯一
其他相关参数:
log_bin = ON log_slave_updates = ON sync_binlog = 1 gtid_mode = ON enforce_gtid_consistency = ON建议使用GTID模式:
CHANGE MASTER TO MASTER_AUTO_POSITION = 1;
5.2 排查复制问题的通用流程
检查基本复制状态:
SHOW SLAVE STATUS\G验证网络连通性:
telnet master_ip 3306检查权限:
SHOW GRANTS FOR 'repl'@'%';验证binlog配置:
SHOW VARIABLES LIKE '%bin%';检查server_id唯一性
6. 生产环境建议
尽量避免使用级联复制:
- 考虑使用中间件实现读写分离
- 或者使用多源复制
如果必须使用级联复制:
- 实现自动化部署检查server_id
- 增加定期健康检查
- 使用监控工具如Prometheus+Granfa监控复制状态
重要配置检查清单:
- server_id唯一性
- binlog格式一致(ROW格式推荐)
- 时区设置一致
- 字符集设置一致
这个案例告诉我们,MySQL复制问题有时表现得很隐蔽。作为DBA,不仅要了解表面配置,还需要深入理解复制机制的工作原理。每次变更前做好检查清单,才能避免这类"静默"故障的发生。