30

我写了一个查询,它在我的本地服务器上正确运行,它的数据更少,

但是当我在生产服务器上运行它时会出错 - (这有更多大约 6GB 的数据)

Incorrect key file for table '/tmp/#sql_3c51_0.MYI'; try to repair it

这是我的查询

SELECT   
    `j25_virtuemart_products`.`virtuemart_product_id`,
    `product_name`, 
    `product_unit`,
    `product_s_desc`,
    `file_url_thumb`,
    `virtuemart_custom_id`, 
    `custom_value`   
    FROM 
    `j25_virtuemart_product_customfields`,
    `j25_virtuemart_products`,
    `j25_virtuemart_products_en_gb`,
    `j25_virtuemart_product_medias`,
    `j25_virtuemart_medias`     
    WHERE
    (
    `j25_virtuemart_products`.`virtuemart_product_id`=`j25_virtuemart_products_en_gb`.`virtuemart_product_id`
    AND 
    `j25_virtuemart_products`.`virtuemart_product_id`=`j25_virtuemart_product_customfields`.`virtuemart_product_id`)

AND

    `j25_virtuemart_products`.`virtuemart_product_id`=`j25_virtuemart_product_medias`.`virtuemart_product_id`
    AND 
    `j25_virtuemart_product_medias`.`virtuemart_media_id`=`j25_virtuemart_medias`.`virtuemart_media_id`

    GROUP BY `j25_virtuemart_products`.`virtuemart_product_id`

    LIMIT 0, 1000;

任何人都知道如何从该错误中恢复 - 比如 otimize 这个查询或任何其他方式谢谢

4

8 回答 8

58

该问题是由 /tmp 文件夹中的磁盘空间不足引起的。/tmp 卷用于需要创建临时表的查询。即使查询仅使用带有 InnoDB 的表,这些临时表也是 MyISAM 格式。

以下是一些解决方案:

  • 优化查询,使其不会创建临时表(重写查询,将其拆分为多个查询,或添加适当的索引,使用pt-query-digest和分析执行计划EXPLAIN <query>)请参阅Percona 关于临时表的文章
  • 优化 MySQL,使其不会创建临时表(sort_buffer_size、join_buffer_size)。请参阅:https ://dba.stackexchange.com/questions/53201/mysql-creates-temporary-tables-on-disk-how-do-i-stop-it
  • 使桌子更小。如果可能,删除不需要的行
  • 使用SELECT table1.col1, table2,col1 ...而不是select *仅使用查询中需要的列来生成较小的临时表
  • 使用占用更少空间的数据类型
  • 在 /tmp 文件夹所在的卷上添加更多磁盘空间
  • TMPDIR通过在 mysqld 启动之前设置环境变量,通过 mysql 更改临时文件夹用户。指向TMPDIR具有更多可用空间的磁盘卷上的文件夹。您还可以在 mysqld 服务的命令行中或命令行中使用tmpdir选项。请参阅:B.5.3.5 MySQL 存储临时文件的位置/etc/my.cnf--tmpdir
于 2013-10-23T20:44:39.973 回答
9

执行这些步骤

停止mysql服务

将 .myi 文件重命名为 x.old

启动mysql

修复查询中的所有表,MySQL将重建密钥文件

于 2012-08-04T04:05:50.450 回答
7

上面有这么多答案,问题所有者已经按照@Hawili的建议得到了解决方案,并且自从提出这个问题以来已经过去了很长时间。但由于这是一个常见问题,我想分享我的经验,以便如果有人由于不同的原因再次遇到这个问题,那么可以从这里得到解决方案。

情况1:

最常见的原因是查询获取的数据大于 /tmp 分区的大小。每当您在查询期间遇到此问题时,请查看您的 /tmp 文件夹大小。临时表是自动创建和删除的,如果在此查询期间此处的可用空间降至 0,则意味着您需要优化查询或需要增加 /tmp 的分区大小。

注意:有时它不是单个查询:如果大量查询的组合在同一台服务器上同时执行此操作,那么您可能会遇到此问题,通常单个查询将在没有任何错误的情况下执行。

案例二:

如果您需要修复损坏的 myisam 表,目录路径将与错误消息中的 /tmp 不同。

案例3:(罕见情况)

有时由于不正确的表连接,您可能会收到此错误。这实际上是一个语法错误,但 mysql 可以抛出这个错误。您可以在下面的链接中查看详细信息-

表 '/tmp/#sql_18b4_0.MYI' 的密钥文件不正确;尝试修复它

于 2015-07-08T11:31:00.933 回答
3

通过运行检查 tmp 目录的位置df -h。确保有足够的空间来增长临时文件,它可能是几个演出。

编辑:如果您有足够的可用空间,我会检查以确保您索引或包含在 WHERE 子句中的每一列都被索引。

于 2012-08-04T04:00:00.357 回答
0

检查您的数据库服务器上是否有足够的磁盘空间。如果磁盘已满,则会显示此错误。现在,您应该查看哪些文件夹取决于您的设置。

于 2015-01-09T11:12:05.460 回答
0

我使用了以下命令,错误消失了:

mysqlcheck --all-databases -r #repair

我从cpanel 论坛得到了这个解决方案

于 2016-10-23T14:15:33.387 回答
0

对我来说同样的问题

运行df -h看看你的分区 /tmp 是否有足够的空间

在我的情况下 /tmp 是一个溢出文件系统:

overflow 1,0M 24K 1000K 3% /tmp

发生了什么:

我在这里遇到了一些问题,我的分区/已满,然后 Debian 发行版/tmp在 RAM 内存中创建了一个新分区,以暂时使用。这个/tmp1MB 的分区不足以供系统使用。

解决方案:运行以下命令删除这个临时创建的分区/tmp

sudo umount -l /tmp

于 2018-01-15T18:43:58.960 回答
-2

/etc/init.d/mysqld restart在终端中使用此命令行重新启动 MySQL 服务。

于 2016-04-11T09:50:25.870 回答