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


10

由于某些原因,当我运行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的碎片是针对整个文件的,而不是针对每个表的。任何人都可以确认是否会这样吗?


您真的认为7个免费MB是个问题吗?
大卫·史瓦兹

@DavidSchwartz这不是一个线索,这就是为什么我问;)有2314个表,每个表有7MB的可用空间,我不知道这意味着什么。我不确定为什么mysqltuner不会显示这个数字,如果它不是引起关注的潜在原因。我希望这里的某人能够告诉我如何考虑数字,以及如何解决问题,因为“标准”方法不起作用
Clive

根据用户请求在标记中迁移此问题。
Daniel Beck

mysqltuner显示的大多数详细信息仅供参考。并非一切都是问题。如果有问题,请明确指出。是否表示存在问题?
约翰·加迪尼尔

@JohnGardeniers我相信,消息是:[!!] Total fragmented tables: 2314,我非常确定这表示一个问题(带有红色的双感叹号)
Clive 2012年

Answers:


5

根据我上面的评论,并非sqltuner的所有输出都指示错误。除非脚本非常清楚地指出这是一个问题,通常在下一行,然后是有关修复的建议,否则它仅是一个参考项目。


3

启用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,然后重新装入。

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

更新2012-08-15 12:05 EDT

您可能需要研究mysqltuner.pl脚本本身。恕我直言,我认为它使用了一个旧的公式来测量碎片。确保您具有最新版本的mysqltuner。

至于衡量外部存储的InnoDB表的碎片,我在2012年4月11日写了一篇有关该碎片的文章(请参阅底部的2012年4月19日更新)


1
好的,谢谢,现在事情变得更有意义了。我最终导出了数据,完全擦除了MySQL,然后重新安装(但innodb_file_per_table在启动服务器并重新导入之前将其添加到conf文件中)。在此之前,我遇到了各种各样的InnoDB错误(非常糟糕的错误……这意味着我必须innodb_force_recovery在6级运行才能获取数据!),各种各样的“日志文件日期都在未来!' 错误。那些似乎已经停止了,但是我仍然有一些零散的表。我会继续关注,再次感谢您的投入
克莱夫(Clive)

太棒了!这是非常有用的。谢谢@RolandoMySQLDBA!
Sudhi 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.