先确认tmpdir实际路径:SELECT @@tmpdir;再检查该目录是否存在、属主是否为mysql用户、权限是否为1777(含粘滞位)、磁盘及inode是否充足、SELinux/AppArmor或systemd PrivateTmp是否限制写入。

MySQL报错“Can't create/write to file”时先看tmpdir路径
错误信息里出现 Can't create/write to file,基本可以锁定是 MySQL 服务进程无法在 tmpdir 指定的目录下创建文件。这个路径由系统变量 tmpdir 控制,不是固定写死的 /tmp,必须查实当前值。
执行以下命令确认实际路径:
SELECT @@tmpdir;
常见误判点:
- 配置文件(
my.cnf或my.ini)里写了tmpdir=/data/tmp,但该目录根本不存在 - 目录存在,但属主不是运行 mysqld 的用户(如
mysql用户),或权限不包含写入(w)和执行(x,对目录意味着可进入) - 目录挂载在 NFS 或某些容器卷上,而这些文件系统禁用了
exec或不支持临时文件创建
检查tmpdir目录的权限与粘滞位
Unix/Linux 下,tmpdir 目录不仅需要可写,还必须有粘滞位(Sticky bit),否则 MySQL 会因 OS errno 13(Permission denied)失败——这是很多运维忽略的关键点。
用以下命令检查:
ls -ld /path/to/your/tmpdir
正确输出应类似:drwxrwxrwt 2 mysql mysql 4096 May 10 02:00 /data/tmp,末尾的 t 表示粘滞位已设。
若缺失粘滞位,且属主已是 mysql,执行:
sudo chown mysql:mysql /data/tmp && sudo chmod 1777 /data/tmp
注意:1777 中的 1 就是粘滞位;不要用 755 或 777 替代。
确认磁盘空间与inode是否耗尽
即使 df -h 显示还有空间,也可能因 inode 耗尽导致无法创建新文件。MySQL 创建临时表时会生成多个小文件(如 ibXXXXXX),极易触发 inode 不足。
检查方式:
df -i /path/to/your/tmpdir
如果 Use% 接近 100%,问题就在这里。临时解决可清空该目录下旧的、非活跃的临时文件(注意:只删以 ib、sql、MY 开头且无对应进程占用的文件),长期方案是换一个 inode 更充裕的挂载点,或调整应用逻辑减少临时表使用频次。
另一个常见陷阱是:目录所在分区没满,但 tmpdir 是软链接,实际指向的路径所在分区已满。务必用 readlink -f /path/to/tmpdir 确认真实路径再查空间。
验证MySQL进程能否真正写入tmpdir
别依赖 ls -l 或 id -u mysql 就断定权限没问题。最可靠的方式是模拟 mysqld 进程身份写一个测试文件:
sudo -u mysql touch /data/tmp/test_write_$$ && sudo -u mysql rm /data/tmp/test_write_$$
如果报错 Permission denied,说明权限链某处断裂——可能是 SELinux 启用、AppArmor 限制、或 systemd 服务单元设置了 ProtectSystem= 或 PrivateTmp=yes(后者会让 MySQL 实际使用 /tmp/systemd-private-xxx,而非你配置的 tmpdir)。
检查 systemd 配置:
systemctl show mysqld | grep PrivateTmp
若为 true,要么关掉它(PrivateTmp=no),要么把你的 tmpdir 改成该私有路径(不推荐),或者干脆让 MySQL 使用 /var/lib/mysql/tmp 这类更可控的位置。


















