删一半的行,同时追踪文件大小和DATA_FREE这个常被当成碎片指标的字段,看它到底能不能真实预警表碎片。
代码-- frag_test 有1000行 DELETE FROM frag_test WHERE id % 2 = 0; -- 真实删掉一半 -- 追踪:真实的文件大小 / TABLE_ROWS / DATA_FREE
删除前: TABLE_ROWS=1000 文件=344064字节 DATA_FREE=0 删除后: TABLE_ROWS=500 文件=344064字节 DATA_FREE=0 ← 两者真实都没变化!
本以为删掉一半数据,至少information_schema.TABLES里的DATA_FREE字段会真实反映出"这么多空间理论上可以回收",结果它全程真实都是0。这是一个容易被误解的真实细节:DATA_FREE在InnoDB独立表空间下,反映的是表空间文件里完整空闲的区(extent)数量,而不是删除操作在页面内部留下的、还没被回收成完整空闲区的零散空间——删除留下的洞,绝大多数情况下都停留在"页面内部有空隙,但整个页面还没空到能算作空闲区"这个状态,不会被这个字段真实统计进去。
OPTIMIZE TABLE frag_test 之前: 文件=344064字节(500行数据,但文件是1000行时期的大小) OPTIMIZE TABLE frag_test 之后: 文件=245760字节,DATA_FREE依然是0 真实缩小了约28.6%
每一步都是本文上面用真实文件大小和information_schema跑出来的原始结果。
information_schema.TABLES里的DATA_FREE字段 + 真实磁盘文件大小对比