根本原因是mysql执行alter时临时空间不足,重点需检查tmpdir(默认/tmp,常为小容量tmpfs)、innodb_tmpdir和innodb_temp_data_file_path(控制ibtmp1大小)三处路径空间,而非仅关注datadir;失败后残留的#sql-xxx.ibd文件也需手动清理。
直接结论:不是 phpmyadmin 本身的问题,而是 mysql 执行 alter 时缺临时空间 —— 重点查 tmpdir、datadir 和 innodb_tmpdir 三个路径的可用空间,别只盯着 /var/lib/mysql。
为什么改大表会报“磁盘空间不足”,但 df -h / 显示还有几十 GB?
因为 MySQL 在执行某些 ALTER(如 ADD INDEX、MODIFY COLUMN、ENGINE=InnoDB)时,会把中间排序/重建数据写进 tmpdir,而不是 datadir。默认 tmpdir 指向 /tmp,而很多系统用 tmpfs 挂载 /tmp,仅 1–2 GB 内存盘,跑个 50GB 表就爆了。
常见错误现象:
-
phpMyAdmin 页面卡住或返回空白,MySQL 错误日志里出现
ERROR 1114 (HY000): The table '#sql-xxx' is full - 日志里带
Operating system error number 28(No space left on device) -
df -h /var/lib/mysql有空余,但df -h /tmp已 100%
实操建议:
- 运行
mysql -e "SHOW VARIABLES LIKE 'tmpdir';"确认当前路径 - 立刻检查该路径:比如是
/tmp,就执行df -h /tmp;如果是/home/xxx/.phpenv/versions/8.2.0/tmp,就查对应路径 - 别信软链接 —— 用
readlink -f $(mysql -Nse "SELECT @@tmpdir")看真实路径 - 临时应急:清掉
/tmp下以#sql-开头的残留文件(确认无活跃 DDL 后再删)
innodb_tmpdir 和 innodb_temp_data_file_path 也得一起盯
这两个参数管的是 InnoDB 内部临时表和排序/聚合用的临时空间,和 tmpdir 是两套机制。尤其当 SQL 出现 Using temporary(比如没索引的 GROUP BY 或多表 JOIN),它们会猛涨。
常见错误现象:
- ALTER 过程中突然中断,日志报
DB_ONLINE_LOG_TOO_BIG或ibtmp1占满整个磁盘 -
ls -lh /var/lib/mysql/ibtmp1发现几百 GB
实操建议:
- 查当前配置:
mysql -e "SELECT @@innodb_tmpdir, @@innodb_temp_data_file_path;" - 如果
ibtmp1已膨胀,只能重启 MySQL 释放(它只在启动时重建,默认 12MB) - 预防性配置:在
my.cnf加上innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:500M,硬限最大 500MB - 别设
max:过大,否则仍可能撑爆磁盘;也别不设,放任它长到 900GB 是真实案例
ALTER 失败后残留的 #sql-xxx.ibd 文件必须手动清理
MySQL 执行失败的 ALTER,会在 datadir 对应库目录下留下未完成的临时表文件,比如 yourdb/#sql-abc123.ibd。它们不会自动删除,且不计入 INFORMATION_SCHEMA.TABLES,OPTIMIZE TABLE 也扫不到。
实操建议:
- 先停写入,确认无活跃连接:
mysql -e "SHOW PROCESSLIST;" | grep -E "(Sleep|Query)" - 进
datadir对应库目录:cd /var/lib/mysql/yourdb - 找并删临时文件:
ls -lh #sql-*→rm -f #sql-* - 删完再
df -h看是否释放空间 —— 这步常被跳过,导致以为“清理没用”
真正缩表体积,OPTIMIZE TABLE 不是万能的
DELETE 掉大量数据后,.ibd 文件大小不变是 InnoDB 正常行为。但 OPTIMIZE TABLE 并不能无脑用:它本质是 ALTER TABLE ... ENGINE=InnoDB,仍要额外空间,且全程锁表。
实操建议:
- 只对启用了
innodb_file_per_table=ON的表有效(查SELECT @@innodb_file_per_table;) - 执行前确保
tmpdir+datadir合计有原表 1.2 倍空间(重建过程需要) - 业务高峰期禁用;若表 >100GB,优先考虑
mysqldump+DROP+ 重建导入 - 更稳妥的离线方案:
pt-online-schema-change或gh-ost,它们自己管理临时表路径,不依赖 MySQL 的tmpdir
最易被忽略的一点:很多团队只调 tmpdir,却忘了 innodb_temp_data_file_path 默认没上限,ibtmp1 可以一路涨到占满整块盘 —— 它不像 tmpdir 那样容易被 df 发现,得专门 ls -lh ibtmp1 才看得见。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











