不能。TRUNCATE PARTITION 仅逻辑清空分区数据页,不释放磁盘空间;需通过 REORGANIZE PARTITION、OPTIMIZE TABLE(整表重建)或 ENGINE=InnoDB 强制重建才能真正回收空间。
TRUNCATE PARTITION 能直接释放空间吗?
不能。mysql 8.0+ 的 truncate partition 只是逻辑清空该分区的数据页,但不会立即归还磁盘空间给操作系统——它仍被 innodb 表空间文件(如 ibdata1 或独立表空间 .ibd)持有,除非后续触发收缩操作。
为什么 TRUNCATE PARTITION 后磁盘占用没变?
- InnoDB 默认不自动收缩数据文件;
TRUNCATE PARTITION 仅复位该分区的内部指针、删除索引项、重置 AUTO_INCREMENT,但物理页未擦除或返还
- 若分区在共享表空间(
innodb_file_per_table=OFF),空间根本无法单独回收
- 即使启用了
innodb_file_per_table=ON,单个分区的 .ibd 文件也不支持“局部 shrink”,整个表空间文件才可重建
真正释放空间的实操路径
TRUNCATE PARTITION 仅复位该分区的内部指针、删除索引项、重置 AUTO_INCREMENT,但物理页未擦除或返还innodb_file_per_table=OFF),空间根本无法单独回收innodb_file_per_table=ON,单个分区的 .ibd 文件也不支持“局部 shrink”,整个表空间文件才可重建必须重建包含目标分区的表空间。安全且常用的做法是:用 ALTER TABLE ... REORGANIZE PARTITION 拆出目标分区 → 清空 → 再合并回去,强制生成新文件。
- 先确认分区名:
SELECT PARTITION_NAME FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 'your_table' AND TABLE_SCHEMA = 'your_db'; - 执行重组(以 RANGE 分区为例):
ALTER TABLE your_table REORGANIZE PARTITION p2 INTO (PARTITION p2 VALUES LESS THAN (100), PARTITION p3 VALUES LESS THAN MAXVALUE);
—— 这会重建p2对应的物理段 - 更稳妥的做法是:导出其余分区 +
TRUNCATE PARTITION p2+OPTIMIZE TABLE your_table(仅当innodb_file_per_table=ON且整表为独立表空间时有效) - 注意:
OPTIMIZE TABLE在 MySQL 8.0+ 对已分区表会重建整个表,不是只处理一个分区
容易踩的坑
- 误用
DROP PARTITION:它会删分区定义和数据,且无法恢复(不像 TRUNCATE 可回滚到事务点)
- 在从库上执行前没检查复制过滤规则——某些
REORGANIZE 语句可能被过滤或引发不一致
- 没预留足够磁盘空间:重建过程会临时占用等量新空间,尤其大分区易触发
ERROR 1114 (HY000): The table is full
- 忽略分区表达式依赖:比如按
TO_DAYS(created_at) 分区,TRUNCATE PARTITION 后插入旧日期可能进错分区
DROP PARTITION:它会删分区定义和数据,且无法恢复(不像 TRUNCATE 可回滚到事务点)REORGANIZE 语句可能被过滤或引发不一致ERROR 1114 (HY000): The table is full
TO_DAYS(created_at) 分区,TRUNCATE PARTITION 后插入旧日期可能进错分区分区空间回收从来不是“删数据就释放”,本质是文件级操作。最省事的方案往往是最暴力的:备份其余分区、TRUNCATE PARTITION、再 ALTER TABLE ... ENGINE=InnoDB 强制重建——但得停写、占空间、耗时间。选哪个,取决于你手里的停机窗口和磁盘余量。










