实测GreatSQL 8.4.4-5新特性:大事务binlog独立落盘

业务痛点

在以前,使用 MySQL 处理大事务时,一般会出现数据库整体性能卡顿问题:单个大事务提交会引发全库 TPS 剧烈抖动,普通事务提交被大事务阻塞,磁盘 I/O 负载急剧增高,高并发业务场景下该现象尤为严重。 根源在于原生 binlog 提交流程存在固有缺陷:

  1. 大事务产生的binlog数据先写入 binlog cache 由于溢出内存写入临时文件,提交阶段需要重新读取 cache 内容,再写入正式 binlog 文件,产生双倍磁盘写入,造成严重写放大、I/O 资源浪费;
  2. 二次读写流程执行周期长,会长期持有全局 binlog 锁,阻塞其他所有事务提交;
  3. I/O 阻塞 + 锁竞争叠加,导致数据库吞吐量剧烈波动,业务响应延迟。

GreatSQL解决方案:大事务 binlog 独立落盘

GreatSQL 8.4.4-5 推出大事务 binlog 独立落盘优化特性,彻底消除原生 binlog 二次读写带来的性能损耗。

核心优化思路

优化传统「binlog cache溢出落盘→ binlog cache 读取 → 写入 binlog 文件」流程,预构建完整结构的 binlog cache 临时文件,事务满足阈值后直接将 cache 文件重命名为正式 binlog 文件,消除二次写 I/O,大幅缩短事务提交时间。

底层关键改造

  1. 可重构 Cache 文件结构 写入 binlog cache 时提前预留文件头、描述事件、GTID 相关事件、对齐填充位等标准 binlog 必备结构,cache 文件天然符合正式 binlog 文件格式,无需二次加工改写。
  2. 文件直接 Rename 落盘机制 当事务达到阈值,先结束当前正在写入的 binlog 文件,向 cache 预留空间补全头部事件,通过文件重命名操作直接将 cache 临时文件转为正式 binlog,省去数据复制写入动作。

特性预期收益

  1. 大事务提交延迟降低 30%~70%;
  2. 高并发混合事务场景整体 TPS 提升 10%~40%;
  3. 消除 binlog 写放大,磁盘 I/O 显著下降,消除大事务对业务 TPS 冲击问题。

使用方法

GreatSQL增加了系统变量:binlog_large_commit_threshold

  • 变量类型:无符号长整型(ulonglong),取值范围 10485760 ~ 18446744073709551615
  • 默认值:128MB
  • 作用逻辑:当单个事务 binlog 数据大小达到该阈值,自动启用大事务 binlog 独立落盘优化逻辑。

实测binlog独立落盘

binlog独立落盘

系统变量binlog_large_commit_threshold设置了binlog独立落盘的阈值,binlog大小超过此值,GreatSQL会将该事务的binlog独立落盘。

-- binlog_large_commit_threshold的默认值是128M
greatsql> SHOW VARIABLES LIKE 'binlog_large_commit_threshold';
+-------------------------------+-----------+
| Variable_name                 | Value     |
+-------------------------------+-----------+
| binlog_large_commit_threshold | 134217728 |
+-------------------------------+-----------+
1 row in set (0.01 sec)

执行一个超过128M的大事务

-- 检查binlog信息,最新binlog是binlog.000003
greatsql> SHOW BINARY LOGS;
+---------------+-----------+-----------+
| Log_name      | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 |  19082048 | No        |
| binlog.000002 | 190815557 | No        |
| binlog.000003 |       158 | No        |
+---------------+-----------+-----------+
3 rows in set (0.00 sec)

-- 执行一个大事务
greatsql>INSERT INTO test2 SELECT * FROM test1;
Query OK, 1000000 rows affected (25.41 sec)
Records: 1000000  Duplicates: 0  Warnings: 0

-- 检查binglog,发现事务未写入binlog.000003,而是写入了binlog.000004
greatsql> SHOW BINARY LOGS;
+---------------+-----------+-----------+
| Log_name      | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 |  19082048 | No        |
| binlog.000002 | 190815557 | No        |
| binlog.000003 |       391 | No        |
| binlog.000004 | 190725193 | No        |
+---------------+-----------+-----------+
4 rows in set (0.00 sec)

对比大事务对TPS的影响

执行大事务,不使用binlog独立落盘

-- 设置binlog独立落盘的阈值1G
greatsql> SET GLOBAL binlog_large_commit_threshold=1024*1024*1024;
Query OK, 0 rows affected (0.00 sec)

