我不经常来这里寻求帮助,但我对此感到非常沮丧,我希望有人以前遇到过这种情况。
每当我尝试使用多个连接从表中获取记录时,我都会收到此错误:
#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
则会触发错误。这仅发生在我当前使用的特定网络服务器上。如果我下载数据库并在本地主机和其他服务器上尝试相同的操作,它运行良好。 MySQL版本是5.0.77。
知道这一点后,我相当有信心正在发生的事情是正在创建的 tmp 表太大并且 MySQL 阻塞 如本博文中所述。我仍然不确定解决方案是什么,但......
I don't come here for help often but I am pretty frustrated by this and I am hoping someone has encountered it before.
Whenever I try to fetch records from a table using more than one join I get this error:
#126 - Incorrect key file for table '/tmp/#sql_64d_0.MYI'; try to repair it
So this query will produce the error:
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
But this one won't:
SELECT * FROM `core_username`
INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`)
ORDER BY `core_username`.`name` ASC LIMIT 1
And neither will this one:
SELECT * FROM `core_username`
INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`)
ORDER BY `core_username`.`name` ASC LIMIT 1
What could be causing this? I don't really know how to go about repairing a tmp table but I don't really think that's the problem as it is a new tmp table every time. The username table is fairly large (233,718 records right now) but I doubt that has anything to do with it.
Any help would be much appreciated.
UPDATE: After some further testing, it appears that the error only happens when I try to order the results. That is, this query will give me what I expect:
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
But if I add the:
ORDER BY `core_username`.`name` ASC
The error is triggered. This is only happening on the specific webserver I am currently using. If I download the database and try the same thing on my localhost as well as other servers it runs fine. The MySQL version is 5.0.77.
Knowing this I am fairly confident that what is happening is that the tmp table being created is way too big and MySQL chokes as described in this blog post. I am still not sure what the solution would be, though...
发布评论
评论(11)
有时,当临时表发生此错误时:
可能是因为
/tmp
文件夹空间不足。在某些 Linux 安装上,/tmp
位于其自己的分区中,并且没有太多空间 - 大的 MySQL 查询会填满它。您可以使用
df -h
来检查\tmp
是否在自己的分区中,以及为其分配了多少空间。如果它在自己的分区中并且空间不足,您可以:
(a) 修改 /tmp 以便其分区有更多空间(通过重新分配或将其移动到主分区 - 例如 参见此处)
(b) 更改 MySql 配置,使其使用 不同的临时文件夹< /a> 位于不同的分区,例如
/var/tmp
Sometimes when this error happens with temp tables:
It can be because the
/tmp
folder is running out of space. On some Linux installations,/tmp
is in its own partition and does not have much space - big MySQL queries will fill it up.You can use
df -h
to check whether\tmp
is in its own partition, and how much space is allocated to it.If it is in its own partition and short of space, you can either:
(a) modify /tmp so that its parition has more space (either by reallocating or moving it to the main partition - e.g. see here)
(b) changing MySql config so that it uses a different temp folder on a different partition, e.g.
/var/tmp
运行查询时检查 MySQL tmpdir 可用空间(在您的情况下为 /tmp),因为在处理大表时它可能会占用数百 MB。这样的事情对我有用:
Check your MySQL tmpdir available space (/tmp in your case) while running the queries as it can eat hundreds of MBs when working with big tables. Something like this worked for me:
运行这个
或执行以下操作:
run this
or do this:
您可能会发现运行“ANALYZE TABLE”有帮助。
我们在一个大表(~100M行)上突然出现这个问题,MySQL尝试使用/tmp写入超过1GB的临时表,但由于/tmp限制为~600M而失败。
事实证明,InnoDB 表的统计信息相当陈旧。运行“ANALYZE TABLE ...”后,统计数据已更新,问题已解决。有了更准确的统计数据,MySQL 能够正确优化查询,不再需要大的 tmp 文件。
我们现在定期运行“mysqlcheck -Aa”以保持所有表统计信息最新。
You may find running "ANALYZE TABLE " helps.
We had this problem suddenly appear on a large table (~100M rows) and MySQL tried to use /tmp to write a temporary table of over 1GB, which failed as /tmp was limited to ~600M.
It turned out that the statistics for the InnoDB table were rather stale. After running "ANALYZE TABLE ...", the statistics were updated and the problem cleared. With the more accurate statistics, MySQL was able to optimize the query correctly and the large tmp file was no longer required.
We now run "mysqlcheck -Aa" periodically to keep all table statistics fresh.
我在对包含 500K+ 条记录的表进行查询时遇到了这个问题。
它给了我同样类型的错误,指向 /tmp 目录中的 .MYI 文件,但在检查时很少出现该文件。我已经增加了 /etc/my.cnf 文件中的堆和临时文件大小。
该查询的问题是它确实在末尾包含一个 ORDER 子句,省略它会使查询正常工作而不会出现错误。它也有一个限制。我试图查看表中最近的 5 条记录。当包含 ORDER 子句时,它会卡住并给出错误。
发生的情况是 mysqld 正在创建一个内部临时表,其中包含巨型表中的所有记录来应用订单。
我解决这个问题的方法是应用一个额外的 WHERE 条件,将巨型表中的记录限制为一些较小的集合。我方便地有一个日期时间字段来进行过滤。
我希望这对某人有帮助。
I had this problem with a query on a table that had 500K+ records.
It was giving me the same exact type of error, pointing to a .MYI file in the /tmp directory that was rarely there upon checking. I had already increased the heap and temp file sizes in the /etc/my.cnf file.
The problem with the query was the it did indeed contain a ORDER clause at the end, omitting it made the query work without error. It also had a LIMIT. I was trying to look at the most recent 5 records in the table. With the ORDER clause included it choked and gave the error.
What was happening was the mysqld was creating an internal temp table with ALL the records from the giant table to apply the ORDER.
The way that I got around this is to apply an additional WHERE condition, limiting the records from the giant table to some smaller set. I conveniently had a datetime field to do the filtering from.
I hope that helps someone.
在 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 上,路径应以分号 (“;”) 分隔。
On Unix, MySQL uses the value of the TMPDIR environment variable as the path name of the directory in which to store temporary files. If TMPDIR is not set, MySQL uses the system default, which is usually /tmp, /var/tmp, or /usr/tmp.
On Windows, Netware and OS2, MySQL checks in order the values of the TMPDIR, TEMP, and TMP environment variables. For the first one found to be set, MySQL uses it and does not check those remaining. If none of TMPDIR, TEMP, or TMP are set, MySQL uses the Windows system default, which is usually C:\windows\temp.
If the file system containing your temporary file directory is too small, you can use the --tmpdir option to mysqld to specify a directory in a file system where you have enough space.
In MySQL 5.0, the --tmpdir option can be set to a list of several paths that are used in round-robin fashion. Paths should be separated by colon characters (“:”) on Unix and semicolon characters (“;”) on Windows, NetWare, and OS/2.
我遇到同样的问题。
这是我的解决方案:
1. 不要使用“选择*”。只需选择您需要的字段。
2. 拆分查询。如果您选择的字段太多,则将其拆分为某个查询可能会是一个结果。如果您希望包含结果的变量不发生更改,您可以稍后使用“array_merge()”结果。
就我而言,我将查询拆分为 5 个查询,然后使用 PHP 对其进行数组合并。
问题出在mysql服务器上。这只是应用程序开发人员(例如我们)没有特权。
I experience the same problem.
Here is my solution :
1. Dont use "select *". Just select field that you need.
2. Split the query. If the field you select is too much, splitting it to some query can be a result. You can "array_merge()" the result later if you want the variable that contain the result not changed.
On my case, I split the query to 5 queries, then array merge it using PHP.
The problem is lies on the mysql server. It is just a thing that application developer (such us me) don't has a previlege.
只增加文件tmp,因为mysql没有空间,用于查询...
链接参考:
一般错误:126 表 '/tmp/#sql_254c_0.MYI' 的密钥文件不正确;尝试修复它
[错误] /usr/sbin/mysqld: 表 '/mysqltmp/#sql_ca1a_0.MYI' 的密钥文件不正确;尝试修复它
如何增加 /tmp 分区大小
Only increase the file tmp, because mysql doesn't have space in it, for queries...
Links reference:
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
How to increase /tmp partition size
我有类似的问题。就我自己而言,问题是由于不正确的所有者/权限而发生的。我只需将数据目录的所有者更改为 mysql 用户即可解决问题。
I had similar problem. In my own case, the problem occurred due to incorrect owner/permission. I just had to change the owner on my data directory to mysql user and this resolved the problem.
3 个表之一的索引键可能损坏,请尝试对所有 3 个表运行修复命令。
the index keys for one of the 3 tables might be bad, try running a repair command on all 3 tables.
使用 EXPLAIN 关键字可能有助于找出如何最好地优化此查询。本质上,您需要做的是尽快获得尽可能小的结果集。如果您在 core_username 中的每一行直到最后都有一个结果集,那么当您订购它时,您将面临...这个风险。
如果您可以单独对 core_username 进行排序而不会出现问题,则您可能希望将 min() 行作为子查询获取。
Using the EXPLAIN keyword may help find out how to best optimize this query. Essentially, what you need to do is get the result set as small as possible as quickly as possible. If you have a result set of every row in core_username until the end, when you order it you run the risk of... this.
If you can do the ordering on core_username alone without a problem, you may want to get the min() row as a subquery.