“The table is full”真因90%是内存临时表超限或tmpdir写入失败;先查错误日志关键词(如No space left on device)、再看Created_tmp_disk_tables占比是否超20%、最后确认tmpdir和datadir分区的空间与inode是否耗尽。

“The table is full”不是业务表真满了,90% 是内存临时表撞限或磁盘临时目录写不进去——先别改表结构,按顺序查这三处。
查错误日志里到底在报谁“满”
MySQL 的错误日志会暴露真实瓶颈,比报错语句本身更可信:
- 运行
SHOW VARIABLES LIKE 'log_error';找到日志路径,再用tail -n 50 /var/log/mysql/error.log查最近记录 - 重点搜这些关键词:
No space left on device(磁盘满)、Could not create temporary file(tmpdir 写失败)、tablespace full(ibdata1 或 ibtmp1 撑爆) - 如果看到
ERROR 1114 (HY000): The table 'canteen_membership' is full且引擎是MEMORY,那才是这张表自己内存超了;如果是InnoDB,基本可排除它
看 Created_tmp_disk_tables 是否猛涨
这个状态变量直接反映内存临时表是否频繁落地——它是判断 tmp_table_size 和 max_heap_table_size 是否过小的黄金指标:
- 执行
SHOW GLOBAL STATUS LIKE 'Created_tmp%'; - 对比
Created_tmp_tables(总临时表数)和Created_tmp_disk_tables(落地磁盘的次数):若后者占比 >20%,说明内存不够用 - 同时查当前值:
SELECT @@tmp_table_size, @@max_heap_table_size, @@tmpdir;—— 两个参数必须相等,否则 MySQL 取小值;默认常是 16M,远不够 GROUP BY 大结果集
盯死 tmpdir 和 datadir 分区空间与 inode
很多人只查 datadir(比如 /var/lib/mysql),却忽略 MySQL 默认把临时表往 /tmp 写,而那里早被其他进程塞爆了:
- 先确认路径:
SELECT @@tmpdir;,常见是/tmp或/var/tmp - 立刻跑:
df -h /tmp和df -i /tmp—— inode 耗尽也会报 “No space left on device”,但du -sh看不出 - 同样查
datadir:SHOW VARIABLES LIKE 'datadir';→df -h /var/lib/mysql - 若
df -h显示满,但du -sh /var/lib/mysql总和小很多,大概率是 mysqld 还占着已删文件句柄:lsof | grep deleted | grep mysql
RDS 用户注意 loose_rds_max_tmp_disk_space 这个隐藏上限
阿里云 RDS 等托管服务额外加了一道闸:磁盘临时表总大小不能超过 loose_rds_max_tmp_disk_space,默认 10GB,超了就报 the table '/home/mysql/xxx/#tab_name' is full:
- 该参数单位是字节,
10737418240 = 10GB,最大支持107374182400(100GB) - 控制台参数管理中直接修改,无需重启;但别设到顶——要留至少 10%~20% 给 binlog、错误日志等系统文件
- 配合调高
tmp_table_size(RDS 上限 64MB),减少落地频率,比单纯拉高磁盘限额更治本
真正容易被忽略的是:tmpdir 分区可能比 datadir 更早写满,且 noexec 或 nosuid 挂载选项会让 MySQL 根本写不进临时文件——哪怕磁盘还有空间,也会卡在“创建失败”这一步。


















