临时文件不自动清理需先确认MySQL是否正在使用:通过lsof检查文件句柄状态,SHOW VARIABLES查tmpdir路径,SHOW GLOBAL STATUS监控Created_tmp_disk_tables增长;清理前须终止长事务、FLUSH TABLES,并按命名规则(#sql/MY/ML/ib)及-mmin +30条件安全删除;根治需优化慢查询、调大tmp_table_size/max_heap_table_size、合理配置tmpdir与innodb_tmpdir。

临时文件不自动清理?先确认是不是 MySQL 正在用
MySQL 的 /tmp 或自定义 tmpdir 下残留大量 #sql*、MY*、ML*、ib* 文件,不代表它们都“无效”——很多是正在运行的查询或未提交事务生成的,直接删可能触发崩溃或主从不一致。
- 先查 MySQL 是否还在用这些文件:
lsof -n | grep mysql | grep /tmp,看到(deleted)后缀说明进程已释放句柄,可安全清理;没标这个的,大概率还在用 - 查当前
tmpdir路径:mysql -u root -p -e "SHOW VARIABLES LIKE 'tmpdir';" - 查是否正大量写磁盘临时表:
mysql -e "SHOW GLOBAL STATUS LIKE 'Created_tmp%';",重点关注Created_tmp_disk_tables值是否持续上涨
手动清理前必须停掉活跃查询
别一上来就 rm -f /tmp/#sql*。MySQL 在执行 ALTER TABLE、ORDER BY、GROUP BY 或大事务时,会把中间结果落盘到 tmpdir,强行删除会导致语句失败、连接中断甚至数据字典损坏。
- 先杀掉长时间运行的可疑连接:
mysql -e "SELECT CONCAT('KILL ',id,';') FROM information_schema.processlist WHERE TIME > 60 AND COMMAND != 'Sleep';" | mysql -u root -p - 再刷新表缓存(非强制清空,但能促使部分临时文件释放):
mysql -e "FLUSH TABLES;" - 确认无活跃 DDL 操作(如
ALTER、OPTIMIZE)后再进目录清理
安全删临时文件的实操命令
清理不是靠猜,而是按文件命名规律 + 状态判断。MySQL 临时文件有固定前缀,不同版本略有差异,但主流可识别:
-
#sql*:Online DDL 生成的临时表文件(如#sql-6b82_6_7.ibd),若对应ALTER已完成或失败,且lsof不显示占用,可删 -
MY*:filesort 临时文件(ORDER BY/DISTINCT大量数据时产生),通常进程退出后自动删,残留说明异常终止过 -
ML*:binary log 缓存溢出产生的临时文件,多见于大事务 + 小binlog_cache_size,删前建议调大该值 - 执行清理:
find /tmp -maxdepth 1 \( -name '#sql*' -o -name 'MY*' -o -name 'ML*' -o -name 'ib*' \) -mmin +30 -delete(只删 30 分钟以上未访问的,留点缓冲)
根治比清理更重要:为什么 tmpdir 总是爆满
频繁清理只是止痛,真正的问题往往藏在查询或配置里。比如一个没加索引的 GROUP BY user_id 在百万表上跑,每次都会写几百 MB 临时文件——换再大的磁盘也扛不住。
- 检查高频慢查询:
mysqldumpslow -s t /var/log/mysql/mysql-slow.log | head -20,重点看含Using temporary和Using filesort的 - 临时表默认走磁盘?确认
tmp_table_size和max_heap_table_size是否太小(建议设为 256M~512M,需两者一致) - 业务无法改 SQL?那就把
tmpdir挂内存(tmpfs),但注意:内存不是无限的,size=2G,nr_inodes=20k,mode=0700这类限制必须写死,否则 OOM 杀 mysqld 进程
最常被忽略的一点:innodb_tmpdir 和 tmpdir 是两套路径,前者专管 InnoDB 内部排序/DDL,后者管所有其他临时文件。只改一个,另一处照样爆满。


















