Binlog Cache Free Flush

在有大事务的业务场景中,大事务提交时常会出现Binlog耗时过长、实例长时间不可写或夯住(hang)的问题。RDS MySQL引入的Binlog Cache Free Flush功能,对大事务提交写Binlog的阶段做了优化,有效解决了该问题,能够提升实例的稳定性。

前提条件

  • 实例版本:MySQL 8.0

  • 内核小版本:20230930或以上

    说明

    您可以在基本信息页面的配置信息区域查看是否有升级内核小版本按钮。如果有按钮,您可以单击按钮查看当前版本;如果没有按钮,表示已经是最新版。详情请参见升级内核小版本

实现原理

Binlog Cache介绍

image

Binlog Cache是一块会话级别的临时空间,即为每一个会话建立一个Binlog Cache,用来暂存Binlog events。Binlog Cache由内存缓存(Buffer)和临时文件(Temp File)两部分组成,其中内存缓存的大小由binlog_cache_size参数控制。当事务比较大,内存缓存被写满之后,事务的events就会被记录到临时文件中。

事务在执行过程中,会将自己生成的events暂存在Binlog Cache中。事务在提交时,需要按顺序从Binlog Cache中读出一个个Event,并且更新events的end_pos(结束位置)和checksum(校验和),然后将其写到Binlog文件中。为了保证事务在Binlog文件中的连续性,整个过程是加锁进行的,即一个事务写Binlog文件时,其他事务都会被阻塞。

大事务写Binlog带来的问题

image

对于非常大的事务,其使用的Binlog Cache可能会达到几十个GB,在提交事务期间写Binlog的过程耗时很长,并且对实例影响极大,主要包括以下两点:

  • 大事务写Binlog过程中,会持有Binlog写锁,期间整个实例将处于不可写状态。

  • 大事务写Binlog的过程会消耗大量IO资源,在IO资源有限的场景下,可能导致整个实例夯住(hang)。

Binlog Cache Free Flush优化

image

AliSQL对Binlog Cache的临时文件进行了改造,使其具备了直接转为Binlog文件的能力。开启本功能后,在大事务提交时会将Binlog Cache临时文件直接转化为Binlog正式文件,这个过程的耗时很短,并且IO资源消耗很少,彻底解决了大事务写Binlog对实例的影响。

对Binlog Cache的改造

image

为了使Binlog Cache的临时文件能够直接转化为Binlog正式文件,AliSQL对Binlog Cache的使用方式进行了改造。主要包括以下两点:

  • 在写Binlog Cache的临时文件时,在文件头部预留出一部分空间。在临时文件转Binlog正式文件过程中,这部分空间用于存放Binlog头部的events。

  • 在写Binlog Cache时,每个events都根据预留空间的大小计算自己的end_pos。

Binlog文件的转化

image

在大事务提交时,会直接将Binlog Cache临时文件转化为Binlog正式文件。在这个过程中,Binlog的文件头(File Header )和头部的几个events(Header Events)会填满预留空间,预留空间主要包含四部分内容:

  • File Header:在每个Binlog文件的头部4字节,都写有一个标识:[ 0xFE 'bin'],用来标识此文件是个Binlog文件。

  • Header Events:包括Format description event和Previous gtid event。

  • Empty event:用来填充剩余的预留空间的,使用当前Binlog中已有的ignorable event类型。

  • Gtid event:大事务的Gtid是在提交阶段生成的,Gtid event也会被写到预留空间中。

预留空间之后的Events in Binlog Cache,是Binlog Cache中的内容,主要包括Query event、Table map event、Row event和Xid event等。

与普通的Binlog文件相比,使用本功能转化而来的Binlog文件有两点区别:

  • 多了一个Empty event。

  • 默认关闭了本文件的checksum。

Binlog Cache Free Flush功能不会改变Binlog的格式,基于Binlog的复制及第三方的工具不会受任何影响。

参数介绍

  • loose_binlog_cache_free_flush:

    Binlog Cache Free Flush的功能开关。全局系统变量,修改该参数立刻生效,不需要重启实例。

    取值范围:on或off。

  • loose_binlog_cache_free_flush_limit_size:

    开启Binlog Cache Free Flush功能后,当事务的Binlog超过该参数值,提交时会将Binlog Cache临时文件转为Binlog正式文件。

    默认值:256 MB

    取值范围: 20971520~18446744073709551615 (单位:字节)

优化效果

image.png

对比常用的ESSD PL1云盘和本地盘SSD两种形态,在开启和不开启Binlog Cache Free Flush功能时大事务提交阶段的耗时,结果如上图所示。

可以看到,开启Binlog Cache Free Flush功能时,大事务提交的耗时被大幅缩短,提交导致的IO压力和长时间持写锁的问题被彻底消除。