MySQL临时文件路径由@@tmpdir和@@innodb_tmpdir运行时值决定,需用SELECT @@tmpdir, @@innodb_tmpdir;确认实际路径,并通过df -h和df -i检查其所在分区空间及inode使用情况,避免误判根目录或配置文件设置。

直接查 tmpdir 路径和对应分区空间,别猜配置文件或删文件——90% 的查询卡住或报错,根源就是 MySQL 正在往一个只剩几十 MB 的 /tmp(常为 tmpfs)里拼命写临时排序文件。
查清 MySQL 实际用的是哪个 tmpdir
运行时值才准,my.cnf 里写的可能没生效,也可能被覆盖:
- 进 MySQL 执行:
SELECT @@tmpdir, @@innodb_tmpdir;—— 若返回空或/tmp,基本锁定问题区域 - 注意:
innodb_tmpdir只影响 InnoDB 临时表,而ORDER BY、GROUP BY、DISTINCT等排序类操作仍走tmpdir - 若返回路径含空格或中文(如
C:/Windows/Temp),Windows 下大概率静默失败,需立刻处理权限与路径格式
确认该路径真实可用空间和 inode
不要只看 df -h /,MySQL 不关心根目录剩多少,只认它实际写的挂载点:
- 执行:
df -h $(mysql -Nse "SELECT @@tmpdir;")—— 直接显示 tmpdir 所在分区的使用率 - 若类型是
tmpfs(常见于/tmp),重点看Size列:它通常只有内存的一半,几 GB 就会爆,删文件无效 - 顺手检查 inode:
df -i $(mysql -Nse "SELECT @@tmpdir;")—— 小临时文件极多时,Space剩得多但Inodes耗尽,也会报OS error code 28
结合错误现象快速归因
不是所有 “table is full” 都是数据目录满,关键看状态和错误上下文:
- 查询长时间卡在
Copying to tmp table状态 → 几乎 100% 是tmpdir写失败 - 报错
The table '#sql-xxxx' is full或Incorrect key file for table '/tmp/#sql_'→ 落盘路径明确指向 tmpdir - 错误日志里出现
Can't create/write to file '/tmp/#sql'(Errcode: 28)→ 不是权限问题,就是空间或 inode 耗尽 - 如果
SHOW STATUS LIKE 'Created_tmp_disk_tables';暴涨,且Created_tmp_tables / Created_tmp_disk_tables比值骤降 → 说明大量本该内存完成的操作被迫落盘,而落盘目标已不可写
临时救急但必须验证的 SET GLOBAL 操作
5.7.20+ / 8.0.12+ 支持动态切换,但极易因权限、路径不存在或空间不足而静默失败:
- 先确保新路径存在、MySQL 进程用户(如
mysql)有读写权限、不在 NFS 或 tmpfs 上:sudo mkdir -p /data/mysql-tmp && sudo chown mysql:mysql /data/mysql-tmp - 执行:
SET GLOBAL tmpdir = '/data/mysql-tmp'; -
必须立刻验证:
SELECT @@tmpdir;返回值必须是新路径,否则配置未生效(常见于权限不足或路径不可写) - 切完后不调大
tmp_table_size和max_heap_table_size,只是把瓶颈从磁盘换到内存,一样会失败
真正容易被忽略的点:换完 tmpdir 后,没人去检查 innodb_online_alter_log_max_size 是否也撑爆了——它虽不占磁盘,但超限会直接中止 DDL 并报类似磁盘错误;还有 Windows 下路径必须用正斜杠、SYSTEM 用户权限要“完全控制”而非仅“修改”,这些细节一漏,整个操作就白做了。


















