应先执行show variables like 'tmpdir';确认mysql实际使用的临时目录路径,再针对性清理或迁移;若路径下存在(deleted)标记文件,需重启mysqld释放空间,且tmpdir必须通过配置文件修改并重启生效,不可动态设置。

不是删 /tmp 就完事——MySQL 的 tmpdir 可能根本不在 /tmp,且删了正在使用的临时文件不会立即释放空间。
查清 MySQL 实际用的 tmpdir 路径
别猜,直接问 MySQL:
SHOW VARIABLES LIKE 'tmpdir';
输出结果里的路径才是真实生效位置。常见陷阱包括:
-
tmpdir指向/var/tmp、/run/mysqld或容器内小 volume(如/var/lib/mysql-tmp),而非/tmp - Docker 环境中,
tmpdir映射的 host 路径可能只有 1GB,df -h看根分区还有空间,但那个小 volume 已 100% - 某些发行版默认用
tmpfs挂载/tmp,但 MySQL 启动时若没显式配置,可能 fallback 到/var/tmp
临时文件删了磁盘还不释放?这是 lsof 在“占着茅坑”
执行 lsof | grep -i 'deleted' | grep mysql,如果看到类似 /tmp/MLXvlID8 (deleted) 的条目,说明 MySQL 进程还持有已删除文件的句柄,空间未归还。
此时:
- 重启 MySQL 服务是最直接的办法:
systemctl restart mysqld(或service mysql restart) - 如果无法重启,可尝试断开长连接(如应用端重启、kill 对应 connection ID),但效果不确定
- 切勿手动
rm -rf /tmp/*后就以为万事大吉——没 kill 进程,空间照旧不释放
清理前先确认哪些文件真能动
MySQL 临时文件名通常带随机字符串(如 SQL_abc123、#sql-ib12345),但日志、慢查询、socket 文件等不能乱删。
安全操作顺序:
- 先
df -h $(dirname $(mysql -Nse "SELECT @@tmpdir"))精准定位挂载点使用率 - 再
ls -lt /path/to/tmpdir | head -20看最近生成的文件是否全是 MySQL 临时表 - 若发现大量
ibtmp1、aria_log.或mysql.sock,别碰——它们不属于临时表范畴 - 真正可清的只有形如
#sql-*、SQL_*、MYD_*的文件(前提是 MySQL 已停或确认无活跃查询依赖)
为什么改了 my.cnf 的 tmpdir 还是写到旧路径?
tmpdir 是只读启动参数,SET GLOBAL tmpdir = '/new' 会报错:变量不可动态修改。
必须:
- 停 MySQL:
systemctl stop mysqld - 确认新路径存在、属主为
mysql:mysql、权限为750、文件系统是ext4或xfs(NFS/overlayfs 不稳定) - 修改
my.cnf中的[mysqld]段:tmpdir = /mnt/big-disk/mysql-tmp - 重启后立刻验证:
SHOW VARIABLES LIKE 'tmpdir';+ls -ld /mnt/big-disk/mysql-tmp
临时表问题本质是 SQL + 配置 + 磁盘三者耦合的结果,单独清理目录只是止痛;真正卡住业务的,往往是那个没加索引的 ORDER BY 查询——它每跑一次,就在 tmpdir 里啃掉几百 MB。











