更新时间:2022-10-26 GMT+08:00

MySQL主备复制原理简介

RDS for MySQL的默认备库、只读实例、自建从库、DRS链路灾备实例均采用MySQL的Binlog复制技术,也称为MySQL主备复制或主从复制技术。本章节介绍MySQL的主从复制原理。

主备复制流程

  • 主节点(Master)中有数据更新时,会按照Binlog格式,将更新的操作以event形式写入到主节点的Binlog中。event有多种类型:INSERT、DELETE、UPDATE、QUERY等。
  • 从节点(Slave)连接主节点时,有多少个从节点就会创建多少个Binlog dump线程。
  • 当主节点的Binlog发生变化时,Binlog dump线程会通知所有从节点,并将相应Binlog内容推给从节点。
  • 从节点的I/O thread收到Binlog内容后,会将内容写到本地relay log(中继日志)。
  • 从节点的SQL thread会读取I/O thread写入的relay log,并且根据relay log中的event,回放对应的操作(DML、DDL等)。

Seconds_Behind_Master计算方式

Seconds_Behind_Master即主备复制时延,通过show slave status查询获取。Seconds_Behind_Master计算的伪代码实现如下:

if (SQL thread is running) 
//如果SQL线程启动
{
     if (SQL thread processed all the available relay log)
     //IO thread拉取主库Binlog的位置和sql thread应用的relay log相对于主库Binlog的位置相等
     {
         if (IO thread is running)
             //如果IO线程启动,设置延迟为0
             print 0;
         else
             //如果IO线程未启动,设置延迟为null
             print NULL;
     }
     else
         //如果SQL线程没有应用完所有的IO线程写入的event,那么需要计算Seconds_Behind_Master
         按公式计算Seconds_Behind_Master的值;
}  
else
     //如果SQL线程也没有启动,则设置为空值
     print NULL;

上述伪代码中,Seconds_Behind_Master的计算公式为:

Seconds_Behind_Master = time(0) - last_master_timestamp - clock_diff_with_master

相关变量含义如下:
  1. time(0):当前从节点服务器的系统时间。
  2. clock_diff_with_master:从节点的系统时间和主节点服务器系统时间的差值,一般为0。如果主从节点系统时间不一致,那么计算出的从节点复制时延会不准确。
  3. last_master_timestamp:从节点在回放relay log中event过程中计算和更新,该变量在并行复制(MTS)和非并行复制方式下,更新的时机是不同的,默认全部开启并行复制:
    • 并行复制:可以简单理解为,从节点的SQL线程在每个事务执行完成后,更新last_master_timestamp值,其更新是以事务为单位。所以大事务、DDL容易导致主备延迟大,具体请参见主备复制延迟持续增长后自动恢复
    • 非并行复制:从节点的SQL线程读取了relay log中的事务后,事务未执行前便会更新last_master_timestamp,其更新是以事务为单位。

综上所述,Seconds_Behind_Master的计算公式可以理解为:

Seconds_Behind_Master = 当前从节点服务器的系统时间 - 从节点SQL线程处理中事务在主节点的执行时间 - 从节点的系统时间和主节点服务器系统时间的差值