磁盘写满时MySQL卡住应先确认mysqld进程存活并检查deleted大文件;优先停用日志后删除slow/general log,binlog和redo log需停库操作;ibdata1膨胀只能通过导出、删文件、启用innodb_file_per_table重建解决。

MySQL磁盘写满时,SHOW PROCESSLIST卡住或连不上怎么办?
连不上 MySQL 不代表服务挂了,很可能是磁盘满导致写入阻塞、线程卡在日志刷盘环节。此时 mysqld 进程往往仍在运行,但所有写操作(包括 SHOW PROCESSLIST)会超时或卡死。
- 先别急着重启——重启失败概率极高,且可能触发崩溃恢复,进一步加重磁盘压力
- 用
ps aux | grep mysqld确认进程还在;再用lsof -p $(pgrep mysqld) | grep deleted查看是否有被删除但仍被占用的大文件(常见于误删ib_logfile或慢日志) - 如果还能执行命令,优先尝试
mysqladmin -u root -p ping测试基础连通性;失败则跳过 SQL 层,直奔系统层清理
哪些日志能立刻删、哪些必须停服务才能动?
不是所有“日志”都能直接 rm,MySQL 对不同日志的打开/写入方式差异极大,误删可能引发启动失败。
-
安全可删(无需停库):
slow_query_log_file、general_log_file(前提是已关闭对应日志开关:SET GLOBAL slow_query_log = OFF;否则删完会被立即重建) -
需停库后删:
ib_logfile0、ib_logfile1(redo log)、mysql-bin.*(binlog,除非确认不需要主从和恢复) -
不能删但可轮转:
error_log(通过mysqladmin -u root -p flush-logs触发重命名,旧文件保留但不再写入)
innodb_file_per_table=OFF 时,ibdata1 膨胀怎么减?
这是最让人头疼的情况:即使删了所有表,ibdata1 也不会收缩。它像一个只进不出的黑洞,尤其在共享表空间模式下。
- 根本没快捷办法——
OPTIMIZE TABLE对共享表空间无效,TRUNCATE也不释放空间 - 唯一可靠路径是:导出数据(
mysqldump),停库,删掉ibdata1和ib_logfile*,修改配置启用innodb_file_per_table=ON,再重建库并导入 - 过程中务必确认
innodb_log_file_size与原值一致,否则启动报错:InnoDB: Error: log file ./ib_logfile0 is of different size
扩容前先做空间归还:FLUSH LOGS 和 PURGE BINARY LOGS 的实际效果
FLUSH LOGS 本身不删文件,只是让 MySQL 关闭当前日志、开新文件;真正释放磁盘的是后续的 PURGE 操作,但必须满足前提。
- 先查 binlog 列表:
SHOW BINARY LOGS,确认最老的还在被哪个 position 或 GTID 使用(SHOW SLAVE STATUS\G中的Relay_Master_Log_File) - 安全 purge 命令:
PURGE BINARY LOGS TO 'mysql-bin.000245'(指定保留到某文件)或PURGE BINARY LOGS BEFORE '2024-06-01 00:00:00' - 注意:
expire_logs_days是被动策略,磁盘满时它早已失效——必须手动 purge 才见效
真正麻烦的从来不是“怎么扩”,而是“扩之前能不能把空间腾出来”。很多线上事故,就卡在 purge 前没核对从库位点,一删全链路断掉。动手前,多看一眼 SHOW SLAVE STATUS 的输出,比什么都管用。


















