帮你快速理解、总结文档立即下载
文档中心>云数据库 MySQL>常见问题>性能空间内存>使用 OPTIMIZE TABLE 释放 MySQL 实例的表空间

使用 OPTIMIZE TABLE 释放 MySQL 实例的表空间

最近更新时间:2026-09-04 19:00:31
我的收藏
当 MySQL 表数据量较大时,通过 DELETE 语句清理数据并不会直接释放磁盘空间,仅会将数据库记录或数据页标记为可复用。若需要真正回收表空间并减少磁盘占用,可通过 OPTIMIZE TABLE 实现。

前提条件

仅 InnoDB 和 MyISAM 引擎支持 OPTIMIZE TABLE 语句。
实例剩余磁盘空间必须大于等于需释放表的空间。
说明:
如果实例剩余磁盘空间不足,请务必先 扩容磁盘空间。后续操作完成后,可按需缩容磁盘空间,系统会核算未使用的资源并退费。

注意事项

必须先删除大量数据:如果未先通过 DELETE 删除大量数据,直接执行 OPTIMIZE TABLE 将无法有效降低表空间使用率。
磁盘空间占用的短暂增加:执行 OPTIMIZE TABLE 时,MySQL 会创建一个临时表来存储重组后的数据,这会导致磁盘空间在短时间内增加。操作完成后,临时表会被删除,磁盘空间占用会恢复正常。
释放后表和索引的统计信息可能没变化:MySQL 表统计信息未及时刷新所致。详情可参见 常见问题
性能影响与高峰期风险:在云数据库 MySQL 5.7和8.0中,OPTIMIZE TABLE 使用 Online DDL 方式执行,支持并发 DML 操作。然而,对大表执行该操作可能引发突发的 IO 和 Buffer 资源占用,存在锁表或资源抢占风险,业务高峰期还可能导致实例不可用或监控中断。因此,建议选择业务低峰期执行以避免对正常业务造成影响。
手动终止正在执行的 OPTIMIZE TABLE:在客户端(如 MySQL 命令行或 DMC 的 SQL 窗口)中按 Ctrl + C 只会断开当前客户端连接,不会终止后端正在执行的 OPTIMIZE TABLE 操作。如需终止该操作,需通过另一个数据库连接执行 SHOW PROCESSLIST; 查看线程列表,找到正在执行 OPTIMIZE TABLE 的线程 ID,然后执行 KILL <线程 ID>; 终止该线程。
注意 MySQL 8.0 20221215(包含) 至 MySQL 8.0 20230703(包含)MySQL 表重建操作(ALTER/OPTIMIZE)会导致数据丢失,详情请参考 文档

通过命令行操作

2. 使用 DELETE 语句清理不需要的数据,根据业务实际情况删除即可。
3. 执行 OPTIMIZE TABLE 命令,释放表空间。
OPTIMIZE TABLE <$Database1>.<Table1>,<$Database2>.<Table2>;
说明:
1. <$Database1>与<$Database2>为数据库名,<Table1>与<Table2>为表名。
2. 在 InnoDB 引擎中执行 OPTIMIZE TABLE 语句时,会出现以下提示信息,该信息是正常执行返回的结果,您可忽略信息,确认返回 ok 即可。详情请参见 OPTIMIZE TABLE Statement
Table does not support optimize, doing recreate + analyze instead

常见问题

执行 OPTIMIZE TABLE 后,云数据库 MySQL 磁盘空间没变化?

问题描述

用户执行 DELETE 删除大量数据并运行 OPTIMIZE TABLE 回收表空间后,立即查询 information_schema.tables 中的 DATA_FREE 字段,发现数值未更新,认为磁盘空间未释放,回收操作无效。

问题原因

实际磁盘空间已释放,但因 MySQL 表统计信息未及时刷新所致,执行 OPTIMIZE TABLE 后不会自动更新表和索引的统计信息,导致 information_schema.tables 中的 DATA_FREE 数据仍保留旧值,无法准确反映实际空间使用情况。问题详情,请参见 Bug #117426

解决方案

临时规避方案:强制刷新统计信息
可对已执行 OPTIMIZE TABLE 的表执行命令 ALTER TABLE table_name ENGINE=InnoDB; 强制重建表并更新统计信息,执行后 information_schema.tables 中的 DATA_FREE 会正确显示已释放后的空间。
说明:
注意 MySQL 8.0 20221215(包含) 至 MySQL 8.0 20230703(包含)MySQL 表重建操作(ALTER/OPTIMIZE)会导致数据丢失,详情请参考 文档

执行 DELETE 后云数据库 MySQL 空间未释放如何处理?

在云数据库 MySQL 中,使用 DELETE 语句删除数据时,该命令仅会将记录的位置或数据页标记为可复用,而磁盘文件大小并不会改变,即表空间不会直接回收。这种行为会导致表空间无法直接回收,形成实例存储空间碎片,占用实例存储空间。
需注意,执行前均需确保实例剩余空间充足,避免实例空间打满引起实例锁定
通过命令整理空间碎片:执行 OPTIMIZE TABLEALTER TABLE <table_name> ENGINE=InnoDB; 等 DDL 操作重新组织表数据和索引结构,从而释放碎片空间。

重要

使用原生 DDL 命令,需注意在业务低峰期执行,避免元数据锁阻塞的情况。更多重要说明,请参见 注意事项

TRUNCATE 或 DROP 后云数据库 MySQL 空间未释放如何处理?

在云数据库 MySQL 中,执行 TRUNCATE 或 DROP 操作后,若发现磁盘空间未释放,可按照以下步骤处理:
1. 确认空间释放逻辑
执行 TRUNCATE 或 DROP 后,通过监控指标确认空间是否已释放。通常情况下,被删除表的大小占总实例空间的比例会反映为存储空间使用量、数据文件使用量、存储空间利用率、数据文件空间利用率的下降。
2. 避免依赖过时信息
若通过 information_schema.tables 或控制台(DBbrain > 诊断优化 > 空间分析) 查看表大小,可能会因数据更新延迟导致表空间显示未变化。因此,建议优先以磁盘使用率作为判断依据。
3. 异步删除的影响
若实例开启了 异步删除大表 能力,表文件占用的空间不会立即释放,而是由后台进程逐步清理。此时需等待异步进程完成,磁盘空间才会最终释放。