MySQL:无法创build/写入文件“/tmp/#sql_3c6_0.MYI”(Errcode:2) – 它甚至意味着什么?
出于某种原因,我的制作数据库决定发布此消息。 所有应用程序调用失败的数据库与错误:
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
文件,出于某种原因我不能创build一个带有#
字符的文件。 有没有人听说过或看到这个错误? 有什么可能是错的,有些可能的事情要看?
MySQL数据库似乎已经启动并可以通过控制台查询,但应用程序似乎无法完成。 应用程序代码/文件没有变化。 它发生在蓝色。 所以我甚至不知道从哪里开始看,或者采用什么样的分辨策略。 有任何想法吗?
这通常意味着你的/tmp
分区的空间不足,无法创build文件,或者出于某种原因,由于权限问题, mysqld
进程无法写入该目录。 当selinux
在游行中下雨的时候,有时就是这种情况。
任何需要“临时文件”的操作默认都会进入/tmp
目录。 你看到的名字只是一些内部的随机名字。
当我在Fedora系统上运行wordpress时,我也遇到了这个错误。
我GOOGLE了,并find一种方法来解决这个问题。
也许这也会帮助你。
-
检查mysql config:my.cnf
cat /etc/my.cnf | grep tmpdir
我在
my.cnf
中看不到任何东西 -
在
[mysqld]
下添加tmpdir=/tmp
到my.cnf
-
重启web / app和mysql服务器
/etc/init.d/mysqld restart
在systemd上的Fedora上,MySQL获取private / 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创build的private / tmp正在被删除。 以下是发生的事情:
-
systemd通过clone()方法通过CLONE_NEWNS标志创build一个新的进程来获得一个私有的命名空间。 或者,也可以使用CLONE_NEWNS调用unshare()。 一样。
-
systemd在/ tmp(例如/ tmp / systemd-namespace-XRiWad / private)中创build一个子目录并将其挂载在/ tmp上。 因为在#1中设置了CLONE_NEWNS,所以其他进程不可见这个挂载点。
-
systemd然后在这个私有名称空间中调用mysqld。
-
一些特定的数据库操作(如“describe”)创build和删除临时文件,这些文件有更新/ tmp / systemd-namespace-XRiWad / private上的时间戳的副作用。 其他数据库操作在不使用/ tmp的情况下执行。
-
最后10天,即使数据库本身保持活动状态,也不会执行更新/ tmp / systemd-namespace-XRiWad / private上的时间戳的操作。
-
/ bin / systemd-tmpfiles出现并移除“old”/ tmp / systemd-namespace-XRiWad / private目录,有效地使private / tmp不能用于mysqld,而public / tmp保持可用于系统上的其他所有内容。
重新启动mysqld是可行的,因为它在第一步开始重新开始,并带有全新的private / tmp目录。 但是,这个问题最终会再次出现。 然后再次。
简单的解决scheme是configuration/ bin / systemd-tmpfiles文件,使其保留/ tmp / tmp / systemd-namespace- *中的所有内容。 我通过使用以下内容创build/etc/tmpfiles.d/privatetmp.conf来完成此操作:
x /tmp/systemd-namespace-* x /tmp/systemd-namespace-*/private
问题解决了。
文件名看起来像是由MySQL中的查询创build的临时表。 这些文件通常是非常短暂的,它们是在一个特定查询期间创build的,然后立即清理。
然而,他们可能会变得非常大,这取决于查询需要在临时表中处理的数据量。 或者您可能有多个并发查询创build临时表,如果这些查询中有足够多的查询同时运行,则可能会耗尽磁盘空间。
我做了MySQL咨询,我帮助一个在根分区上有间歇性磁盘完全错误的客户,即使每次他看,他都有大约6GB的空闲空间。 在我们检查了他的查询日志之后,我们发现他有时有四个或更多的查询同时运行,每个查询在/ tmp中创build一个1.5GB的临时表,这个表在他的根分区上。 繁荣!
我给他的解决scheme:
-
增加MySQLconfigurationvariables
tmp_table_size
和max_heap_table_size
这样MySQL可以在内存中创build真正大的临时表。 但是,允许MySQL在内存中创build1.5GB临时表并不是一个好主意,因为没有办法限制同时创build多less个表。 你可以用这种方法快速消耗你的记忆力。 -
将MySQLconfigurationvariables
tmpdir
设置为具有更多空间的另一个磁盘分区上的目录。 -
找出哪些查询正在创build如此大的临时表,并优化查询。 例如,使用索引帮助查询将其扫描缩小到表格的较小片段。 否则,将这个故事中的一些数据归档,这样查询就没有太多的行要扫描了。
对我来说,这个问题是在很长一段时间没有使用MySQL和Web服务器之后才出现的。 所以我确定我的设置在哪里是正确的; 只需重新启动服务即可解决此问题; 关于这个问题的奇怪的部分是,仍然可以连接到数据库,甚至使用mysql工具查询/添加表。 例如 :
mysql -u root -p
我重新使用:
systemctl start mysqld.service
或者服务mysqld restart或者/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/
在Ubuntu上,我将/ tmp移动到不同的卷(符号链接)后,出现此错误。 即使设置了所需的权限1777,问题仍未解决。
MySQL受AppArmor保护,它不允许写入新的tmp位置/ mnt / tmp。 我不得不添加以下行到/etc/apparmor.d/abstractions/user-tmp来解决这个问题
所有者/ mnt / tmp / ** rwkl,
/ mnt / tmp / rw,
在Debian 7.5上,我得到了同样的错误。 我意识到/tmp
文件夹的所有者和权限已closures。 作为另一个答案build议我做了如下(必须是根):
chown root:root /tmp && chmod 1777 /tmp
我甚至不需要重启mysql守护进程。
由于访问控制安全策略,特别是在启用SELinux时,它不允许外部可执行文件在系统位置创build临时文件。
通过以下命令禁用SELinux:
echo 0> / selinux / enforce
你现在可以启动mysql,在读/写到/ tmp或系统目录时,不会给与任何权限相关的错误。
如果您希望在上述命令中启用SELinux安全性,请将其更改为0到1。
这很容易,你只需授予/ tmp文件夹为777权限。 只需键入:
chmod -R 777 /tmp
检查权限问题,mysqlconfiguration。
另外检查你是否还没有达到磁盘空间,配额限制。
注意:有些系统限制文件数量(不只是空间),删除一些旧的会话文件有助于解决我的情况。