ERROR 3或OS error code 28是磁盘写入失败信号,需先用df -h /backup和df -i确认空间及Inodes余量,检查/tmp是否与备份路径同分区,可加--tmpdir指定大空间临时目录,并在备份前添加空间校验脚本防止半截失败。

MySQL 升级后突然报 ERROR 3 或 OS error code 28: No space left on device,大概率不是升级本身吃掉了空间,而是升级触发了某些隐性行为:比如重启后 ibtmp1 重建暴涨、PURGE BINARY LOGS 逻辑变更失效、或新版本默认启用更激进的日志策略。先别删文件,按路径定位再操作。
确认到底是哪个分区被撑爆了
升级后 MySQL 服务重启,可能让 tmpdir 或 datadir 下的临时文件“重置式膨胀”。必须立刻区分真实瓶颈:
- 运行
df -h /var/lib/mysql /tmp /var/log——重点看这三个挂载点,尤其注意/tmp是否是tmpfs(内存盘),CentOS 默认大小常只有 1–2GB - 查 MySQL 实际用哪:执行
SELECT @@tmpdir, @@innodb_tmpdir, @@datadir;,别只信配置文件,运行时值才准 - 如果
df显示 100% 但du -sh /var/lib/mysql/* | sort -hr总和远小于此,说明有“幽灵文件”:进程还在写但文件已被rm,用lsof +L1找出并 kill 对应进程
清理 ibtmp1 临时表空间(升级后最常暴涨)
MySQL 5.7+ 默认启用独立临时表空间 ibtmp1,升级重启后它会从 12MB 开始动态增长,大排序、JSON 函数、CREATE TABLE AS SELECT 都会猛推它到几十 GB。它不会随表删除自动收缩,但可以安全释放:
- 确认无长事务:
SELECT * FROM information_schema.INNODB_TRX WHERE TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) > 60;,结果为空才能继续 - 执行
ALTER TABLESPACE innodb_temp_tablespaces ENCRYPTION='N';(仅 5.7.30+ / 8.0+ 支持),立即释放已分配空间 - 若版本不支持,唯一可靠方式是停服务 → 删除
ibtmp1文件 → 启动 MySQL(它会自动重建为初始大小) - 长期预防:在
my.cnf中加innodb_temp_data_file_path = ibtmp1:12M:autoextend:max:2G,硬限最大尺寸
二进制日志没按预期清理?检查 expire_logs_days 是否真生效
升级后 expire_logs_days 常失效——不是配置丢了,而是 MySQL 8.0+ 改用 binlog_expire_logs_seconds,且老参数仅在 FLUSH LOGS 或重启时触发清理。误删会导致主从断裂:
- 查当前设置:
SELECT @@expire_logs_days, @@binlog_expire_logs_seconds;,8.0+ 优先看后者 - 看哪些 binlog 还活着:
SHOW MASTER LOGS;,记下最老文件名(如mysql-bin.000099) - 查从库是否跟得上:
SHOW SLAVE STATUS\G,确认所有从库的Relay_Master_Log_File≤mysql-bin.000099 - 安全清理:
PURGE BINARY LOGS TO 'mysql-bin.000100';(精确到文件名,比时间戳更可控) - 别用
rm -f mysql-bin.*,否则mysql-bin.index不同步,下次启动报错
升级后 tmpdir 路径错配导致写入失败
MySQL 升级包可能重置 tmpdir 为系统默认 /tmp,而你之前手动设过其他路径。大查询、ALTER TABLE、ORDER BY 全部卡在这儿:
- 执行
SELECT @@tmpdir;,如果返回/tmp且该目录已满,立刻改配置 - 编辑
my.cnf,在[mysqld]下加:tmpdir = /data/mysql-tmp(选一个空间充足、MySQL 用户有读写权限的路径) - 确保目标目录存在并授权:
mkdir -p /data/mysql-tmp && chown mysql:mysql /data/mysql-tmp - 重启前先测试:
mysql -e "SELECT 1 INTO OUTFILE '/data/mysql-tmp/test.txt';",验证写入成功再重启 - 注意:RHEL/CentOS 上若启用了 SELinux,还需
semanage fcontext -a -t mysqld_tmp_t "/data/mysql-tmp(/.*)?"并restorecon -Rv /data/mysql-tmp
真正危险的不是空间满了,而是清理动作没对齐 MySQL 的运行时状态:ibtmp1 必须等事务空闲,binlog 必须核对从库位点,tmpdir 切换前得验证权限和上下文。每一步跳过验证,都可能让问题从“磁盘满”变成“主从断”或“实例起不来”。


















