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,业务秒级恢复。
相关推荐
紫金桥软件3 小时前
【紫金桥跨平台实时数据库】的技术架构与工程实践
数据库·架构·自动化·跨平台
逍遥德3 小时前
如何学编程之理论篇.03.如何做数据库表结构设计?
开发语言·数据库·性能优化·代码规范·代码复审
Hello eveybody3 小时前
如何将十进制转为二进制、八进制、十六进制?
前端·javascript·数据库
a285283 小时前
最新SQL Server 2022保姆级安装教程【附安装包】
数据库·性能优化
小刘的大模型笔记3 小时前
向量数据库深度剖析:核心优劣势 + 适用场景,避开 RAG 落地的选型坑
数据库·人工智能·深度学习·机器学习
w***29853 小时前
开放自己本机的mysql允许别人连接
数据库·mysql·adb
invicinble4 小时前
对于梳理mysql和jdbc,以及hikiria三者依赖的关系
数据库·mysql
skywalk81634 小时前
DBAASP‌(Database of Antimicrobial Activity and Structure of Peptides) 怎么下载数据集
数据库
knighthood20014 小时前
PCL1.14.0+VTK9.3.0+Qt5.15.2实现加载点云
开发语言·数据库·qt