磁盘占用翻倍主因是mysql 8.0默认启用独立undo表空间(如undo_001)且innodb_undo_log_truncate=off,导致undo日志只增不减;同时redo log文件被重建为更大尺寸(如128mb→256mb),且binlog和临时表未清理。

磁盘占用翻倍,八成是 undo_001 和 ib_logfile* 在 quietly 吃空间——不是数据变多了,是 MySQL 8.0 默认启用新日志机制,但升级时没做适配。
undo 表空间自动创建且不收缩
MySQL 5.7 的 undo 日志全塞在 ibdata1 里;8.0 默认改用独立 undo 表空间(如 undo_001、undo_002),每个默认 128MB,一启就占 256MB。更关键的是:innodb_undo_log_truncate 默认为 OFF,意味着旧 undo 段永不回收,文件只增不减。
- 执行
SHOW VARIABLES LIKE 'innodb_undo_log_truncate';确认是否为ON - 若为
OFF,立即执行SET GLOBAL innodb_undo_log_truncate = ON; - 注意:即使设为
ON,undo_001文件体积也不会缩小——它只会复用空闲段,du -sh undo_001显示大小不变是正常现象 - 持续增长?查长事务:
SELECT * FROM information_schema.INNODB_TRX WHERE TIME_TO_SEC(TIMEDIFF(NOW(), TRX_STARTED)) > 300;
redo log 文件被重建为更大尺寸
MySQL 8.0 对 innodb_log_file_size 的默认值上调(常见从 48MB → 128MB 或 256MB),而升级过程不会自动缩容旧日志。结果就是:配置里写的是 128M,但磁盘上残留着 256M 的 ib_logfile0 和 ib_logfile1,重启时 MySQL 拒绝启动并报错 InnoDB: Error: log file ib_logfile0 is of different size。
- 检查实际文件大小:
ls -lh /var/lib/mysql/ib_logfile* - 比对配置:
SHOW VARIABLES LIKE 'innodb_log_file_size'; - 安全缩容必须分步:先在
my.cnf中设好目标值(如innodb_log_file_size = 128M),再停库 → 手动删掉ib_logfile*→ 启动,MySQL 自动重建 - 务必提前执行
SET GLOBAL innodb_fast_shutdown = 0;,否则 crash recovery 可能失败
临时表和 binlog 没清理,悄悄撑爆磁盘
升级后 tmp_table_size 参数已失效,但旧配置若还留在 my.cnf 里,会让人误以为“调了没用”。真实控制内存临时表的是 max_heap_table_size 和 internal_tmp_mem_storage_engine;同时,binlog 若未设过期策略,也会持续累积。
-
SHOW VARIABLES LIKE 'internal_tmp%';查当前引擎和限制 - 看落盘比例:
Created_tmp_disk_tables / Created_tmp_tables> 5% 就该干预 -
SHOW BINARY LOGS;查 binlog 总量;确认binlog_expire_logs_seconds是否合理(如设为 2592000 表示 30 天) - 临时目录若和
datadir相同(SHOW VARIABLES LIKE 'tmpdir';),大查询生成的磁盘临时表会直接写进数据目录
最易被忽略的一点:所有这些膨胀都不是孤立发生的。比如 undo 持续增长 + redo 文件重建 + binlog 不清理,三者叠加可能让磁盘在一周内多占 10GB 以上,而你只盯着某一张表的 Data_free 值看——那根本不是主因。











