磁盘满导致mysql无法启动的核心是os错误28,必须先腾出≥1gb空间;需用df定位瓶颈分区,查datadir/tmpdir路径,识别幽灵文件,区分安全清理与停库操作,并验证主从binlog位点后谨慎purge。

磁盘满导致 MySQL 无法启动,核心问题不是数据库损坏,而是写入被系统拒绝——OS error code 28: No space left on device 出现时,MySQL 连初始化日志、刷 checkpoint、加载表空间都做不了。必须先腾出至少 1GB 空间,否则任何 SQL 命令(包括 PURGE BINARY LOGS)都执行不了。
确认到底是哪个路径堵死了
别猜,直接定位真实瓶颈点:
- 运行
df -h /var/lib/mysql /tmp /var/log,看哪个分区使用率 ≥95% - 查 MySQL 实际数据目录:
SELECT @@datadir;,确保你操作的是它所在的挂载点 - 查临时文件位置:
SELECT @@tmpdir;,有些环境/tmp是 tmpfs,满了一样卡住 - 如果
df显示满但du -sh /var/lib/mysql/* | sort -hr总和远小于已用空间,大概率是已删除但 mysqld 还占着句柄的“幽灵文件”,跑lsof +L1或lsof -p $(pgrep mysqld) | grep deleted查看
哪些文件能立刻删,哪些必须停库
误删会直接让 MySQL 启动失败,得按类型区别对待:
- 可安全清理(无需停库):
slow_query_log_file和general_log_file对应的文件,但前提是先关开关:SET GLOBAL slow_query_log = 'OFF';,否则删完立刻重建 - 必须停库后删:
ib_logfile0、ib_logfile1(redo log)、mysql-bin.*(binlog)——但 binlog 推荐用PURGE而非rm,避免破坏mysql-bin.index - 临时文件重点盯:
/tmp或@@tmpdir下以#sql_、ibtmp、mysqltmp开头的大文件,用lsof +D /tmp | grep mysqld确认没进程在用再删
清理 binlog 必须验证从库位点
直接 PURGE BINARY LOGS BEFORE ... 很危险,主从可能瞬间断裂:
- 主库执行:
SHOW MASTER STATUS;,记下File(如mysql-bin.000123)和Position - 从库执行:
SHOW SLAVE STATUS\G,比对Relay_Master_Log_File和Exec_Master_Log_Pos - 只有当从库
Relay_Master_Log_File是mysql-bin.000122且Exec_Master_Log_Pos已到该文件末尾,才表示mysql-bin.000122及更早的 binlog 可删 - 别信
Seconds_Behind_Master = 0——IO 线程可能卡在旧日志上,只看 SQL 线程延迟是不够的
重启后必须立刻验证的三件事
空间腾出来了、MySQL 起来了,不等于风险解除:
- 检查
innodb_log_file_size × 2是否超过可用空间的 25%,否则下次 crash recovery 可能失败 - 运行
SHOW ENGINE INNODB STATUS\G,看LOG小节里Log sequence number和Last checkpoint at是否接近,差太多说明刷盘滞后,后续容易再爆 - 确认
max_binlog_size没设成 1GB 这种巨无霸值,建议压到 100–256MB,防止单个 binlog 文件撑爆分区
真正容易被忽略的是 ibtmp1 ——它不随重启自动收缩,崩溃后残留的巨型 ibtmp1 文件常被漏掉,而它就在 @@datadir 下,和 ibdata1 一样吃空间不吐核。每次清理完务必再 ls -lh /var/lib/mysql/ibtmp1 看一眼。











