当进行多个连接时,MySQL不正确的tmp表的密钥文件
我不是经常来这里寻求帮助,但是我很沮丧,我希望以前有人遇到过。
每当我尝试使用多个连接从表中获取logging,我得到这个错误:
#126 - Incorrect key file for table '/tmp/#sql_64d_0.MYI'; try to repair it
所以这个查询会产生错误:
SELECT * FROM `core_username` INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`) INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`) ORDER BY `core_username`.`name` ASC LIMIT 1
但是这个不会:
SELECT * FROM `core_username` INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`) ORDER BY `core_username`.`name` ASC LIMIT 1
而这个也不是:
SELECT * FROM `core_username` INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`) ORDER BY `core_username`.`name` ASC LIMIT 1
什么可能导致这个? 我真的不知道如何去修复一个tmp表,但是我不认为这是个问题,因为它每次都是一个新的tmp表。 用户名表格相当大(现在有233,718条logging),但是我怀疑这跟它有什么关系。
任何帮助将非常感激。
更新 :经过一些进一步的testing,似乎错误只发生在我尝试命令结果时。 也就是说,这个查询会给我所期望的:
SELECT * FROM `core_username` INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`) INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`) LIMIT 1
但是,如果我添加:
ORDER BY `core_username`.`name` ASC
错误被触发。 这只发生在我目前使用的特定networking服务器上。 如果我下载数据库,并在我的本地主机以及其他服务器上尝试相同的事情,它运行良好。 MySQL版本是5.0.77。
知道这一点,我相当确信发生的事情是,正在创build的tmp表格太大了,MySQL扼stream器正如本文所述 。 我仍然不确定解决scheme是什么,虽然…
有时当临时表发生这个错误时:
#126 - Incorrect key file for table '/tmp/#sql_64d_0.MYI'; try to repair it
这可能是因为/tmp
文件夹空间不足。 在一些Linux安装中, /tmp
位于自己的分区中,没有太多空间 – 大的MySQL查询将会填满它。
您可以使用df -h
来检查\tmp
是否在自己的分区中,以及分配了多less空间。
如果它在自己的分区和空间不足,您可以:
(a)修改/ tmp,使其分区有更多的空间(通过重新分配或移动到主分区 – 例如在这里看到 )
(b)更改MySqlconfiguration,以便在不同的分区上使用不同的临时文件夹 ,例如/var/tmp
在运行查询时检查你的MySQL tmpdir可用空间(在你的情况下是/ tmp),因为在处理大表时可能会消耗数百MB的空间。 像这样的东西对我有用:
$ while true; do df -h /tmp; sleep .5; done
运行这个
REPAIR TABLE `core_username`,`core_site`,`core_person`;
或者这样做:
select * from ( SELECT * FROM `core_username` INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`) INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`) LIMIT 1) ORDER BY `name` ASC
我有一个具有500K +logging的表上的查询的这个问题。 它给了我相同的确切types的错误,指向/ tmp目录中的一个.MYI文件,这个文件在检查时很less出现。 我已经增加了/etc/my.cnf文件中的堆和临时文件大小。
查询的问题在于最后确实包含了一个ORDER子句,省略了这个查询使查询无误地工作。 它也有一个限制。 我试图看看表中最近的5条logging。 随着ORDER条款包括它呛,并给出了错误。
发生了什么事是mysqld创build一个内部临时表与巨大的表中的所有logging来应用ORDER。
我解决这个问题的方法是应用一个额外的WHERE条件,将巨型表中的logging限制在一些较小的集合中。 我很方便地有一个date时间字段做过滤。
我希望能帮助别人。
你可能会发现运行“ANALYZE TABLE”有帮助。
这个问题突然出现在一个大表(〜100M行)上,MySQL试图用/ tmp写一个超过1GB的临时表,因为/ tmp被限制在600M左右。
事实certificate,InnoDB表的统计数据相当陈旧。 运行“ANALYZE TABLE …”后,统计信息被更新并清除问题。 通过更准确的统计数据,MySQL能够正确地优化查询,并且不再需要大的tmp文件。
我们现在定期运行“mysqlcheck -Aa”以保持所有表格统计数据的新鲜度。
在Unix上,MySQL使用TMPDIR环境variables的值作为存储临时文件的目录的path名。 如果没有设置TMPDIR,则MySQL使用系统默认值,通常为/ tmp,/ var / tmp或/ usr / tmp。
在Windows,Netware和OS2上,MySQL依次检查TMPDIR,TEMP和TMP环境variables的值。 对于第一个被发现的设置,MySQL使用它并且不检查剩下的。 如果没有设置TMPDIR,TEMP或TMP,则MySQL使用Windows系统默认值,通常为C:\ windows \ temp。
如果包含临时文件目录的文件系统太小,则可以使用mysqld的–tmpdir选项指定文件系统中有足够空间的目录 。
在MySQL 5.0中,可以将–tmpdir选项设置为以循环方式使用的多个path的列表。 path在Unix上应该用冒号(“:”)分隔,在Windows,NetWare和OS / 2上应该用分号(“;”)分隔。
我遇到同样的问题。
这是我的解决scheme:1.不要使用“select*”。 只需select你需要的字段。 2.拆分查询。 如果您select的字段太多,将其分割为某个查询可能会导致结果。 如果您希望包含结果的variables未被更改,则可以稍后“array_merge()”结果。
在我的情况下,我将查询拆分为5个查询,然后使用PHP对数组进行合并。
问题在于mysql服务器上。 这只是一个应用程序开发人员(我们这样)没有特权。
我有类似的问题。 在我自己的情况下,由于所有者/许可不正确而出现问题。 我只需要更改我的数据目录的所有者到MySQL用户,这解决了这个问题。
只增加文件tmp,因为mysql没有空间,查询…
mount -o remount,size=[NEW MAX SIZE HERE] tmpfs /tmp
链接参考:
一般错误:126表'/tmp/#sql_254c_0.MYI'的密钥文件不正确; 尝试修复它
[错误] / usr / sbin / mysqld:表'/mysqltmp/#sql_ca1a_0.MYI'的密钥文件不正确; 尝试修复它
如何增加/ tmp分区大小
3个表格之一的索引键可能不好,请尝试在所有3个表格上运行修复命令。
使用EXPLAIN关键字可能有助于了解如何最佳地优化此查询。 本质上,你需要做的是尽可能快地得到尽可能小的结果集。 如果你有一个core_username中的每一行结果集,直到结束,当你命令它时,你冒着…这个风险。
如果您可以单独对core_username进行sorting而不出现问题,则可能需要将min()行作为子查询。