mysql 8.0并发事务上限由innodb_rollback_segments与undo表空间数量共同硬性约束,理论值为128×1024×2=262144;dml事务需占用普通和临时两类回滚段槽位,实际可用值减半,且受purge线程效率制约。

undo回滚段个数直接决定并发事务上限
MySQL 8.0 的并发事务数不是无限制的,它被 innodb_rollback_segments 和 undo 表空间数量共同硬性约束。每个活跃事务必须独占至少一个回滚段槽位(slot),而每个回滚段最多提供 1024 个槽位(默认页大小 16KB)。所以总并发能力 = innodb_rollback_segments × 1024 × undo 表空间个数。
例如,默认配置 innodb_rollback_segments = 128、innodb_undo_tablespaces = 2,理论最大并发事务数是 128 × 1024 × 2 = 262144。但注意:如果事务含 INSERT/UPDATE/DELETE,实际可用值要再除以 2 —— 因为这类操作会同时占用普通事务和临时表事务两类槽位。
为什么DML事务要“双倍”消耗回滚段槽位
InnoDB 对事务类型做了物理隔离:普通事务和临时表事务分别使用不同回滚段子集(默认各占一半)。当你执行一条 UPDATE,它既产生普通事务的 update undo log(用于 MVCC 和回滚),又可能触发内部临时表操作(如排序、去重),从而额外申请一个临时事务槽位。
- 只读事务(纯
SELECT)不占槽位 -
INSERT/UPDATE/DELETE至少占用 2 个槽位:1 个普通 + 1 个临时 - 长时间未提交的大事务会持续锁住槽位,导致后续事务排队甚至超时
动态增加undo表空间能立刻提升并发吗
能,但有条件。MySQL 8.0.14+ 支持在线添加 undo 表空间,命令是 CREATE UNDO TABLESPACE。但它不会自动扩大现有回滚段容量,只是新增一组独立的 128 个回滚段(每个仍含 1024 槽位)。
关键点:
- 新表空间必须指定绝对路径,且目录需 MySQL 进程有读写权限
- 新增后需重启或执行
SET GLOBAL innodb_undo_tablespaces = N(N 为总数)才生效 - 旧事务仍绑定在原表空间,新事务才会逐步分摊到新增空间
- 不能删除正在使用的 undo 表空间;必须等所有事务提交/回滚完毕才能
DROP
容易被忽略的隐性瓶颈:purge线程跟不上
回滚段槽位释放依赖后台 purge 线程清理已提交事务的 undo log。如果 innodb_purge_threads 设置过低(默认 1),或大事务频繁提交,purge 延迟会导致“可用槽位”迟迟不回收,表现就是 SHOW ENGINE INNODB STATUS 中看到 History list length 持续飙升。
这时即使你加了 undo 表空间,也解决不了根本问题。需要同步调高:
-
innodb_purge_threads(建议设为 4 或更高) -
innodb_max_purge_lag(控制 purge 压力阈值) -
innodb_undo_log_truncate(开启自动截断,配合innodb_max_undo_log_size)
真正卡住并发的,往往不是槽数不够,而是 purge 跟不上提交节奏——这个点查监控时最容易漏掉。











