當磁盤剩餘空間不足寫入當前行時,MySQL (MyISAM/InnoDB redo log/binlog) 採取「等待-重試-記錄」策略:
# 1. 確認佔用大戶
du -h /var/lib/mysql | sort -hr | head -20
# 2. 安全清理項目
# 歸檔/刪除舊 Binlog (保留近 7 天)
PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);
# 清理慢查詢/一般日誌
TRUNCATE TABLE mysql.slow_log; -- 若用 TABLE 存儲
# 或刪除檔案並 FLUSH LOGS
# 刪除臨時表殘留 (#sql-*.ibd)
# 重啟 MySQL 自動清理,或手動 DROP
# 壓縮歷史分區表 (InnoDB)
ALTER TABLE big_table COMPRESS=ON; -- 需 5.7+ 與 Barracuda 格式
-- 查找長事務
SELECT * FROM information_schema.INNODB_TRX
WHERE TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) > 600;
-- Kill 阻塞源頭
KILL thread_id;
datadir 或獨立表空間目錄innodb_file_per_table 便於單表遷移這些操作會建立大臨時檔案 (#sql-*.ibd)。磁盤滿時 MySQL 會:
ALTER TABLE 採用拷貝算法時,舊表保持完整恢復:REPAIR TABLE tbl_name 或 myisamchk -r (MyISAM);InnoDB 重啟自動崩潰恢復。
# Prometheus + node_exporter 告警規則
- alert: DiskSpaceCritical
expr: (node_filesystem_avail_bytes{mountpoint="/var/lib/mysql"} / node_filesystem_size_bytes{mountpoint="/var/lib/mysql"}) < 0.15
for: 5m
labels:
severity: critical
annotations:
summary: "MySQL 數據目錄磁盤剩餘 < 15%"
# 定時任務巡檢腳本
#!/bin/bash
usage=$(df -h /var/lib/mysql | awk 'NR==2 {print $5}' | sed 's/%//')
if [ $usage -gt 80 ]; then
echo "磁盤使用率 $usage%" | mail -s "MySQL 磁盤預警" dba@company.com
fi
磁盤滿是可預防的嚴重故障。核心策略:監控預警 → 定期清理 Binlog/日誌 → 獨立表空間便於遷移 → LVM/雲盤彈性擴容。緊急時刻,PURGE BINARY LOGS 和 Kill 長事務是最快止血手段。