基于本文回答

播面 播面

刷题像听歌,多听自然懂
0
评论

讲讲MySQL 主从复制的原理和基本流程

知识点图片

MySQL 的主从复制(Master-Slave Replication)是 MySQL 中最核心的高可用和扩展性技术之一。它的主要作用是实现数据备份、读写分离、高可用故障转移

下面为你详细拆解 MySQL 主从复制的原理和基本流程。


一、 核心原理

MySQL 主从复制的核心原理可以用一句话概括:基于二进制日志(Binlog)的事件重放。

主库(Master)将数据库所有的修改操作(如 INSERT、UPDATE、DELETE 以及 DDL 语句)记录到 Binlog 中。从库(Slave)通过请求获取主库的 Binlog,并在本地重新执行(重放)这些日志中的操作,从而保持与主库数据的一致。

在这个过程中,有 三个核心线程 发挥着关键作用:

  1. Binlog Dump 线程(位于主库):负责读取主库的 Binlog 并发送给从库。
  2. I/O 线程(位于从库):负责连接主库,接收 Binlog 数据,并将其写入从库本地的中继日志(Relay Log)。
  3. SQL 线程(位于从库):负责读取 Relay Log 中的数据,并在从库本地执行这些 SQL 或数据修改事件。

二、 基本工作流程

主从复制的完整流程可以分为以下几个步骤:

plaintext
[客户端] ---> (1.写入数据) ---> [主库 Master] ---> (2.记录Binlog) ---> [本地 Binlog 文件]
                                 | (3.唤醒/推送)
                                 v
                        [Binlog Dump 线程]
                                 | (4.网络传输)
                                 v
                            [I/O 线程] ---> (5.写入) ---> [中继日志 Relay Log]
                            (从库 Slave)                        | (6.读取)
                                                               v
                                                          [SQL 线程] ---> (7.执行重放) ---> [从库本地数据]

详细步骤说明:

  1. 主库执行并记录: 客户端向主库发起写操作(如执行一个事务),主库执行完毕后,在返回给客户端成功信息之前,会将该操作按顺序写入到本地的 Binlog 中。
  2. 从库建立连接: 从库启动主从复制(执行 START SLAVE)时,会创建一个 I/O 线程,该线程通过指定的账号密码连上主库,并请求从指定 Binlog 文件的指定位置(Position)开始复制。
  3. 主库发送日志: 主库接收到从库的连接请求后,会为该从库创建一个 Binlog Dump 线程。该线程会读取 Binlog,并将其发送给从库的 I/O 线程。如果主库有新的写入,Dump 线程会被唤醒并继续发送。
  4. 从库接收并写入中继日志: 从库的 I/O 线程 接收到主库发来的日志数据后,将其保存在从库本地的 中继日志(Relay Log) 中,并记录当前读取到的主库 Binlog 的文件名和位置。
  5. 从库应用重放: 从库的 SQL 线程 持续监控 Relay Log 的变化。一旦发现有新的事件产生,SQL 线程就会读取这些事件,并在从库的数据库中重放(执行),从而实现主从数据一致。

三、 Binlog 的三种格式

复制的准确性很大程度上取决于 Binlog 记录数据的格式:

  1. Statement(基于语句): 记录的是执行的 SQL 语句。
    • 优点: 日志量小,节省 IO 和网络带宽。
    • 缺点: 遇到非确定性函数(如 NOW(), UUID())时,主从执行结果会不一致。
  2. Row(基于行): 不记录 SQL 语句上下文,只记录哪条数据被修改成了什么样。
    • 优点: 非常安全可靠,能保证数据绝对一致。
    • 缺点: 遇到批量更新(如 UPDATE table SET status = 1)时,日志量会暴增(如果表有100万行,就会记录100万条修改)。
  3. Mixed(混合模式): MySQL 自己判断,一般的语句用 Statement,遇到可能引起主从不一致的语句自动切换为 Row。
    • (目前主流企业生产环境中,通常强制使用 Row 模式,以保证数据的绝对安全,结合 GTID 使用更佳)

四、 主从复制的同步模式

默认情况下,MySQL 的主从复制是异步的,这可能导致数据丢失。为了解决这个问题,MySQL 提供了不同的同步模式:

  1. 异步复制(Asynchronous replication - 默认):
    • 主库把事务写入 Binlog 后,直接返回给客户端成功,不管从库是否收到了日志。
    • 风险: 如果主库突然宕机,而部分 Binlog 还没来得及传给从库,此时切换主从会导致数据丢失
  2. 半同步复制(Semi-synchronous replication):
    • 主库执行完事务后,不立刻返回给客户端,而是等待至少一个从库收到 Binlog 并写入 Relay Log 后,再给客户端返回成功。
    • 优点: 兼顾了性能与数据安全性。
  3. 全同步复制 / 组复制(Group Replication - MGR):
    • 所有节点之间进行协商,大多数节点成功执行事务才算成功。数据安全性最高,但性能损耗最大。

五、 常见面试/实战问题:主从延迟

问题现象: 主库写入数据后,从库需要过一段时间(几秒甚至几小时)才能查到该数据。

产生原因:

  1. 单线程瓶颈: 在 MySQL 5.6 之前,从库的 SQL 线程是单线程的。如果主库并发写入极高,从库单线程回放必然跟不上主库多线程写入的速度。
  2. 大事务/大表 DDL: 主库执行了一个大事务(如一次性 delete 100万条数据)或给大表加索引,从库也需要执行同样的时间,导致阻塞。
  3. 网络延迟或从库硬件差: 从库机器性能不如主库,或者跨机房网络慢。

解决策略:

  1. 开启 MTS (Multi-Threaded Slave) 多线程复制(MySQL 5.7+ 默认支持基于 Logical Clock 的并行复制)。
  2. 业务层面打散大事务,避免长事务。
  3. 读写分离的业务中,对一致性要求极高的读请求,强制路由到主库查询。
  4. 确保主从机器硬件配置一致。
00:00
00:00