连载中 12/22

复制延迟治理:并行复制、半同步与监控兜底

2026-05-08 · 2941 阅读 · 0 评论 · 0 赞

换完头像,刷出来还是旧的

老王上线读写分离第一天就遇到灵异现象:用户改完头像刷新页面,头像又变回旧的——写走主库,紧接着的读被路由到还没同步完的从库。复制延迟不是偶发故障,是主从架构的物理属性,这篇讲它的机理与全套治理手段。

延迟的账:拉得快,回放慢

从库回放分两步:IO 线程把主库 binlog 拉回本地中继日志(relay log),SQL 线程把 relay log 重放。IO 阶段是纯网络拷贝,很快;瓶颈几乎都在回放——老版本 SQL 线程只有一条,主库 16 核并发写入,从库单线程排队回放,天生追不平。大事务、大表上无主键的行变更(row 格式要逐行全表定位)更是雪上加霜。

所以治理三板斧:让回放并行起来、让提交更保险、让监控说真话。

第一板斧:并行复制

8.0 默认的 logical clock 方案:主库上同一批提交(同一 binlog group)的事务没有锁冲突,从库允许它们并行回放。从库侧三个参数:

# 从库 my.cnf
replica_parallel_workers = 8          # 回放线程数,按核数给
replica_parallel_type = LOGICAL_CLOCK # 8.0 默认,按事务提交组并行
replica_preserve_commit_order = ON    # 保证回放提交顺序与主库一致

想再上一个台阶,主库开 binlog_transaction_dependency_tracking = WRITESET(基于行哈希判依赖,并行度更高,8.0.35 起该参数进入弃用流程,新版本行为默认优化,升级时留意)。

第二板斧:半同步复制

普通异步复制有个残酷设定:主库提交不等从库确认,主库宕机时最新数据可能还没传出去——故障切换会丢已提交事务。半同步(semi-sync)的折中:主库提交后阻塞,等至少一个从库把 binlog 收进 relay log 的 ACK 再返回成功;超时(rpl_semi_sync 复制插件默认 10 秒)自动降级为异步,不因从库挂掉而拖死主库。

  • 注意边界:半同步只保证 binlog 到达从库,不保证已回放——防丢数据,不防读延迟;
  • 8.0.26 起插件重构为源/副本(source/replica)组件,参数前缀从 rpl_semi_sync_master 变为 rpl_semi_sync_source;
  • 对数据不丢有硬要求的交易库建议开;读多写少的内容库可以不开。

第三板斧:让监控说真话

最常用的 Seconds_Behind_Source 有个致命盲区:主库没写入时它恒为 0——链路可能早就断了,只是没活干。更靠谱的是 pt-heartbeat:主库周期性往心跳表写时间戳,从库读出时间差就是真实延迟,不依赖复制线程自报。配合 SHOW REPLICA STATUS 的 IO/SQL 双线程状态和错误日志,告警才算闭环。

应用层四条自救

  • 写后读主:改完头像后的那次读强制走主库(按用户维度短暂粘住主库即可);
  • 关键读走主:支付结果、余额等强一致读不选从库;
  • 大事务拆小:一次性更新百万行的批处理拆成小批,别让从库回放卡一分钟;
  • 表必须有主键:row 复制下无主键表是回放毒药(第 17 篇表设计再强调一次)。

延迟治理的工程面到这就齐了,但「主库挂了谁接棒」这个终极问题还没答案——读写分离的路由方案、MHA 与 MGR 的高可用选型,下一篇见。

咖啡凉了,记得趁热喝。

503

10 年全栈工程师 · 503咖啡馆主理人

#MySQL#复制延迟#并行复制#半同步#pt-heartbeat

评论 (0)

相关推荐

连载中 12/20

排查四件套:jstack、jmap、jstat、jcmd 的实战分工

jstack 看线程在干什么,jmap 看堆里装了什么,jstat 看运行时在变什么,jcmd 是统一入口。四把刀各管一段,配合着用没有查不动的现场。

#jstack#jmap#jstat#jcmd#排查工具
2026-09-16 · 5 阅读 · 0 评论 · 0 赞
连载中 11/20

GC 日志:把回收过程翻译成人话

一行 GC 日志里塞着七种信息:谁触发的、收了哪、停了多久、活了哪些。加上 -Xlog 配置,再加上日志分析工具,GC 不再是只能盯监控曲线的黑盒。

#GC日志#Xlog#日志分析#GC监控#Full GC排查
2026-09-16 · 13 阅读 · 0 评论 · 0 赞
连载中 10/20

ZGC:亚毫秒停顿是怎么炼成的

百 G 大堆停顿不到一毫秒,靠的是把搬家全部挪到并发阶段——着色指针让引用自带状态,读屏障让搬运中的对象依然可访问。代价是吞吐与内存,收益是停顿与堆大小解耦。

#ZGC#着色指针#读屏障#亚毫秒停顿#分代ZGC
2026-09-15 · 8 阅读 · 0 评论 · 0 赞