AliSQL为提升性能,在Binlog提交阶段做了Binlog Parallel Flush优化,开启优化可以有效提升实例的写性能。
前提条件
实例版本为MySQL 8.0。
内核小版本:20230930或以上
说明您可以在基本信息页面的配置信息区域查看是否有升级内核小版本按钮。如果有按钮,您可以单击按钮查看当前版本;如果没有按钮,表示已经是最新版。详情请参见升级内核小版本。
实例的sync_binlog参数不为1。
背景信息
在MySQL中,每个事务在提交阶段都要写Binlog。这个过程是串行的,即一个事务写完后,另一个事务才能开始写Binlog,如上图所示。
同时,这个过程又是很耗时的,写Binlog之前要将Binlog Cache中存储的所有event都解析出来,填上Checksum和log_pos,还需要生成GTID event,随后才能将这些event写入Binlog文件。这个串行且耗时的过程,对实例的写性能造成了很大的瓶颈。为了解决这个瓶颈,AliSQL引入了Binlog Parallel Flush优化。
优化详情
Binlog Buffer
AliSQL在原有逻辑之上,引入了一个Binlog Buffer。多个线程在分配好位置之后,可以并行的将Binlog event写到Binlog Buffer中,然后由后台线程将Binlog Buffer写入Binlog文件。这样一来,原本串行的解析,填充Checksum和log_pos,生成GTID event等步骤,都可以并行的执行,极大优化了事务写 Binlog的性能瓶颈。
并行组提交
在MySQL中,提交阶段事务会成组地写Binlog和Redo Log,这样做可以最大限度地合并IO操作,提升性能。在本优化中,依旧保留这种组提交的思想,加入组提交后的Binlog Parallel Flush优化,如下图所示。
在Binlog Parallel Flush优化中,每个事务需要串行地分配GTID和Binlog Buffer空间,随后多个组可以并行地写Binlog Buffer,在等待Redo log持久化和后台线程写Binlog完成后,整组事务就可以提交。
Binlog持久化
在Binlog Parallel Flush优化中,Binlog文件由一个后台线程周期性的进行持久化,默认持久化周期为每秒一次。
参数介绍
loose_binlog_parallel_flush
Binlog Parallel Flush的功能开关。全局系统变量,取值:on或off。修改本参数立刻生效,不需要重启实例。
优化效果
测试环境
选取RDS MySQL四种不同规格做测试对比,如表格所示。
RDS产品 | 版本号 | CPU&内存 | 存储类型 | 存储空间 |
RDS MySQL | 8.0(内核小版本20230930) | 16核 32GB | ESSD PL1 | 1000 GB |
16核 32GB | SSD | 1000 GB | ||
64核 128GB | ESSD PL1 | 1000 GB | ||
64核 128GB | SSD | 1000 GB |
参数设置
测试实例使用高性能参数模板,该模板中两个性能相关参数的配置为:sync_binlog = 1000
、innodB_flush_log_at_trx_commit = 2
。
测试脚本
使用SysBench的oltp_update_non_index脚本进行性能测试,测试的数据量为100张表,每张表有10万行数据。
测试结果
测试结果如下图所示。高并发性能下,Parallel Flush与MySQL原生的Normal Flush相比,有明显的性能提升,峰值性能提升在10%到30%之间。