“table is full”错误主因是磁盘块或inode耗尽,需先执行df -h和df -i定位问题分区及/或inode使用率,再针对性清理binlog、临时文件或调整tmpdir等配置。

立刻停掉写入-heavy 的查询,然后查 df -h 和 df -i —— 90% 的 Disk full 不是 MySQL 配置问题,而是磁盘或 inode 真的满了。
查清到底是磁盘块满还是 inode 耗尽
MySQL 报 Error 1021: Disk full 或卡在 waiting for someone to free some space,第一反应不是进 MySQL,而是切到系统层:
-
df -h看各分区使用率,重点盯/var/lib/mysql所在分区(常见是/或/var)是否 100% -
df -i看 inode 使用率 —— 尤其当 binlog 文件极多(如每分钟生成一个mysql-bin.00xxxx)、或临时表爆炸时,df -h显示还有空间但df -i显示 100%,这就是 inode 耗尽,必须删小文件 - 别只看
ibdata1或表文件大小;mysql-bin.*、mysql-relay-bin.*、/tmp下残留的#sql-*临时文件、慢日志都可能撑爆
紧急清理 tmpdir 里的残留临时文件
大排序、GROUP BY、CREATE TABLE AS SELECT 会在 tmpdir 生成巨型临时文件,且 MySQL 不自动清理。一旦卡住,这些文件常驻不退:
- 先查当前位置:
SELECT @@tmpdir, @@innodb_tmpdir;—— 多数指向/tmp,而它常是tmpfs(内存挂载),实际大小受限于 RAM,极易占满 - 手动清理:
sudo find /tmp -user mysql -name "#sql*" -mmin +5 -delete(删 5 分钟前创建、属 mysql 用户的临时表文件) - 如果
/tmp是 tmpfs,重启 MySQL 前务必改配置:tmpdir = /data/mysql-tmp,并确保该路径有足够空间和mysql用户读写权限 - 长期风险点:
sort_buffer_size和join_buffer_size别设成几 GB;对大表加ORDER BY或GROUP BY字段建索引,能大幅减少磁盘临时表生成
安全归档并清理旧 binlog 日志
binlog 是最常被忽略的“磁盘杀手”,尤其主从环境误删会导致同步中断或 PITR 失效:
- 进 MySQL 查活跃日志:
SHOW MASTER LOGS;,记下最后一个文件名(如mysql-bin.000123) - 如果是主从架构,必须确认所有从库已同步到哪条日志:
SHOW SLAVE STATUS\G,比对Relay_Master_Log_File是否 ≤ 你要保留的最后一条 - 生产环境禁用模糊清理:
PURGE BINARY LOGS BEFORE '2024-01-01'—— 改用精确文件名:PURGE BINARY LOGS TO 'mysql-bin.000100'; - 清理前建议先
cp一份到备份目录(如/backup/binlog/),再删;避免 purge 后发现漏同步又没备份可回退
RDS 场景下临时表空间超限(#tab_name is full)
阿里云 RDS 常见报错:The table '/home/mysql/xxx/#tab_name' is full,本质是磁盘临时表总大小超过 loose_rds_max_tmp_disk_space 限制(默认 10GB):
- 这不是磁盘真满,而是 RDS 主动拦截 —— 查当前值:
SHOW VARIABLES LIKE 'loose_rds_max_tmp_disk_space'; - 控制台参数设置里调高该值,但别设到空闲空间上限,留至少 20% 给 binlog 和数据文件增长
- 同时调高
tmp_table_size和max_heap_table_size,让小临时表尽量走内存,减少落盘 - 用
EXPLAIN检查 SQL:若Extra字段含Using temporary,说明用了内部临时表;优先优化这类查询,比如加索引、拆分子查询、避免BLOB/TEXT字段参与排序
真正麻烦的从来不是“怎么删”,而是删完要不要补监控、有没有漏掉 inode 或 tmpfs 这类隐性瓶颈;一次清理后,至少补上 df -h && df -i 的定时巡检,不然下次报警还是凌晨三点。


