greatsql> SHOW BINARY LOGS;
+---------------+-----------+-----------+
| Log_name      | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 |  19082048 | No        |
| binlog.000002 | 190815557 | No        |
| binlog.000003 |       391 | No        |
| binlog.000004 | 190725403 | No        |
| binlog.000005 | 443557932 | No        |
+---------------+-----------+-----------+
5 rows in set (0.00 sec)

greatsql> TRUNCATE TABLE test2;
Query OK, 0 rows affected (0.05 sec)

-- 执行大事务,但该事务小于binlog_large_commit_threshold(1G)
greatsql> SELECT now();INSERT INTO test2 SELECT * FROM test1;select now();
+---------------------+
| now()               |
+---------------------+
| 2026-08-13 12:18:26 |
+---------------------+
1 row in set (0.00 sec)

Query OK, 1000000 rows affected (30.22 sec)
Records: 1000000  Duplicates: 0  Warnings: 0

+---------------------+
| now()               |
+---------------------+
| 2026-08-13 12:18:56 |
+---------------------+
1 row in set (0.00 sec)

-- 事务没有独立落盘,写到了binlog.000005 
greatsql> SHOW BINARY LOGS;
+---------------+-----------+-----------+
| Log_name      | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 |  19082048 | No        |
| binlog.000002 | 190815557 | No        |
| binlog.000003 |       391 | No        |
| binlog.000004 | 190725403 | No        |
| binlog.000005 | 659791246 | No        |
+---------------+-----------+-----------+
5 rows in set (0.00 sec)

对sysbench测试TPS的影响

2026-08-13 12:18:53 [ 33s ] thds: 10 tps: 480.99 qps: 9606.80 (r/w/o: 6725.86/1918.96/961.98) lat (ms,95%): 19.65 err/s: 0.00 reconn/s: 0.00
2026-08-13 12:18:54 [ 34s ] thds: 10 tps: 462.02 qps: 9243.42 (r/w/o: 6470.29/1849.08/924.04) lat (ms,95%): 17.63 err/s: 0.00 reconn/s: 0.00
2026-08-13 12:18:55 [ 35s ] thds: 10 tps: 471.95 qps: 9486.03 (r/w/o: 6648.32/1893.81/943.90) lat (ms,95%): 18.95 err/s: 0.00 reconn/s: 0.00
2026-08-13 12:18:56 [ 36s ] thds: 10 tps: 135.01 qps: 2640.23 (r/w/o: 1840.16/530.05/270.02) lat (ms,95%): 861.95 err/s: 0.00 reconn/s: 0.00
2026-08-13 12:18:57 [ 37s ] thds: 10 tps: 791.87 qps: 15849.30 (r/w/o: 11098.10/3167.47/1583.73) lat (ms,95%): 17.01 err/s: 0.00 reconn/s: 0.00
2026-08-13 12:18:58 [ 38s ] thds: 10 tps: 507.26 qps: 10140.24 (r/w/o: 7094.66/2032.06/1013.52) lat (ms,95%): 17.32 err/s: 0.00 reconn/s: 0.00
2026-08-13 12:18:59 [ 39s ] thds: 10 tps: 499.13 qps: 9991.69 (r/w/o: 7002.88/1989.53/999.27) lat (ms,95%): 16.41 err/s: 0.00 reconn/s: 0.00
2026-08-13 12:19:00 [ 40s ] thds: 10 tps: 468.96 qps: 9385.18 (r/w/o: 6562.43/1884.84/937.92) lat (ms,95%): 17.63 err/s: 0.00 reconn/s: 0.00

在事务完成的时间点(2026-08-13 12:18:56),TPS被明显拉低,由约470降低到135,降低约70% 。

执行大事务,使用binlog独立落盘

-- 设置binlog独立落盘的阈值10M
greatsql> SET GLOBAL binlog_large_commit_threshold=10*1024*1024;
Query OK, 0 rows affected (0.00 sec)


greatsql> SHOW BINARY LOGS;
+---------------+-----------+-----------+
| Log_name      | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 |  19082048 | No        |
| binlog.000002 | 190815557 | No        |
| binlog.000003 |       391 | No        |
| binlog.000004 | 190725403 | No        |
| binlog.000005 | 659791246 | No        |
+---------------+-----------+-----------+
5 rows in set (0.00 sec)

