mysql 8.0 已移除 tmp_table_size 参数,实际生效的是 max_heap_table_size 和 internal_tmp_mem_storage_engine;监控 created_tmp_disk_tables / created_tmp_tables 比值(超5%需优化)比调参更关键。

查不到 tmp_table_size 就对了,它在 8.0 里根本不存在
MySQL 8.0 彻底移除了 tmp_table_size 参数。如果你从 5.7 升级上来,配置文件里还留着这行,MySQL 启动时会静默忽略,既不报错也不警告。执行 SHOW VARIABLES LIKE 'tmp_table_size' 会返回空或报错 Unknown system variable 'tmp_table_size';SELECT @@tmp_table_size 同样无效。
真正起作用的是两个参数:max_heap_table_size 和 internal_tmp_mem_storage_engine。临时表是否落盘,取决于二者中较小的那个值,再结合查询实际中间结果大小——不是看单个参数设多大,而是看“内存上限”和“引擎能力”的交集。
务必清理旧配置项,否则你会误以为调参没生效,白折腾。
监控 Created_tmp_disk_tables / Created_tmp_tables 比值才是关键
只看 Created_tmp_disk_tables 绝对值没意义,得算比值:
-
SHOW GLOBAL STATUS LIKE 'Created_tmp_tables':总临时表数(内存 + 磁盘) -
SHOW GLOBAL STATUS LIKE 'Created_tmp_disk_tables':其中写到磁盘的数量 - 比值 =
Created_tmp_disk_tables / Created_tmp_tables
超过 5% 就该介入;超过 15% 已有明显性能瓶颈。注意:这个比值只对新建立的连接实时更新,老连接沿用启动时的设置,所以调参后要等 10–30 分钟再评估真实效果。
释放会话级临时表空间(temp_n.ibt)靠断连,不是靠 OPTIMIZE TABLE
MySQL 8.0 的会话级临时表空间(temp_n.ibt 文件)在连接断开时自动截断并归还到池中,不需要人工干预。它的生命周期与连接绑定,不是普通表,所以 OPTIMIZETABLE 对它完全无效。
如果你发现 #innodb_temp/ 目录下 temp_*.ibt 文件长期不减少:
- 检查是否有长连接未断开(比如应用连接池没正确 close)
- 确认
innodb_temp_tablespaces_dir路径是否被其他进程占用或权限异常 - 运行
SELECT * FROM INFORMATION_SCHEMA.INNODB_SESSION_TEMP_TABLESPACES查看哪些ID还在被占用
重启 MySQL 会清空整个池,但这是最后手段——会中断所有连接,且无法定位具体哪个查询在撑大临时空间。
ibtmp1 不会自动收缩,但通常不用手动删
全局临时表空间 ibtmp1 存放的是临时表的回滚段,它支持 autoextend,但**从不自动收缩**。即使所有临时表都被销毁,ibtmp1 文件大小也维持不变。
不过你一般不需要、也不应该手动删除 ibtmp1:
- MySQL 正常关闭时会自动重建
ibtmp1,大小回归初始设定(如ibtmp1:12M:autoextend) - 如果因异常关闭导致
ibtmp1损坏,MySQL 启动时会报错并拒绝服务,此时需按官方流程重建,而非简单 rm - 盲目删除
ibtmp1可能引发启动失败或数据不一致
真正需要关注的是:为什么它持续膨胀?大概率是 Created_tmp_disk_tables 比值过高,说明大量查询被迫落盘——根源不在 ibtmp1 本身,而在 SQL 写法或内存限制设置上。











