44

出于某种原因,我的生产数据库决定喷出这条消息。所有应用程序调用都失败到数据库并出现以下错误:

PreparedStatementCallback; SQL [ /*long sql statement here*/ ]; 
Can't create/write to file '/tmp/#sql_3c6_0.MYI' (Errcode: 2); 
nested exception is java.sql.SQLException: Can't create/write to file '/tmp/#sql_3c6_0.MYI' (Errcode: 2)

我不知道,这甚至意味着什么。没有文件#sql_3c6_0.MYI,由于某种原因/tmp,我无法创建带有角色的文件。#有没有人听说过或看到过这个错误?可能有什么问题以及需要注意的一些事情?

MySQL DB 似乎已启动并正在运行,可以通过控制台查询,但应用程序似乎无法访问它。应用程序代码/文件没有变化。它只是突然发生了。所以我什至不确定从哪里开始寻找或应用什么解决策略。有任何想法吗?

4

14 回答 14

38

当我在我的 Fedora 系统上运行 wordpress 时,我也遇到了这个错误。

我用谷歌搜索了它,并找到了解决此问题的方法。

也许这对你也有帮助。

  1. 检查mysql配置:my.cnf

     cat /etc/my.cnf | grep tmpdir
    

    我看不到任何东西my.cnf

  2. 添加tmpdir=/tmpmy.cnf[mysqld]

  3. 重启 web/app 和 mysql 服务器

    /etc/init.d/mysqld restart

于 2012-11-02T16:15:49.933 回答
21

这通常意味着您的/tmp分区已用完空间并且无法创建文件,或者mysqld由于权限问题,该进程无法写入该目录。selinux有时,当你的游行下雨时就是这种情况。

默认情况下,任何需要“临时文件”的操作都将进入该/tmp目录。您看到的名称只是一些内部随机名称。

于 2012-08-17T00:18:25.983 回答
16

在带有 systemd 的 Fedora 上,MySQL 获取私有 /tmp 目录。在 /proc/PID_of_MySQL/mountinfo 中,您会发现如下行:

156 129 8:1 /tmp/systemd-namespace-AN7vo9/private /tmp rw,relatime - ext4 /dev/sda1 rw,seclabel,data=ordered

这意味着一个临时文件夹 /tmp/systemd-namespace-AN7vo9/private 作为 /tmp 挂载在 MySQL 进程的私有命名空间中。不幸的是,如果不经常使用,tmpwatch 会删除此文件夹。

我修改了 /etc/cron.daily/tmpwatch 并像这样插入了排除模式-X '/tmp/systemd-namespace*'

/usr/sbin/tmpwatch "$flags" -x /tmp/.X11-unix -x /tmp/.XIM-unix \
        -x /tmp/.font-unix -x /tmp/.ICE-unix -x /tmp/.Test-unix \
        -X '/tmp/systemd-namespace*' \
        -X '/tmp/hsperfdata_*' 10d /tmp

副作用是未使用的私有命名空间文件夹不会被自动删除。

于 2013-01-22T09:58:00.260 回答
14

非常感谢 ArturZ 为我指明了正确的方向。我的系统上没有安装 tmpwatch,所以这不是我的问题的原因。但最终结果是一样的:systemd 创建的私有 /tmp 被删除。这是发生的事情:

  1. systemd 通过带有 CLONE_NEWNS 标志的 clone() 创建一个新进程以获得私有命名空间。或者它用 CLONE_NEWNS 调用 unshare()。一样。

  2. systemd 在 /tmp 中创建一个子目录(例如 /tmp/systemd-namespace-XRiWad/private)并将其安装在 /tmp 上。因为 CLONE_NEWNS 是在 #1 中设置的,所以这个挂载点对所有其他进程都是不可见的。

  3. systemd 然后在这个私有命名空间中调用 mysqld。

  4. 一些特定的数据库操作(例如“describe ;”)创建和删除临时文件,其副作用是更新 /tmp/systemd-namespace-XRiWad/private 上的时间戳。其他数据库操作根本不使用 /tmp 来执行。

  5. 最终 10 天过去了,即使数据库本身仍然处于活动状态,也不会发生更新 /tmp/systemd-namespace-XRiWad/private 上的时间戳的操作。

  6. /bin/systemd-tmpfiles 出现并删除了“旧” /tmp/systemd-namespace-XRiWad/private 目录,有效地使私有 /tmp 无法用于 mysqld,而公共 /tmp 仍然可用于系统上的所有其他内容。

重新启动 mysqld 可以正常工作,因为这会在第 1 步重新启动所有内容,并使用全新的私有 /tmp 目录。然而,问题最终又回来了。然后再次。

简单的解决方案是配置 /bin/systemd-tmpfiles 以便它保留 /tmp 中名称为 /tmp/systemd-namespace-* 的任何内容。我通过使用以下内容创建 /etc/tmpfiles.d/privatetmp.conf 来做到这一点:

x   /tmp/systemd-namespace-*
x   /tmp/systemd-namespace-*/private

问题解决了。

于 2013-03-07T07:14:04.907 回答
14

文件名看起来像一个由 MySQL 中的查询创建的临时表。这些文件的寿命通常很短,它们是在一个特定查询期间创建的,然后立即清理。

然而,它们可能会变得非常大,具体取决于查询需要在临时表中处理的数据量。或者您可能有多个并发查询创建临时表,如果同时运行足够多的这些查询,它们可能会耗尽磁盘空间。

