mysql报错28本质是操作系统enospc错误,需用df -h和df -i分别检查磁盘空间及inode是否耗尽,重点排查/tmp、datadir、binlog所在挂载点,确认tmpdir实际路径后针对性清理残留临时文件并调优tmp_table_size等参数。

这不是 MySQL 自己出的错,是操作系统告诉它“没地方写了”——ENOSPC(No space left on device)。磁盘空间或 inode 耗尽都会触发,但故障点不一定是根分区,/tmp、datadir、binlog 所在挂载点都可能单独撑爆。
df -h 看哪几行才管用
别扫一眼就跳过,重点盯三类挂载点:
-
df -h输出里Use%≥95% 的所有行,尤其是挂载在/var/lib/mysql、/tmp、/var/log、/var/lib/mysql/binlog这些路径下的设备 - 如果
/tmp是tmpfs(df -h /tmp显示类型为tmpfs),它默认只占内存一半,几十 GB 查询一跑就满,和物理磁盘无关 - 必须执行
df -i查 inode:哪怕Avail列显示还有空间,IUse%到 100% 同样会报 28
mysql -e "SHOW VARIABLES LIKE 'tmpdir'" 返回的路径才是关键
MySQL 不一定用系统 /tmp,它按配置走。常见陷阱:
- 输出是
/tmp,但实际挂载点是tmpfs—— 重启 MySQL 前得先清或换路径 - 输出是
/var/tmp,而/var分区只剩 2%,那删/tmp根本没用 - 输出为空?说明 MySQL 继承了启动用户的
TMPDIR环境变量,得查ps aux | grep mysqld看启动命令里有没有-D TMPDIR=...
清理前先确认哪些文件真能删
直接 rm -rf /tmp/* 很危险,可能干掉 mysql.sock 或 systemd 临时文件。稳妥做法:
- 运行
lsof +L1(Linux)找标记为deleted却仍占空间的文件——这些是崩溃后残留的#sql_*.MYD、#sql-*.ibd,可安全清理 - 只删 1 小时前的临时表文件:
find /tmp -name "#sql_*" -mmin +60 -delete -
ibtmp1是 InnoDB 全局临时表空间,不能手动删;要改innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:2G并重启 MySQL - 二进制日志用
PURGE BINARY LOGS BEFORE NOW() - INTERVAL 3 DAY;,别直接rm mysql-bin.*
tmp_table_size 和 max_heap_table_size 必须相等
这两个值不一致时,MySQL 按小的那个生效,极易把本该走内存的临时表逼到磁盘。设成一样才能真正压住落盘行为:
- 临时表内存上限建议设为
64M(tmp_table_size = 64M,max_heap_table_size = 64M) - 排序缓冲别太激进:
sort_buffer_size = 2M(全局设置,非 per-connection) - 显式指定
tmpdir = /var/tmp(确保该路径所在分区空间充裕且非 tmpfs),并在my.cnf中写死
最常被忽略的是 inode 耗尽和 tmpfs 临时目录——它们不会在 df -h 的 “容量” 列暴露问题,但一样让 error 28 反复出现。











