MySQL显示表状态总是返回Data_free 17825792

当我执行SHOW TABLE STATUS databaseName;

我在所有的表中都得到了Data_free的值为17825792的值:

| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment | | ubqACL | InnoDB | 10 | Compact | 0 | 0 | 16384 | 0 | 16384 | 17825792 | 1 | 2011-08-23 17:45:48 | NULL | NULL | utf8_general_ci | NULL | | Access Control List per a ubqDocs | | ubqAssociacions | InnoDB | 10 | Compact | 1216 | 148 | 180224 | 0 | 262144 | 17825792 | 1246 | 2011-08-23 17:45:48 | NULL | NULL | utf8_general_ci | NULL | | Vincles entre documents | 

数据库引擎是InnoDB。

我想检索这个值来计算碎片和触发优化操作。

Data_free总是以每个表上相同的数字回来的原因很简单:

  • 你没有使用innodb_file_per_table
  • 所有的InnoDB数据都放在这个名为/ var / lib / mysql / ibdata1的大文件中。

只要这两个条件存在, 就永远不会消除分裂 。 任何针对InnoDB表运行OPTIMIZE TABLE的尝试都会使该表的数据和索引连续,但会被引入ibdata1,从而使ibdata1变得更大。

鉴于此,您必须知道ibdata1内部是什么。 里面有四(4)种信息:

  • 表数据页面
  • 表索引页面
  • 表元数据
  • MVCC数据

你必须做四件重要的事情:

  • 转储所有数据库
  • 删除ibdata1
  • 使用innodb_file_per_table重新configurationInnoDB
  • 重新加载转储

这将保留ibdata1中的所有数据和索引,并将它们存储在单独的.ibd文件中。 从那里,您可以对configuration为innodb_file_per_table的InnoDB表运行OPTIMIZE TABLE。 因此,.ibd文件可以单独进行碎片整理。

  • 我最初在2010年10月29日在StackOverflow中写道
  • 我也写了关于这个2011年2月4日在ServerFault
  • 并在2011年3月11日在ServerFault

这将使ibdata1尽可能小,永远不会再疯狂地失控。 InnoDB碎片整理的所有担心只是一个优化表。

– 应该指出的是,INNODB表上的OPTIMIZE TABLE与使用其他存储引擎有点不同。 Percona有一篇关于提高OPTIMIZE TABLE速度的好文章,当你应该/不应该考虑在这里执行这个动作。

“对于InnoDB表,OPTIMIZE TABLE被映射到ALTER TABLE,它重build表来更新索引统计信息并释放聚集索引中的未使用空间。

更多关于'OPTIMIZE TABLE'的信息