根本解法是调temptable_max_ram(必须重启生效),该参数不支持SET GLOBAL,须写入my.cnf的[mysqld]段并重启;同时需设innodb_fast_shutdown=0再关库,确保旧ibtmp1被删除。

MySQL 8.0 升级后空间“突然变大”,90% 是日志、临时表空间或缓冲池配置变更导致的假性膨胀——不是数据真多了,而是旧机制被新规则接管后,默认行为从“保守不占”变成“积极预分配”。不查实况直接删文件,容易断主从或触发 OOM。
为什么 ibtmp1 持续暴涨却查不到 /tmp 写满
MySQL 8.0.16+ 默认用 TEMPTABLE 引擎管理内存临时表,它不走 tmpdir,而是直写 InnoDB 临时表空间 ibtmp1。所以:
-
lsof +D /tmp查不到大文件是正常的,别在/tmp目录里翻了 -
SHOW GLOBAL STATUS LIKE 'Created_tmp_disk_tables'飙升,但Created_tmp_tables增长更猛 → 说明大量临时表在内存阶段就失败,直接落盘到ibtmp1 - 错误日志里报
The table '/tmp/#sql-xxx' is full是误导路径,真实位置就是ibtmp1
根本解法是调 temptable_max_ram(必须重启生效):
- 该参数不支持
SET GLOBAL,必须写进my.cnf的[mysqld]段,例如:temptable_max_ram = 4G - 设值不能超物理内存 15%,比如 64 GiB 机器最多设
8G - 重启前务必先执行:
SET GLOBAL innodb_fast_shutdown = 0;,再SHUTDOWN;,否则旧ibtmp1不会被删除
为什么 binlog 占满磁盘却没自动清理
MySQL 8.0+ 彻底废弃 expire_logs_days,设了会报错 3683,且默认 binlog_expire_logs_seconds = 0 —— 等于永不清除。
- 先确认是否启用:
SHOW VARIABLES LIKE 'log_bin';返回ON才有效 - 查当前策略:
SHOW VARIABLES LIKE 'binlog_expire_logs_seconds';若为0,说明自动清理关闭;再查binlog_expire_logs_auto_purge必须是ON - 永久生效要改配置:在
[mysqld]下加两行:binlog_expire_logs_seconds = 604800(7 天)、binlog_expire_logs_auto_purge = ON - 若之前设过
expire_logs_days,顺手清掉:SET GLOBAL expire_logs_days = 0;,避免冲突
已堆积的日志不会自动删,得手动 PURGE,但必须核对主从安全下限:
- 主库执行:
SHOW MASTER STATUS;记下当前File(如mysql-bin.000042) - 每台从库执行:
SHOW SLAVE STATUS\G,看Relay_Master_Log_File(如mysql-bin.000035) - 取所有从库中最小序号(这里是
000035),则最多只能PURGE TO 'mysql-bin.000036'; - GTID 模式下禁用
TO,改用时间点:PURGE BINARY LOGS BEFORE '2026-10-05 00:00:00';
为什么 innodb_buffer_pool_size 显示 4GB 实际 RSS 却占了 12GB
MySQL 8.0.22+ 启用自动推导 innodb_buffer_pool_chunk_size,若你没显式设置,它会按物理内存算出 chunk 大小(比如 256MB),再乘以 innodb_buffer_pool_instances(默认 8),最终分配远超配置值。
- 查真实分配:
SHOW VARIABLES LIKE 'innodb_buffer_pool%';,对比innodb_buffer_pool_size和innodb_buffer_pool_chunk_size × innodb_buffer_pool_instances - 手动固定 chunk:
innodb_buffer_pool_chunk_size = 128M(必须是 1M 整数倍) - 确保
innodb_buffer_pool_size / (chunk_size × instances)是整数,否则 MySQL 会悄悄向上补齐 → 多占内存 - 例如设
innodb_buffer_pool_size = 2048M,instances就别设 7(2048 ÷ 7 不整除),改设 2、4 或 8
另外,innodb_buffer_pool_dump_at_shutdown 默认开启,重启后会加载上次 dump 的热页,造成 RSS 短时陡增——这不是泄漏,但若你不需要冷启动即满载,可关掉:innodb_buffer_pool_load_at_startup = OFF。
哪些操作看似清理实则危险
升级后空间问题常被误判为“数据膨胀”,于是有人直接删文件或盲目 OPTIMIZE TABLE,结果引发连锁故障:
- 直接
rm -f ibtmp1或rm -f *.bin:MySQL 进程还在用这些文件句柄,磁盘空间不释放,还可能崩溃 - 对未关写入的大表执行
OPTIMIZE TABLE:InnoDB 表会重建,锁表时间取决于数据量,线上服务直接卡死 - 没确认
innodb_file_per_table就执行OPTIMIZE:如果为0,表还在共享表空间ibdata1,OPTIMIZE根本不释放磁盘空间 - 在 GTID 模式下用
PURGE TO:语法错误,命令不执行,但你以为删了,其实什么都没动
真正安全的动作只有三类:改配置后重启、用 SQL 命令(PURGE/FLUSH LOGS)触发内部清理、或对明确可停写的小表做 ALTER TABLE ... ALGORITHM=INPLACE。其他所有“手动删文件”“直接清目录”的操作,都该先停掉 MySQL 进程再评估。


















