MySQL报错28的真实原因是操作系统返回ENOSPC,即磁盘或/tmp分区满;需用df -h定位满载分区,检查tmpdir路径下的残留临时文件并安全清理,同时调优sort_buffer_size等参数预防复发。

MySQL 报 Got error 28 from storage engine 的真实原因
这个错误不是 MySQL 本身出问题,而是操作系统返回的 ENOSPC(No space left on device)——磁盘已满或 /tmp 分区满了。MySQL 在执行排序、临时表、大查询、DDL 操作(如 ALTER TABLE)时会依赖磁盘临时空间,一旦写不进去就直接报错 28。
先快速确认到底哪个分区满了
别急着删日志,先定位瓶颈:
- 运行
df -h,重点看/、/var、/tmp对应的挂载点使用率是否 ≥95% - 如果
/tmp是独立挂载(比如tmpfs),运行df -h /tmp;很多系统默认只给tmpfs分配内存的一半,很容易撑爆 - 检查 MySQL 实际用的临时目录:
mysql -e "SHOW VARIABLES LIKE 'tmpdir';",输出的tmpdir值才是关键路径
清理 /tmp 下的 MySQL 临时文件(谨慎操作)
MySQL 有时崩溃或异常退出后,会在 tmpdir 留下未清理的临时文件(如 #sql_*.MYD、ibtmp1 碎片、mysql.sock.lock 等),它们可能占几十 GB 却不显示在常规 ls 中(因被进程占用)。
解析 MySQL 8.0 的 DDL 脚本,并将表结构导出为 Excel 格式。适用于用户需将 MySQL 的 `CREATE TABLE` 语句转换为结构化的 Excel 文件场景,导出内容包含字段名、数据类型、长度及精度等信息。支持多张表的批量处理,每张表对应 Excel 中的一个独立工作表。适用于数据库文档编写、数据字典生成及模式分析等任务。
- 先查是否有残留进程:运行
lsof +L1(Linux)或lsof | grep deleted,找标记为deleted但仍在占用空间的文件 - 确认无活跃 MySQL 进程在用这些文件后,再清理:
find /tmp -name "#sql_*" -mmin +60 -delete(只删 1 小时前的) - 不要直接
rm -rf /tmp/*—— 可能误删 socket、systemd 临时文件,导致服务起不来 -
ibtmp1是 InnoDB 全局临时表空间,不能手动删;需重启 MySQL 才会重建(且重启前确保配置了innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:2G防止无限增长)
预防再次触发 error 28 的硬性配置项
光清空间是治标。MySQL 默认行为对磁盘很“贪婪”,尤其在 OLAP 类查询或未加 LIMIT 的 UPDATE 场景下:
- 限制单次排序/临时表内存上限:
sort_buffer_size = 2M、read_rnd_buffer_size = 1M(避免动不动就落盘) - 强制小结果集走内存:
tmp_table_size = 64M和max_heap_table_size = 64M必须相等,否则以小值为准 - 把
tmpdir指向空间充裕且非tmpfs的路径(例如/var/tmp),并在my.cnf中显式配置,避免继承系统默认 - 定期清理二进制日志:
PURGE BINARY LOGS BEFORE NOW() - INTERVAL 3 DAY;(配合expire_logs_days = 3)
真正麻烦的是那些隐式依赖磁盘的操作:比如没加索引的 GROUP BY、ORDER BY,或 JOIN 字段类型不一致导致无法走索引——这些不会报错,但会让 tmpdir 在后台疯狂写临时文件,直到某天突然崩出 error 28。










