出于某种原因,我的生产数据库决定发出此消息。所有应用程序对数据库的调用都失败,并显示错误:
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)
我不知道,这甚至意味着什么。/tmp
中没有文件#sql_3c6_0.MYI
,由于某种原因,我无法创建一个带有#
字符的文件。有没有人听说过它或看到这个错误?可能出了什么问题以及一些可能要看的事情?
MySQL 数据库似乎已启动并运行,可以通过控制台进行查询,但应用程序似乎无法通过它。应用程序代码/文件没有更改。它只是突然发生。所以我甚至不确定从哪里开始寻找或应用什么解决方案策略。有什么想法吗?
当我在Fedora系统上运行wordpress时,我也会遇到这个错误。
我用谷歌搜索了一下,并找到了解决此问题的方法。
也许这也会对你有所帮助。
-
检查 MySQL 配置 : my.cnf
cat /etc/my.cnf | grep tmpdir
我看不到
my.cnf
-
将
tmpdir=/tmp
添加到[mysqld]
下的my.cnf
-
重新启动 Web/应用程序和 MySQL 服务器
/etc/init.d/mysqld restart
这意味着您的/tmp
分区已用完空间,无法创建文件,或者由于任何原因,mysqld
进程由于权限问题而无法写入该目录。有时,当您的游行selinux
下雨时就是这种情况。
默认情况下,任何需要"临时文件"的操作都将进入/tmp
目录。您看到的名称只是一些内部随机名称。
在 Fedora 上使用 systemd 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
副作用是不会自动删除未使用的私有命名空间文件夹。
ArturZ为我指出正确的方向。我的系统上没有安装 tmpwatch,因此在我的情况下这不是问题的原因。但最终结果是一样的:systemd 创建的私有/tmp 被删除了。以下是发生的情况:
systemd 通过 clone() 创建一个新进程,CLONE_NEWNS标志以获取专用命名空间。或者也许它调用 unshare()与CLONE_NEWNS。同样的事情。
systemd 在/tmp 中创建一个子目录(例如/tmp/systemd-namespace-XRiWad/private) 并将其挂载在/tmp 上。由于CLONE_NEWNS是在 #1 中设置的,因此此装入点对所有其他进程。
然后,systemd 在这个私有命名空间中调用 mysqld。
一些特定的数据库操作(例如"描述;")创建并删除临时文件,这具有更新的副作用/tmp/systemd-namespace-XRiWad/private 上的时间戳。其他数据库操作在不使用/tmp 的情况下执行。
最终 10 天过去了,即使数据库本身保持活动状态,不会发生更新时间戳的操作/tmp/systemd-namespace-XRiWad/private.
/bin/systemd-tmpfiles 出现并删除了"旧"/tmp/systemd-namespace-XRiWad/private directory, 有效地使私有的/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
问题解决了。
看起来像由MySQL中的查询创建的临时表。 这些文件通常非常短暂,它们是在一个特定查询期间创建的,并在之后立即清理。
然而,它们可能会变得非常大,具体取决于查询需要在临时表中处理的数据量。 或者,您可能有多个并发查询创建临时表,如果同时运行足够多的这些查询,它们可能会耗尽磁盘空间。
我做MySQL咨询,我帮助了一个在他的根分区上出现间歇性磁盘已满错误的客户,即使每次他查看时,他都有大约6GB的可用空间。 在我们检查了他的查询日志后,我们发现他有时会同时运行四个或更多查询,每个查询在他的根分区上的/tmp 中创建一个 1.5GB 的临时表。 繁荣!
我给他的解决方案:
增加MySQL配置变量
tmp_table_size
和max_heap_table_size
,以便MySQL可以在内存中创建非常大的临时表。 但是允许MySQL在内存中创建1.5GB的临时表并不是一个好主意,因为无法限制同时创建的数量。 通过这种方式,您可以很快耗尽内存。将 MySQL 配置变量
tmpdir
设置为另一个具有更多空间的磁盘分区上的目录。找出哪个查询正在创建如此大的临时表,并优化查询。 例如,使用索引来帮助该查询将其扫描减少到表的较小切片。 或者存档故事中的一些数据,以便查询没有那么多行要扫描。
这个问题是在很长一段时间不使用 mysql 或网络服务器之后出现的。所以我确定我的设置正确;只需重新启动服务即可解决此问题;关于这个问题的奇怪之处在于,人们仍然可以连接到数据库,甚至可以使用 mysql 工具查询/添加表。例如:
mysql -u root -p
我重新开始使用:
systemctl start mysqld.service
或 服务 mysqld 重新启动或 /etc/init.d/mysqld restart
注意:根据这些命令的计算机/环境,应重新启动服务。
一个更好的方法对我有用。
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/
很容易,您只需将/tmp 文件夹授予为 777 权限即可。只需键入:
chmod -R 777 /tmp
在 Ubuntu 盒子上,我将/tmp 移动到不同的卷(符号链接)后开始出现此错误。即使在设置了所需的权限 1777 之后,问题仍未解决。
MySQL受AppArmor保护,AppArmor不允许写入新的tmp位置/mnt/tmp。我不得不将以下行添加到/etc/apparmor.d/abstractions/user-tmp 来解决此问题
owner/mnt/tmp/** rwkl,
/mnt/tmp/rw,
在 debian 7.5 上,我得到了同样的错误。我意识到/tmp
文件夹所有者和权限已关闭。正如另一个答案建议的那样,我做了如下(必须是根):
chown root:root /tmp && chmod 1777 /tmp
我什至不必重新启动mysql守护程序。
我正在使用mariadb。当我尝试将这一行放在/etc/my.cnf 上时:
[mysqld]
tmpdir=/tmp
它解决了与/tmp 相关的网站前端生成的错误。但是,它有/tmp 的后端问题。例如,当我尝试从后端重建mariadb时,它无法读取/tmp dir,然后生成了类似的错误。
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(例如。Centos7: systemctl restart mysqld)
由于访问控制安全策略,特别是当启用 SELinux 时,它不允许外部可执行文件在系统位置创建临时文件。
通过发出以下命令禁用 SELinux:
echo 0>/selinux/enforce
您现在可以启动 mysql,它在读取/写入/tmp 或系统目录时不会授予任何与权限相关的错误。
如果您希望启用 SELinux 安全性,请在上面的命令中将 0 更改为 1。
检查权限问题,mysql 配置。
还要检查是否尚未达到磁盘空间、配额限制。
注意:某些系统正在限制文件数量(不仅仅是空间),删除一些旧的会话文件有助于解决我的问题。
对于那些使用VPS/虚拟主机的人。
我正在使用VPS,遇到MySQL无法写入/tmp的错误,一切看起来都正确。我有足够的可用空间,足够的可用索引节点,正确的权限。事实证明,问题出在我的VPS之外,是托管VPS的机器已满。我的文件系统中只有"虚拟空间",但后台托管VPS的机器没有"物理空间"。我不得不联系VPS公司,他们修复了它。
如果您认为这可能是您的问题,您可以测试将较大的文件写入/tmp (1GB):
dd if=/dev/zero of=/tmp/file.txt count=1024 bs=1048576
我收到一条No space left on device
错误消息,这是一个赠品,即它是后台已满的磁盘/卷。
我遇到了同样的问题,这是因为我们的数据库服务器空间不足。清理一些磁盘空间解决了这个问题。