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
- time(0):当前从节点服务器的系统时间。
- clock_diff_with_master:从节点的系统时间和主节点服务器系统时间的差值,一般为0。如果主从节点系统时间不一致,那么计算出的从节点复制时延会不准确。
- 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线程处理中事务在主节点的执行时间 - 从节点的系统时间和主节点服务器系统时间的差值