Slave 的 SQL 线程为什么追不上 Master?

你的网站只有一台数据库。

双 11 当天,流量暴涨 10 倍。所有的查询(SELECT)和写入(INSERT/UPDATE)都挤在这一台机器上。
结果: CPU 100%,磁盘 I/O 打满,数据库卡死,网站 502 Bad Gateway。
更惨的场景:

运维误删了数据库文件,或者服务器硬盘物理损坏。
结果: 数据全丢,公司原地解散。
救世主:
主从复制

让一台机器(Master)专门负责写,几台机器(Slave)专门负责读。

哪怕 Master 挂了,Slave 也能立刻顶上去,数据一份都不会少。


1. 核心原理:三个线程的"传话游戏"

主从复制的本质,就是把主库发生的数据变更,在从库上重放 (Replay) 一遍。

这个过程涉及 3 个核心线程2 个关键日志

第一步:Master 记录"日记" (Binlog)
  • 当 Master 执行了写操作(INSERT/UPDATE/DELETE)时,它不仅会修改内存数据,还会把这次操作记录到 Binlog (Binary Log) 中。
  • Binlog 是逻辑日志,记录的是"把 ID=1 的名字改成 Alice"这样的事件。
第二步:传输 (IO Thread & Dump Thread)
  • Slave 发起请求: Slave 启动一个 I/O 线程 ,连上 Master,说:"请把 Binlog 发给我,我上次读到了 mysql-bin.000001 的位置 1024。"
  • Master 发送数据: Master 启动一个 Binlog Dump 线程,把 Binlog 内容推送给 Slave。
  • Slave 接收落盘: Slave 的 I/O 线程收到数据后,并不直接执行,而是先把它写入自己本地的中转站 ------ Relay Log (中继日志)
第三步:重放 (SQL Thread)
  • Slave 启动一个 SQL 线程
  • 它读取 Relay Log 中的事件,将其转换成 SQL 语句,在 Slave 自己的数据库里再执行一遍。
  • 结果: Slave 的数据就和 Master 一模一样了。

2. 三种复制模式:速度与安全的博弈

MySQL 提供了不同的复制策略,以应对不同的业务需求。

模式 A:异步复制 (Asynchronous Replication) ------ 默认
  • 机制: Master 写完 Binlog,不等 Slave 确认,直接给客户端返回"成功"。
  • 优点: 性能最高。Master 不需要等待网络延迟。
  • 缺点: 数据不安全。如果 Master 刚写完 Binlog 就宕机了,而 Binlog 还没传给 Slave,这部分数据就永久丢失了。
模式 B:半同步复制 (Semi-Synchronous Replication)
  • 机制: Master 写完 Binlog 后,必须等待至少一个 Slave 收到 Binlog 并写入 Relay Log(返回 ACK),才给客户端返回"成功"。
  • 优点: 数据基本安全(除非 Master 和那个 Slave 同时挂)。
  • 缺点: 性能有损耗(也就是多了一个 RTT 网络往返时间)。如果超时(默认 10秒),它会退化成异步复制。
模式 C:组复制 (MGR - MySQL Group Replication)
  • 机制: 基于 Paxos 协议。多个节点组成一个组,写入操作必须经过大多数节点同意才能提交。
  • 优点: 强一致性,自动故障转移,真正的多主架构。
  • 缺点: 配置复杂,对网络要求极高。

3. 实战痛点:主从延迟 (Replication Lag)

这是主从架构最大的敌人。

现象:

用户刚注册成功(写入 Master),立马跳到登录页(读取 Slave),结果提示"账号不存在"。

原因:

  1. 单线程瓶颈: 在 MySQL 5.6 之前,Slave 的 SQL 线程是单线程的。如果 Master 并发很高(比如 1000 TPS),Slave 只能一个个排队执行,根本追不上。
  2. 大事务: Master 执行了一个 DELETE 语句删了 100 万行数据,耗时 10 秒。Slave 重放这个事务也要 10 秒,这就导致了 10 秒的延迟。
  3. 网络延迟: 跨机房同步。

解决方案:

  1. 并行复制 (MTS - Multi-Threaded Slave):
  • MySQL 5.7+ 引入了基于逻辑时钟 (Logical Clock) 的并行复制。
  • 原理: 如果两个事务在 Master 上是并行提交的(说明它们没有锁冲突),那么在 Slave 上也可以并行重放。
  • 这让 Slave 的回放速度提升了 10 倍以上。
  1. 读写分离策略优化:
  • 关键业务(如支付、注册后登录)强制读主库
  • 非关键业务(如查看商品列表)读从库

4. 架构进阶:GTID (Global Transaction ID)

在老版本的 MySQL 中,主从切换是非常痛苦的。你需要手动找 Binlog 文件名和 Position 位置(如 mysql-bin.00005, pos=890)。一旦找错,数据就乱了。

GTID (全局事务 ID) 彻底解决了这个问题。

  • 定义: 每个事务都有一个全局唯一的 ID(如 UUID:TransactionId)。
  • 机制: Slave 不再告诉 Master "我读到了哪个文件的哪一行",而是直接说 "我已经执行了 1-100 号事务,请把 101 号之后的发给我"
  • 收益: 极大地简化了故障切换(Failover)和搭建从库的流程。

5. 总结

主从复制 是高可用架构的基石。

  • 它是备份: 每一台 Slave 都是一份完整的数据副本。
  • 它是性能: 通过读写分离,让 1 台 Master 扛写,N 台 Slave 扛读,吞吐量线性增长。
  • 它是容灾: Master 挂了,通过 HA 工具(如 Orchestrator, MHA)把 Slave 提升为新 Master,业务秒级恢复。
相关推荐
IvorySQL1 天前
PostgreSQL 技术日报 (3月6日)|为什么 Ctrl-C 在 psql 里让人不安?
数据库·postgresql·开源
NineData1 天前
数据库管理工具NineData,一年进化成为数万+开发者的首选数据库工具?
运维·数据结构·数据库
IvorySQL2 天前
PostgreSQL 技术日报 (3月5日)|规划器控制力升级,内核能力再进阶
数据库·postgresql·开源
数据组小组2 天前
免费数据库管理工具深度横评:NineData 社区版、Bytebase 社区版、Archery,2026 年开发者该选哪个?
数据库·测试·数据库管理工具·数据复制·迁移工具·ninedata社区版·naivicat平替
爱可生开源社区2 天前
MiniMax M2.5 的 SQL 能力令人惊艳!
sql·llm
Nyarlathotep01132 天前
事务隔离级别
sql·mysql
悟空聊架构2 天前
基于KaiwuDB在游乐场“刷卡+投币”双模消费系统中的落地实践
数据库·后端·架构
IvorySQL2 天前
PostgreSQL 技术日报 (3月4日)|硬核干货 + 内核暗流一网打尽
数据库·postgresql·开源
Nyarlathotep01133 天前
SQL的事务控制
sql·mysql