为什么所有的MySQL InnoDB表都是分片的?

出于某种原因,当我运行mysqltuner时,MySQL服务器中的所有InnoDB表都被列为碎片。 我只在几个小时前(在OSX Lion上)安装了服务器,并且从batch file中导入了一堆新的数据。

我试图将一个数据库中的所有表格转换为MYISAM,并且确实足够的碎片表的数量下降了。 奇怪的是,只要我把这些表格转换回InnoDB,零散的表格数量又一次反弹回来。 这与我迄今为止的研究相反,这表明运行ALTER TABLE table_name ENGINE=INNODB; 应该修复碎片。

谷歌search后,我跑了一下:

 SELECT table_schema, table_name, data_free/1024/1024 AS data_free_MB FROM information_schema.tables WHERE engine LIKE 'InnoDB' AND data_free > 0 

哪个应该列出所有碎片表(它确实返回相同数量的结果作为碎片表计数mysqltuner输出)。 data_free_MB列中的每个条目都具有完全相同的编号(当前为7.00000000)。

这实际上是一个真正的问题或mysqltuner做错了什么? 如果是问题,我该如何解决?

编辑

我变得越来越可疑,我是一个白痴,7MB碎片是整个文件,而不是每个表。 任何人都可以证实,如果是这样的话?

根据我上面的评论,并非来自sqltuner的所有输出都表示错误。 除非脚本非常清楚地表明这是一个问题,通常在下一行,然后是修复build议,那么这只是一个信息性的项目。

当你启用了innodb_file_per_table时 ,你所做的只是设置一个协议,以便在外部的.ibd文件中创build任何新的InnoDB表。 在此之前创build的所有InnoDB表仍然embedded在ibdata1中。

随着innodb_file_per_table禁用,任何时候你运行

 ALTER TABLE table_name ENGINE=INNODB; 

它所做的只是将表的数据和索引页追加到ibdata1。 这将使表格存在于连续的页面中,并消除碎片。缺点是ibdata1快速增长。

build议

您将需要导出所有数据,删除ibdata1,ib_logfile0,ib_logfile1,然后重新加载。

我写了如何以及为什么要这样做

  • Oct 29, 2010Howto:清理MySQL InnoDB存储引擎?
  • Jul 05, 2012移动ibdata1,设置innodb_data_file_path

美国东部时间2012-08-15 12:05

你可能想看看mysqltuner.pl脚本本身。 恕我直言,我认为这是使用旧的公式来衡量碎片。 确保你有最新版本的mysqltuner。

至于测量外部存储的InnoDB表的碎片, 我在2012年4月11日写了一篇关于这个表的post(见2012年4月19日底部的更新)