在高并发写入时如何优化MySQL的事务提交吞吐量

风宇君_2285

风宇君_2285

2026-09-30

126人浏览

原创

必须协同调整innodb_flush_log_at_trx_commit和sync_binlog:单独修改一个吞吐量几乎无提升且易致数据不一致;默认双1最安全但性能差;推荐组合为innodb_flush_log_at_trx_commit=2 + sync_binlog=0或1000,配合批量提交与组提交优化。

在高并发写入时如何优化mysql的事务提交吞吐量

innodb_flush_log_at_trx_commit 和 sync_binlog 必须协同调整

单独改其中一个参数,吞吐量几乎没变化,还可能引入不一致风险。默认值 innodb_flush_log_at_trx_commit=1 + sync_binlog=1 是最安全组合,但每事务两次 fsync,SSD 上也扛不住 2000+ TPS。

实操建议:

  • innodb_flush_log_at_trx_commit=2:日志写入 OS buffer 即返回,崩溃最多丢 1 秒数据;写入吞吐通常翻倍以上
  • sync_binlog=0 或 sync_binlog=1000:关闭 binlog 强制刷盘,或改为每 1000 次事务刷一次;主从延迟会略增,但避免 binlog 与 redo 双重 I/O 压力
  • 两项必须同时生效——否则 redo 刷得快、binlog 刷得慢,组提交(Group Commit)失效,性能提升归零

批量提交比单条提交省掉 90% 以上的 commit 开销

autocommit=1 下,每条 INSERT 都是独立事务,每次都要走 prepare → write log → fsync → commit 流程。网络往返 + 日志刷盘成了最大瓶颈,不是磁盘慢,是协议层太啰嗦。

实操建议:

  • 显式关闭自动提交:SET autocommit = 0,再用 BEGIN / COMMIT 包裹多条语句
  • 每批控制在 100–1000 行之间:太少起不到合并效果,太多易触发锁升级或超时(innodb_lock_wait_timeout 默认 50 秒)
  • 避免在事务里做耗时操作(如 HTTP 请求、文件读写),否则锁持有时间不可控

别让 ON DUPLICATE KEY UPDATE 成为并发写入的隐形锁杀手

看起来是“存在则更新”,实际在高并发下唯一键冲突频繁时,InnoDB 会加 gap lock 或 next-key lock,导致大量线程卡在 update 状态,SHOW ENGINE INNODB STATUS 里能看到大量 waiting for table metadata lock 或 lock wait timeout exceeded。

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载

实操建议:

  • 确认业务是否真需要“upsert”语义;若只是高频插入,优先用纯 INSERT + 忽略重复错误(ERROR 1062)
  • 若必须 upsert,考虑拆成两步:先 SELECT 判断是否存在(加 FOR UPDATE),再按需 INSERT 或 UPDATE,但要严格按相同顺序访问表,防死锁
  • 对计数类字段(如 pv、uv),改用 Redis 自增 + 定时异步落库,彻底绕过行锁

Redo Log 组提交不是默认就高效的

即使开了 innodb_flush_log_at_trx_commit=1,若 binlog_group_commit_sync_delay=0(默认),leader 线程几乎不等待,组大小常为 1~2,等于没启用组提交。

实操建议:

  • 设 binlog_group_commit_sync_delay=10000(10ms),给 leader 收集更多事务的机会;配合 binlog_group_commit_sync_no_delay_count=10,凑够 10 个就发,不等满延时
  • 确保 sync_binlog=1 已开启——否则 binlog 不刷盘,组提交逻辑不触发
  • 避免长事务干扰:一个运行 30 秒的事务会阻塞后续所有事务进入 commit 阶段,组提交失效

真正卡住吞吐的,往往不是 SQL 写法,而是日志刷盘策略和事务边界设计。参数调得再激进,如果应用层还在循环执行单条 INSERT,或者事务里混着 sleep(1),所有优化都白搭。

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

mysql

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

2023.10.12

3883

8

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.27

831

4

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

2024.02.23

1009

5

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

5701

10

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2024.03.06

2663

4

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

2024.04.07

5680

11

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

2024.04.29

7501

6

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

1030

5

sql中删除一列的命令是什么
sql中删除一列的命令是什么

在sql中,使用alter table语句可以删除一列,语法为:alter table table_name drop column column_name。想了解更多sql的相关内容,可以阅读本专题下面的文章。

2024.04.29

892

5

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 177人学习

使用phpenv集成环境安装极致CMS
使用phpenv集成环境安装极致CMS

共2课时 | 282人学习