上篇关于MySQL BUG多不靠谱的问题,吸引了1000多的读者,有读者私信咋办,公司就要用MySQL也切不到PostgreSQL上,可MySQL bug多指望ORACLE是没戏了,怎么才能用上靠谱的MySQL.

今天咱们继续还是阿里云的宋利兵,宋老师解决了一个MySQL存在的大事务问题,今天我们来详细说说。说这个问题前还的说那个外国的MySQL专家的这篇文章。

原文链接:(点击不开的,需要复制链接在浏览器中打开页面) https://jfg-mysql.blogspot.com/2025/05/interesting-binlog-optimization-in-mariadb.html

那个MySQL大事务比你稳定,主从延迟低,为什么? Look my eyes! 因为宋利兵宋老师_MySQL

MySQL的大事务问题

这里我就不翻译了,我总结一下这位“法国”加拿大MySQL专家对于MySQL的“吐槽”。

在使用行级复制的时候,我们难免遇到大事务,而大事务如果较大会导致超过了binlog_cache_size 的设置,最终产生磁盘的临时文件,而这个临时文件可是要跟着你的 binlog 文件的,这一个过程会占用磁盘空间,占用磁盘空间不怕,而更可怕的事会导致其他的事务提交慢,阻塞其他事务,产生MySQL的事务提交卡顿。

那么我们的开源MySQL管这个事情了吗? 当然他们不管开源的MySQL BUG多,性能差着不就是ORACLE要的吗,谁让人家是世界前五的云厂商。

在文章中这位Jean-François Gagné。(让先生 法语发音)提交了 MySQL Bug #118332 请求官方考虑引入该优化。同时文章中又提出了,这个问题阿里云的MySQL专家 宋利兵 宋老师已经有解决方案了,且用到人家的产品中去了。

这也就是说,阿里云的RDS MYSQL没有这个BUG,开源的你就用去吧,一用一个不吱声倒霉去吧。


那个MySQL大事务比你稳定,主从延迟低,为什么? Look my eyes! 因为宋利兵宋老师_MySQL_02

image

我有幸请到了宋老师,宋利兵宋老师 MySQL老粉都知道,啥不知道宋利兵宋老师,你也配叫MySQL的Fans. 在很久很久年前,我还听过3306 Pai,吴丙锡吴老师请宋利兵宋老师在线 MySQL课堂给大家普法 MySQL innodb cluster的原理那时可是 MySQL 5.7,我依稀记得当时宋老师是 ORACLE 中国区负责 innodb cluster 集群的核心开发负责人。

这多少年过去了,宋老师还是持续优化MySQL,所以能人到哪里哪里的产品就牛逼,阿里云的RDS MYSQL 怎么就比你 线下的MYSQL强百倍,知道为什么了吧,牛逼的人在人家阿里云改造 MySQL了。

宋老师把核心对这个问题的改造的资料给我了,我凭着我MySQL这么多年的三脚猫功夫来稍微的解释解释。(其实是抄人家的材料)


宋老师资料

由于Binlog的串行写入机制,大事务不仅自身写入Binlog缓慢,还会阻塞其他事务提交。本功能优化了大事务提交时的Binlog写入机制,使提交速度不再受Binlog Event数量影响,始终保持高效。本功能解决了以下典型问题:

超大事务阻塞实例,导致其他事务无法及时提交。

大事务引发大量IO消耗,造成IO资源耗尽并拖慢查询等业务。

大事务导致小事务执行变慢,引发活跃连接激增和性能抖动,严重时可能触发雪崩效应导致实例不可用。

频繁执行大事务持续引发业务流量的性能抖动。

解决方案:

新建实例:Binlog Cache Free Flush功能默认开启。

存量实例:通过设置全局系统变量loose_binlog_cache_free_flush可开启该功能,参数修改后立即生效,无需重启实例。

相关参数:

loose_binlog_cache_free_flush_limit_size:开启Binlog Cache Free Flush功能后,当事务的Binlog超过该参数值,提交时会将Binlog Cache临时文件转为Binlog正式文件。默认值:256 MB,取值范围: 20971520~18446744073709551615 (单位:字节)

当MySQL实例执行大事务时,慢查询日志可能记录到某些本应快速完成的语句(如COMMIT)出现异常延迟。


那个MySQL大事务比你稳定,主从延迟低,为什么? Look my eyes! 因为宋利兵宋老师_PostgreSQL_03

阿里云原图

原因是另一个线程的大事务因Binlog串行写入机制导致资源竞争。大事务不仅自身写Binlog耗时较长,还会阻塞其他事务的Binlog提交,引发全局串行化延迟。

运行sysbench oltp_write_only时,在每5秒执行一次产生512 MB Binlog的大UPDATE操作后,观察到以下现象:

每次大UPDATE提交时,TPS(每秒事务数)剧烈下降。

抖动时长与Binlog大小正相关:事务产生的Binlog越大,对其他业务的延迟影响越显著。

下图直观的展示了大事务对线上运行业务的影响。


那个MySQL大事务比你稳定,主从延迟低,为什么? Look my eyes! 因为宋利兵宋老师_数据库_04

阿里云原图

UPDATE相关操作:

CREATE TABLE t_large (a INT, b LONGTEXT) ENGINE = InnoDB;# 插入一行数据包含256 MB文本,UPDATE时产生的Binlog events是512 MB。
INSERT INTO t_large VALUES (1, repeat('a', 256000000)); UPDATE t_large SET a = a + 1;

优化后的效果

TPS稳定性显著提升:

优化前:每5秒一次的大UPDATE导致TPS剧烈波动。

优化后(橙色线):大UPDATE对TPS的影响几乎消除。


那个MySQL大事务比你稳定,主从延迟低,为什么? Look my eyes! 因为宋利兵宋老师_#数据库_05

橘黄色的线是优化后的

延迟无明显波动:

不同大小的UPDATE操作对时延的影响不再显著(橙色线为优化后)。

即使Binlog Events超过512 MB,其他事务提交的延迟未受明显干扰。


那个MySQL大事务比你稳定,主从延迟低,为什么? Look my eyes! 因为宋利兵宋老师_MySQL_06

数据库主从延迟

一句话总结,宋老师如何解决这个问题的核心思想

让Binlog cache的临时文件变成最终的binlog文件,而不是复制到binlog文件中。这样在文件头部预留空间用于存放binlog文件头与头部events ,且预估end_pos,提交阶段直接可以将这些数据,转换为binlog的文件,最终优化大事务中的mysql的稳定性和减少数据主从复制延迟的问题,且还可以降低系统的I/O压力,减少阻塞其他事务。

开源的MySQL啥时候解决问题? 2030年吧,应该能解决! 现在咋办,公司开发垃圾就写大事务,那不行你就找 宋老师吧 ! 着急的MYSQL RDS 至少解决了这个大事务不稳定和主从延迟的问题,不信你就试试,当然这只是人家宋老师的优化和改造的冰山一角。

那个MySQL大事务比你稳定,主从延迟低,为什么? Look my eyes! 因为宋利兵宋老师_数据库_07