应先查错误日志关键词,再核验Created_tmp_disk_tables占比与tmpdir的df -h、df -i及挂载选项,而非直接判断磁盘或内存问题;因真正瓶颈常是tmpdir分区inode耗尽、挂载限制或ibtmp1不可扩展,而非数据目录空间不足。

先看错误日志里有没有具体线索,再查状态变量和磁盘路径,别直接猜是磁盘还是内存。
看错误日志里带不带关键词
执行 tail -n 50 /var/log/mysql/error.log,重点找这几类提示:
- 出现
No space left on device或Could not create temporary file→ 大概率是tmpdir所在分区磁盘或 inode 耗尽 - 出现
The table 'xxx' is full且xxx是你明确建的ENGINE=MEMORY表 → 就是max_heap_table_size不够 - 出现
tmp_table_size exceeded或类似表述 → 内存临时表上限被突破,但还没落盘就卡住了 - 完全没提磁盘或文件,只报错 +
EXPLAIN显示Using temporary→ 很可能刚触到内存阈值,还没写磁盘
查 Created_tmp_disk_tables 和 Created_tmp_tables
运行 SHOW GLOBAL STATUS LIKE 'Created_tmp%';:
- 如果
Created_tmp_disk_tables/Created_tmp_tables比值 > 20%,说明大量临时表被迫落盘 →tmp_table_size和max_heap_table_size太小 - 如果
Created_tmp_disk_tables为 0,但依然报错 → 基本排除临时表问题,重点查tmpdir权限、inode、挂载选项(比如noexec) - 注意:这个统计是全局累计值,要对比出错前后增量才更准
确认 tmpdir 分区的真实可用性
执行 SELECT @@tmpdir; 得到路径后,立刻检查:
-
df -h <tmpdir></tmpdir>→ 看剩余容量(哪怕还有 10GB,也可能因碎片无法分配大临时文件) -
df -i <tmpdir></tmpdir>→ inode 耗尽比磁盘满更隐蔽,/tmp下大量小临时文件极易触发 - 如果
tmpdir是/tmp,还要确认挂载参数:mount | grep /tmp,若含noexec或nosuid,MySQL 可能拒绝写入 - 用
lsof | grep deleted | grep mysql查是否有已删未释放的临时文件占着空间
为什么不能只看 df -h 显示的磁盘剩余?
因为 MySQL 报 “The table is full” 时,真正卡住的地方往往不是数据目录(datadir),而是这几个容易被忽略的路径:
-
tmpdir:排序、GROUP BY、子查询生成的临时表默认写这里,Linux 下常是/tmp,其他服务也往里写,极易被塞满 -
innodb_log_group_home_dir:redo 日志所在目录,虽然不直接触发该错,但若它和tmpdir共享分区,也会间接挤占空间 -
ibtmp1所在位置:InnoDB 临时表空间文件,路径由innodb_temp_data_file_path控制,默认在datadir,但它可独立配置,且大小固定时无法扩展 - 慢查询日志、general log 被编辑后保存,mysqld 还在往旧句柄写,文件不显示在目录却持续占空间
真正难处理的,是那些既没报磁盘满、Created_tmp_disk_tables 也不高,但错误反复出现的情况——这时候得盯 tmpdir 的 inode 和挂载选项,而不是调参数。


















