由于某种原因,当我运行 mysqltuner 时,我的 MySQL 服务器中的所有 InnoDB 表都被列为碎片。我几个小时前才安装了服务器(在 OSX Lion 上),它里面有一堆从批处理文件导入的新数据。
我尝试将一个数据库中的所有表都转换为 MYISAM,果然碎片表的数量减少了。但奇怪的是,当我将这些表转换回 InnoDB 时,碎片表的数量又迅速增加。这与我迄今为止的研究相反,我的研究表明运行ALTER TABLE table_name ENGINE=INNODB;
应该可以解决碎片问题。
经过一番谷歌搜索后,我运行了:
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 碎片是针对整个文件的,而不是针对每个表的。有人能确认情况是否如此吗?
答案1
正如我上面的评论,并非所有来自 sqltuner 的输出都表明存在错误。除非脚本非常清楚地指出这是一个问题(通常在下一行),然后是补救建议,否则它只是一个信息项。
答案2
当您启用表 1. innodb_file_per_table,您所做的只是设置一个协议,使任何新的 InnoDB 表都在外部.ibd
文件中创建。您在此之前创建的所有 InnoDB 表仍嵌入在 ibdata1 中。
禁用 innodb_file_per_table 后,每次运行
ALTER TABLE table_name ENGINE=INNODB;
它所做的只是将表的数据和索引页附加到 ibdata1。这将使表存在于连续的页面中并消除碎片,缺点是 ibdata1 增长很快。
推荐
您将需要导出所有数据,删除 ibdata1、ib_logfile0、ib_logfile1,然后重新加载。
我写了如何以及为什么这样做
Oct 29, 2010
:如何:清理 mysql InnoDB 存储引擎?Jul 05, 2012
:移动 ibdata1,设置 innodb_data_file_path
更新时间:2012-08-15 12:05 EDT
您可能需要查看 mysqltuner.pl 脚本本身。恕我直言,我认为它使用了一种旧的公式来测量碎片。确保您拥有最新版本的 mysqltuner。
至于测量外部存储的 InnoDB 表的碎片,我于 2012 年 4 月 11 日写了一篇关于该问题的文章(请参阅底部 2012 年 4 月 19 日的更新)