GreatSQL复制中断问题分析与解决方案

GreatSQL复制中断问题分析与解决方案
1. 问题现象与背景分析最近在排查一个GreatSQL异步复制环境的问题时遇到了一个典型的IO线程中断案例。主从复制环境运行一段时间后从库的IO线程突然停止工作错误日志中出现了这样的报错2026-02-16T12:36:40.08662008:00 12452 [ERROR] [MY-010557] [Repl] Error reading packet from server for channel :Cannot replicate because the master purged required binary logs. Replicate the missing transactions from elsewhere, or provision a new slave from backup. Consider increasing the masters binary log expiration period. The GTID set sent by the slave is 8451fc4d-dlae-1lec-b273-525400fdb1cb:1-424857633, 8451fc4d-d1ae-11ec-b2bf-5254002b8928:1-19789717:19789719-20046740, 8653ccd7-d1ae-11ec-a24c-525400791c4c:1-5, and the missing transaction is 8451fc4d-d1ae-11ec-b2bf-5254002b8928:19789718 (server errno1236)这个错误信息明确告诉我们主库已经清除了从库需要的binlog文件导致复制中断。表面上看这似乎是个常见的binlog过期问题但深入分析后发现真正的罪魁祸首是一个不当的参数配置——slave_skip_errorsALL。2. 错误日志深度解析2.1 GTID集合分析从错误日志中提取的关键GTID信息如下GTID set sent by the slave: 8451fc4d-dlae-1lec-b273-525400fdb1cb:1-424857633, 8451fc4d-d1ae-11ec-b2bf-5254002b8928:1-19789717:19789719-20046740, 8653ccd7-d1ae-11ec-a24c-525400791c4c:1-5 Missing transaction: 8451fc4d-d1ae-11ec-b2bf-5254002b8928:19789718这个GTID集合显示了一个明显的空洞——事务19789718缺失了。正常情况下GTID应该是连续的这种间断说明从库在执行复制时跳过了一个事务。2.2 参数配置检查检查从库的关键参数配置发现slave_skip_errors ALL binlog_expire_logs_seconds 604800 # 7天slave_skip_errorsALL意味着从库会忽略所有复制错误继续执行后续事务。这个配置在生产环境中极其危险它会掩盖数据不一致的问题。3. 问题复现实验为了验证这个问题的成因我设计了两组对比实验。3.1 实验1slave_skip_errorsALL实验步骤搭建异步复制环境从库配置slave_skip_errorsALL在主库和从库上对同一行数据执行冲突操作观察从库的行为关键操作-- 从库执行不提交 BEGIN; UPDATE test1 SET cdddddddddddd WHERE id2; -- 主库执行 UPDATE test1 SET ceeeeeeeee WHERE id2;实验结果从库的GTID集合出现了空洞c12440a7-12c1-11f1-95ad-00163e379f11:1-43804:43806-84055缺少了事务43805但复制进程仍然显示正常Slave_IO_Running: Yes, Slave_SQL_Running: Yes。3.2 实验2slave_skip_errorsOFF实验步骤相同环境但设置slave_skip_errorsOFF执行相同的冲突操作实验结果从库的SQL线程立即停止并报错Last_SQL_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction c12440a7-12c1-11f1-95ad-00163e379f11:109034 at master log binlog.000004, end_log_pos 43620845; Lock wait timeout exceeded; try restarting transaction这种情况下管理员可以及时发现并处理数据冲突问题。4. 问题根源与解决方案4.1 根本原因分析问题的根本原因在于不当的参数组合slave_skip_errorsALL导致从库静默跳过错误事务跳过的那个事务(19789718)后来被主库的binlog清理机制清除当从库需要重新连接主库时会发送自己的GTID集合主库发现从库缺少的事务19789718对应的binlog已经不存在4.2 正确的参数配置建议对于生产环境的GreatSQL复制建议采用以下配置slave_skip_errors OFF # 默认值不要修改 binlog_expire_logs_seconds 1209600 # 14天根据业务需求调整 slave_parallel_workers 8-16 # 根据服务器CPU核心数调整 slave_preserve_commit_order ON # 保证并行复制的事务提交顺序4.3 问题修复方案如果已经遇到IO线程中断的问题可以采取以下步骤修复检查GTID差异-- 在主库执行 SELECT global.gtid_executed; -- 在从库执行 SELECT global.gtid_executed;重建缺失的事务如果缺失的事务不多可以手动在主库重新执行这些事务使用pt-table-sync等工具修复数据不一致重建复制-- 在从库执行 STOP SLAVE; RESET SLAVE ALL; CHANGE MASTER TO ... # 重新配置复制 START SLAVE;5. 生产环境最佳实践5.1 监控建议建立完善的监控体系特别关注以下指标主从延迟时间(Seconds_Behind_Master)复制线程状态(Slave_IO_Running, Slave_SQL_Running)GTID集合差异binlog文件保留时间5.2 定期检查清单每周应执行以下检查-- 检查复制状态 SHOW SLAVE STATUS\G -- 检查GTID执行情况 SELECT global.gtid_executed; -- 检查跳过的事务数量 SHOW STATUS LIKE slave_skipped_errors;5.3 高可用方案建议对于关键业务系统建议考虑使用GreatSQL的MGR架构替代传统复制配置延迟从库(设置CHANGE MASTER TO MASTER_DELAY)实现自动故障转移机制6. 经验总结与教训在这个案例中我们学到了几个重要的经验不要随意修改slave_skip_errors参数这个参数就像数据库的止痛药虽然能暂时缓解症状但会掩盖真正的疾病。生产环境应该始终保持默认值OFF。GTID空洞是危险的信号任何GTID不连续的情况都应该立即调查而不是等待问题爆发。binlog保留时间需要合理设置不仅要考虑磁盘空间还要考虑可能的复制延迟和故障恢复时间。并行复制需要谨慎配置虽然并行复制能提高性能但也增加了数据不一致的风险必须配合slave_preserve_commit_orderON使用。在实际运维中我建议将slave_skip_errors的配置纳入变更管理流程任何修改都需要经过严格的评审。同时对于跳过的错误应该建立即时告警机制而不是等到IO线程中断才发现问题。