greatsql> TRUNCATE TABLE test2;
Query OK, 0 rows affected (0.03 sec)

-- 执行一个大事务(约198M)
greatsql> SELECT now();INSERT INTO test2 SELECT * FROM test1;select now();
+---------------------+
| now()               |
+---------------------+
| 2026-08-13 12:21:53 |
+---------------------+
1 row in set (0.00 sec)

Query OK, 1000000 rows affected (27.34 sec)
Records: 1000000  Duplicates: 0  Warnings: 0

+---------------------+
| now()               |
+---------------------+
| 2026-08-13 12:22:20 |
+---------------------+
1 row in set (0.00 sec)

-- 大事务没有写入binlog.000005,写到了binlog.000006 
greatsql> SHOW BINARY LOGS;
+---------------+-----------+-----------+
| Log_name      | File_size | Encrypted |
+---------------+-----------+-----------+
| binlog.000001 |  19082048 | No        |
| binlog.000002 | 190815557 | No        |
| binlog.000003 |       391 | No        |
| binlog.000004 | 190725403 | No        |
| binlog.000005 | 676207441 | No        |
| binlog.000006 | 208456762 | No        |
+---------------+-----------+-----------+
6 rows in set (0.01 sec)

对sysbench测试TPS的影响

2026-08-13 12:22:16 [ 34s ] thds: 10 tps: 450.49 qps: 9003.74 (r/w/o: 6297.80/1804.96/900.98) lat (ms,95%): 18.61 err/s: 0.00 reconn/s: 0.00
2026-08-13 12:22:17 [ 35s ] thds: 10 tps: 449.98 qps: 9022.58 (r/w/o: 6323.70/1799.92/898.96) lat (ms,95%): 17.63 err/s: 0.00 reconn/s: 0.00
2026-08-13 12:22:18 [ 36s ] thds: 10 tps: 434.03 qps: 8658.63 (r/w/o: 6056.44/1733.13/869.06) lat (ms,95%): 17.32 err/s: 0.00 reconn/s: 0.00
2026-08-13 12:22:19 [ 37s ] thds: 10 tps: 469.99 qps: 9391.79 (r/w/o: 6572.85/1878.96/939.98) lat (ms,95%): 18.95 err/s: 0.00 reconn/s: 0.00
2026-08-13 12:22:20 [ 38s ] thds: 10 tps: 500.00 qps: 10004.97 (r/w/o: 7005.98/1999.99/999.00) lat (ms,95%): 15.55 err/s: 0.00 reconn/s: 0.00
2026-08-13 12:22:21 [ 39s ] thds: 10 tps: 429.71 qps: 8572.31 (r/w/o: 5993.04/1718.85/860.42) lat (ms,95%): 31.94 err/s: 0.00 reconn/s: 0.00
2026-08-13 12:22:22 [ 40s ] thds: 10 tps: 434.91 qps: 8712.29 (r/w/o: 6104.82/1738.65/868.82) lat (ms,95%): 26.68 err/s: 0.00 reconn/s: 0.00
2026-08-13 12:22:23 [ 41s ] thds: 10 tps: 456.40 qps: 9096.05 (r/w/o: 6354.62/1828.62/912.81) lat (ms,95%): 23.52 err/s: 0.00 reconn/s: 0.00
2026-08-13 12:22:24 [ 42s ] thds: 10 tps: 361.98 qps: 7255.68 (r/w/o: 5082.77/1447.94/724.97) lat (ms,95%): 30.81 err/s: 0.00 reconn/s: 0.00
2026-08-13 12:22:25 [ 43s ] thds: 10 tps: 425.99 qps: 8562.86 (r/w/o: 5996.91/1713.97/851.99) lat (ms,95%): 29.19 err/s: 0.00 reconn/s: 0.00

在事务完成时间点(2026-08-13 12:22:20),TPS没有降低,大事务对TPS的冲击消失。

测试总结

经对比测试验证,GreatSQL 大事务 binlog 独立落盘特性效果显著。该特性通过文件结构预构建与文件直接 rename 落盘的优化方式,彻底消除 binlog 二次写入带来的IO写放大问题,大幅减少大事务提交对全局事务的阻塞影响,有效规避了大事务提交引发的吞吐量波动,彻底消除大事务对业务整体TPS稳定性的冲击,确保数据库高并发TP业务场景的平稳运行。

posted @ 2026-08-19 08:11  GreatSQL  阅读(76)  评论(0)    收藏  举报