使用MySQL复制架构时,经常出现从库延迟,如何来解决延迟问题呢?以让读写分离更稳!

延迟的原因

主从复制环境下,从库在一些场景下出现延迟,当发生延迟时,如果业务使用读写分离,在从库上读取的数据将是旧的,会出现业务异常。

从库在什么场景下会出现延迟呢?如:

  • 主从服务器硬件配置不一致,参数不一致问题
  • 从库服务器硬件配置低,或者一机部署多个实例
  • 从库的InnoDB Buffer Pool等参数配置低
  • 从库上的慢查询多,压力大
  • 因DDL变更,或大事务的执行
  • DDL变更可以使用gh-ost、pt-osc等工具来执行
  • 大事务进行拆分
  • 从库在进行逻辑备份,而主库执行了DDL操作,等待MDL锁造成延迟
  • 表没有主键,应用事件时全表扫描
  • 可以通过调整slave_rows_search_algorithms参数
  • 通过优化表结构
  • 主库的TPS大,超出了从库SQL线程应用事件的能力
  • 使用并行复制

基于Schema的并行复制

在MySQL 5.6开始支持基于库的并行复制,当多线程写多个数据库,且没有跨库的操作时,在从库可以通过多个worker线程并行进行应用。

并行复制 mysql 并行复制 级联从库慢_mysql

每个Worker线程会有"库名+表名"的Hash表,可参考WL#5569[1],Coordinator从Relay Log读取日志,通过判断事务中的"库名+表名"是否有Worker在执行事务,有时将分配给该Worker线程,如果跟多个Worker线程处理的事务存在冲突,将等待。

该方案,因只基于库来进行并行,对从库的并行性能提升较少。

基于组提交的并行复制

在MySQL 5.7开始实现了基于组提交的方式来实现并行复制,主库上同时处于Prepare阶段的事务都可以并行,以及处于Prepare和Commit阶段的事务也是可以并行。

写binlog和redo的两阶段提交过程:

并行复制 mysql 并行复制 级联从库慢_mysql_02

主库在写binlog时会写入组提交的信息:具体实现可参考LOGICAL_CLOCK[2],WL#7165[3],MySQL 5.7并行复制实现原理与调优[4],MySQL5.7并行复制中并行的真正含义[5]

  • last_committed,表示上一个组提交的logcial_clock,如果相同,表示可以进行并行应用
  • sequence_number,表示当前组提交中,各事务的logcial_clock

5.7通过参数slave_parallel_type来控制启用新的并行复制:

  • DATABASE,基于库的并行复制
  • LOGICAL_CLOCK,基于组提交的并行复制

这种方式提高了从库的并发能力,但是如果主库并发不高(如单线程),从库的并行能力还是不足,MySQL 5.7可以通过参数(binlog_group_commit_sync_delay,binlog_group_commit_sync_no_delay_count)来控制提交事务的并发度。

两个参数通过控制binlog进行sync的等待时间来提高同时提交的事务数。

  • binlog_group_commit_sync_delay,等待多少微秒才进行提交
  • binlog_group_commit_sync_no_delay_count,在等待的时间内,并发事务数量达到该值将进行提交

基于行的并行复制

MySQL 5.7.22[6]开始支持基于行的并行复制,在开启LOGICAL_CLOCK的情况下,使用参数binlog_transaction_dependency_tracking控制来支持该特性。

binlog_transaction_dependency_tracking[7]参数支持三种配置:

  • COMMIT_ORDER,默认值,使用基于LOGICAL_CLOCK的并行机制(组提交)
  • WRITESET,对事务操作的每一行计算Hash值(主键、唯一键)组成一个writeset,通过判断各事务writeset是否有交集,无交集即可并行执行
  • 如表有外键约束或无主键和唯一键将退化为COMMIT_ORDER
  • WRITESET_SESSION,机制同WRITESET,但对同一个会话的事务要保证顺序执行

对并行复制的性能对比可以参考:Improving the Parallel Applier with Writeset-based Dependency Tracking[8]

并行复制 mysql 并行复制 级联从库慢_并行复制 mysql_03

总结

从5.7.22开始,建议开启并行复制以提高从库应用事件的效率。

并行复制 mysql 并行复制 级联从库慢_mysql 交集_04