我做 MySQL 咨询,我帮助了一个客户,他的根分区出现间歇性磁盘已满错误,即使他每次查看,他都有大约 6GB 的可用空间。在我们检查了他的查询日志后,我们发现他有时会同时运行四个或更多查询,每个查询都会在 /tmp 中创建一个 1.5GB 的临时表,该表位于他的根分区上。繁荣!

我给他的解决方案:

  • 增加 MySQL 配置变量tmp_table_sizemax_heap_table_size以便 MySQL 可以在内存中创建非常大的临时表。但是允许 MySQL 在内存中创建 1.5GB 的临时表并不是一个好主意,因为没有办法限制同时创建的临时表的数量。通过这种方式,您可以很快耗尽您的记忆。

  • 将 MySQL 配置变量设置为tmpdir另一个具有更多空间的磁盘分区上的目录。

  • 找出您的哪些查询正在创建如此大的临时表,并优化查询。例如,使用索引来帮助该查询减少对表的较小部分的扫描。或者存档故事中的一些数据,这样查询就没有太多要扫描的行了。

于 2012-11-02T16:55:11.947 回答
7

对我来说,这个问题是在长时间不使用 mysql 和网络服务器之后出现的。所以我确信我的设置是正确的;只需重新启动服务即可解决此问题;关于这个问题的奇怪部分是仍然可以连接到数据库,甚至可以使用 mysql 工具查询/添加表。例如 :

mysql -u root -p

我重新开始使用:

systemctl start mysqld.service

或 service mysqld restart 或 /etc/init.d/mysqld restart

注意:根据这些命令中的机器/环境,应该重新启动服务。

于 2013-07-19T12:33:54.830 回答
5

一种更好的方法对我有用。

    chown root:root /tmp
  chmod 1777 /tmp
  /etc/init.d/mysqld restart

这就对了。

见这里: http: //nixcraft.com/databases-servers/14260-error-1-hy000-cant-create-write-file-tmp-sql_9f3_0-myi-errcode-13-a.html

http://smashingweb.info/solved-mysql-tmp-error-cant-createwrite-to-file-tmpmykbo3bl-errcode-13/

于 2013-04-17T17:54:48.147 回答
3

这很容易,您只需将 /tmp 文件夹授予 777 权限即可。只需输入:

chmod -R 777 /tmp
于 2015-07-15T08:14:08.730 回答
2

在 debian 7.5 上,我遇到了同样的错误。我意识到/tmp文件夹所有者和权限已关闭。正如另一个答案所建议的那样,我做了如下(必须是root):

chown root:root /tmp && chmod 1777 /tmp

我什至不必重新启动 mysql 守护进程。

于 2015-03-28T13:33:35.190 回答
2

在 Ubuntu 机器上,将 /tmp 移动到不同的卷(符号链接)后,我开始收到此错误。即使在设置了所需的权限 1777 之后,问题也没有解决。

MySQL 受 AppArmor 保护,它不允许写入新的 tmp 位置 /mnt/tmp。我必须将以下行添加到 /etc/apparmor.d/abstractions/user-tmp 来解决这个问题

所有者 /mnt/tmp/** rwkl,

/mnt/tmp/rw,

于 2015-01-06T05:21:14.320 回答
2

我正在使用mariadb。当我尝试将这一行放在 /etc/my.cnf 中时:

[mysqld]
tmpdir=/tmp 

它解决了与 /tmp 相关的网站前端生成的错误。但是,它有 /tmp 的后端问题。例如,当我尝试从后端重建 mariadb 时,它无法读取 /tmp 目录,然后产生了类似的错误。

mysqldump: Couldn't execute 'show fields from `wp_autoupdate`': Can't create/write to file '/tmp/#sql_1680_0.MAI' (Errcode: 2 "No such file or directory") (1)

所以这个适用于前端和后端:

1. mkdir /var/lib/mysql/tmp

2. chown mysql:mysql /var/lib/mysql/tmp

3. 将以下行添加到 [mysqld] 部分:

    tmpdir = /var/lib/mysql/tmp

4.重启mysqld(eg.centos7:systemctl restart mysqld)

于 2019-08-22T12:56:44.563 回答
1

由于访问控制安全策略,特别是在启用 SELinux 时,它不允许外部可执行文件在系统位置创建临时文件。

通过发出以下命令禁用 SELinux:

回声 0 >/selinux/enforce

您现在可以启动 mysql,它在读取/写入 /tmp 或系统目录时不会给出任何权限相关的错误。

如果您希望启用 SELinux 安全性,请将上述命令中的 0 更改为 1。

于 2014-05-19T20:23:09.673 回答
0

检查权限问题,mysql 配置。

还要检查你是否没有达到磁盘空间、配额限制。

注意:一些系统限制了文件的数量(不仅仅是空间),删除一些旧的会话文件有助于解决我的问题。

于 2014-07-17T10:18:47.080 回答
0

对于那些使用 VPS / 虚拟主机的人。

我正在使用 VPS,出现 MySQL 无法写入 /tmp 的错误,并且一切看起来都正确。我有足够的可用空间、足够的可用 inode、正确的权限。原来问题出在我的 VPS 之外,是托管 VPS 的机器已满。我的文件系统中只有“虚拟空间”,但托管 VPS 的后台机器没有“物理空间”。我不得不联系他们修复它的任何 VPS 公司。

如果您认为这可能是您的问题,您可以测试将更大的文件写入 /tmp (1GB):

dd if=/dev/zero of=/tmp/file.txt count=1024 bs=1048576 

我收到一条No space left on device错误消息,这表明它是后台的磁盘/卷已满。

于 2020-01-22T12:48:37.683 回答