《100个“反常识”经验11:删了30万行数据表还是那么大?》
本期摘要你用DELETE删了30万行数据df -h一看磁盘空间没变表文件还是那么大。这不是Bug是InnoDB存储引擎的设计特性DELETE只标记删除不释放磁盘空间留下的位置叫“空洞”。真正释放空间需要执行OPTIMIZE TABLE或ALTER TABLE ENGINEInnoDB。本文还提供了检查表碎片的SQL脚本以及大表优化的工具推荐。一次让人困惑的操作业务需要清理半年前的日志数据大概30万行。执行sqlDELETE FROM operation_logs WHERE created_at 2026-01-01;Query OK, 300000 rows affected。再查表大小sqlSELECT table_name, ROUND(((data_length index_length) / 1024 / 1024), 2) AS size_mb FROM information_schema.tables WHERE table_name operation_logs;结果还是2GB和删除前一样。为什么DELETE不释放磁盘空间InnoDB存储引擎中DELETE操作只是把数据行标记为“已删除”并不会真正回收磁盘空间。这些空间称为“空洞”后续INSERT可以复用但文件大小不会缩小。操作行为磁盘空间DELETE标记删除空间留作复用不释放INSERT优先填充空洞不增加文件大小TRUNCATE重建表释放OPTIMIZE整理碎片释放如何真正释放空间方法一OPTIMIZE TABLE推荐sqlOPTIMIZE TABLE operation_logs;原理重建表消除空洞回缩磁盘空间。注意执行期间会锁表建议在业务低峰期操作。方法二ALTER TABLE重建sqlALTER TABLE operation_logs ENGINEInnoDB;效果和OPTIMIZE类似也会重建表。方法三TRUNCATE全删sqlTRUNCATE TABLE operation_logs;删除所有数据并重置表空间彻底释放。仅适用于全表删除。真实案例对比方法执行前表大小执行后表大小锁表耗时DELETE 30万行2GB2GB行锁几秒OPTIMIZE2GB1.2GB全表锁几分钟TRUNCATE2GB0.1MB全表锁瞬间注意事项频繁DELETEINSERT会产生大量空洞定期OPTIMIZE是必要的大表OPTIMIZE耗时较长建议用pt-online-schema-change工具在线操作磁盘空间紧张时不要只靠DELETE记得跟进OPTIMIZE一键检查表碎片脚本sqlSELECT table_name, ROUND(data_length/1024/1024, 2) AS data_mb, ROUND(data_free/1024/1024, 2) AS free_mb, ROUND(data_free/data_length*100, 2) AS free_pct FROM information_schema.tables WHERE table_schema your_database ORDER BY free_pct DESC;free_mb越大碎片越严重建议执行OPTIMIZE。下期预告《100个“反常识”经验12死锁日志怎么看10分钟学会》
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2554765.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!