我不经常来这里寻求帮助,但我对此感到非常沮丧,我希望以前有人遇到过它。
每当我尝试使用多个连接从表中获取记录时,我都会收到此错误:
#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条记录),但我怀疑它与它有什么关系。
非常感谢任何帮助。
更新:经过一些进一步测试后,似乎只有在我尝试订购结果时才会出现错误。也就是说,这个查询会给我我的期望:
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
触发错误。这只发生在我目前使用的特定网络服务器上。如果我下载数据库并在我的localhost以及其他服务器上尝试相同的操作,它运行正常。 MySQL版本是5.0.77。
知道这一点我相信发生的事情是创建的tmp表太大而MySQL扼杀了as described in this blog post。我仍然不确定解决方案是什么,但是......
答案 0 :(得分:101)
有时当临时表发生此错误时:
#126 - Incorrect key file for table '/tmp/#sql_64d_0.MYI'; try to repair it
可能是因为/tmp
文件夹空间不足。在某些Linux安装中,/tmp
位于其自己的分区中并且没有太多空间 - 大的MySQL查询将填满它。
您可以使用df -h
检查\tmp
是否在自己的分区中,以及分配了多少空间。
如果它在自己的分区中且空间不足,您可以:
(a)修改/ tmp,使其分区有更多空间(通过重新分配或移动到主分区 - 例如see here)
(b)更改MySql配置,以便它在不同的分区上使用different temp folder,例如/var/tmp
答案 1 :(得分:20)
在运行查询时检查你的MySQL tmpdir可用空间(在你的情况下为/ tmp),因为在使用大表时可能会吃掉数百MB。这样的事情对我有用:
$ while true; do df -h /tmp; sleep .5; done
答案 2 :(得分:6)
运行此
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
答案 3 :(得分:4)
您可能会发现正在运行“ANALYZE TABLE”帮助。
我们遇到这个问题突然出现在一个大表(~100M行)上,MySQL试图使用/ tmp写一个超过1GB的临时表,由于/ tmp被限制在~600M左右而失败。
事实证明,InnoDB表的统计数据相当陈旧。运行“ANALYZE TABLE ...”后,统计信息已更新,问题已清除。通过更准确的统计数据,MySQL能够正确优化查询,并且不再需要大型tmp文件。
我们现在定期运行“mysqlcheck -Aa”以保持所有表统计信息的新鲜度。
答案 4 :(得分:3)
我在一个有500K +记录的表上查询时遇到了这个问题。 它给了我相同的确切类型的错误,指向/ tmp目录中的.MYI文件,该文件很少在检查时出现。我已经在/etc/my.cnf文件中增加了堆和临时文件大小。
查询的问题是它确实在最后包含了一个ORDER子句,省略它使查询正常工作而没有错误。它也有一个限制。我试图查看表中最近的5条记录。包含ORDER子句后,它会被阻塞并给出错误。
正在发生的事情是mysqld正在创建一个内部临时表,其中包含来自巨型表的所有记录以应用ORDER。
我解决这个问题的方法是应用一个额外的WHERE条件,将巨型表中的记录限制为一些较小的集合。我方便地有一个日期时间字段来进行过滤。
我希望能有所帮助。
答案 5 :(得分:2)
在Unix上,MySQL使用TMPDIR环境变量的值作为存储临时文件的目录的路径名。如果未设置TMPDIR,MySQL将使用系统默认值,通常为/ tmp,/ var / tmp或/ usr / tmp。
在Windows,Netware和OS2上,MySQL按顺序检查TMPDIR,TEMP和TMP环境变量的值。对于第一个发现设置,MySQL使用它并不检查剩余的。如果没有设置TMPDIR,TEMP或TMP,则MySQL使用Windows系统默认值,通常为C:\ windows \ temp。
如果包含临时文件目录的文件系统太小,可以使用mysqld的--tmpdir选项指定文件系统中有足够空间的目录。
在MySQL 5.0中, - tmpdir选项可以设置为以循环方式使用的多个路径的列表。路径应该用Unix上的冒号字符(“:”)和Windows,NetWare和OS / 2上的分号字符(“;”)分隔。
答案 6 :(得分:1)
我遇到了同样的问题。
这是我的解决方案: 1.不要使用“选择*”。只需选择您需要的字段即可。 2.拆分查询。如果您选择的字段太多,则可能会将其拆分为某个查询。如果希望包含结果的变量未更改,则可以稍后“array_merge()”结果。
就我而言,我将查询拆分为5个查询,然后使用PHP将数组合并。
问题在于mysql服务器。应用程序开发人员(比如我们)没有普遍性,这只是一件事。
答案 7 :(得分:0)
我有类似的问题。在我自己的情况下,问题是由于不正确的所有者/权限。我只需要将我的数据目录中的所有者更改为mysql用户,这就解决了这个问题。
答案 8 :(得分:0)
只增加文件tmp,因为mysql中没有空格,用于查询......
mount -o remount,size=[NEW MAX SIZE HERE] tmpfs /tmp
链接参考:
General error: 126 Incorrect key file for table ‘/tmp/#sql_254c_0.MYI’; try to repair it
[ERROR] /usr/sbin/mysqld: Incorrect key file for table '/mysqltmp/#sql_ca1a_0.MYI'; try to repair it
答案 9 :(得分:-1)
3个表中某个表的索引键可能不好,请尝试在所有3个表上运行修复命令。
答案 10 :(得分:-1)
使用EXPLAIN关键字有助于了解如何最佳地优化此查询。基本上,您需要做的是尽可能快地将结果集尽可能小。如果你有一个core_username中每一行的结果集,直到最后,当你订购它时,你冒着......这个风险。
如果你可以单独对core_username进行排序而没有问题,你可能希望将min()行作为子查询。