MySQL 磁盘空间不足的直接判断方法
先确认是不是真的磁盘满,而不是 MySQL 自身表损坏或日志堆积。运行
df -h查看挂载点使用率,重点盯
/var/lib/mysql所在分区;再用
du -sh /var/lib/mysql/* | sort -hr | head -10快速定位最大库或文件。如果
df显示 100% 但
du总和远小于此,大概率是已删除但进程仍占用的“幽灵文件”,需查
lsof +L1。
快速释放空间的三类操作(按风险升序)
优先执行低风险动作,避免误删:
清空 MySQL 的慢查询日志和通用查询日志(如果启用):SET GLOBAL slow_query_log = 'OFF'; PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);注意:
PURGE BINARY LOGS不影响主从,但
RESET MASTER会彻底清空 binlog 并重置序列,仅限单机调试环境。 清理
mysql.ibd外的临时文件:检查
/var/lib/mysql下是否有以
#sql-或
ibtmp1结尾的大文件,后者是 InnoDB 临时表空间,重启 mysqld 可重建(前提是
innodb_temp_data_file_path未设为固定大小)。 删归档 binlog 前务必确认从库已同步:用
SHOW SLAVE STATUS\G检查
Relay_Master_Log_File和
Exec_Master_Log_Pos,确保不早于从库正在读取的位置。
大表清理后空间不释放?InnoDB 的坑在这里
InnoDB 表即使
DELETE掉 90% 数据,
.ibd文件也不会自动缩容——这是设计行为,不是 bug。释放空间只有两种可靠方式:
OPTIMIZE TABLE t1;:会重建表并释放碎片,但全程锁表(5.7+ 支持 ALGORITHM=INPLACE 的 DDL,仍需短暂排他锁);
ALTER TABLE t1 ENGINE=InnoDB;:效果同上,但更明确; 真正想缩文件,必须用
mysqldump导出 +
DROP TABLE+ 重建导入——适合离线维护窗口期。
注意:
innodb_file_per_table=ON是前提,否则所有表共用
ibdata1,删表也不释放空间。
预防性配置必须改的三项
别等爆满才想起调参:
限制 binlog 保留时间:expire_logs_days = 7(MySQL 5.7)或
binlog_expire_logs_seconds = 604800(8.0+),写入
my.cnf后需重启或
SET PERSIST; 关闭非必要日志:
general_log = OFF、
slow_query_log = OFF(开发环境可开,生产慎用); 监控
information_schema.INNODB_SYS_TABLESPACES中
FILE_SIZE和
ALLOCATED_SIZE差值,差得大说明碎片严重,该计划
OPTIMIZE了。
最常被忽略的是:没有把
log_bin单独挂到大容量磁盘,导致 binlog 和数据文件挤在同一分区——一出问题就全卡死。
