故障現象
- phpMyAdmin 顯示多表狀態為「使用中」
- 「修復表」「分析表」「優化表」均失敗
- 錯誤信息:
can't create new temp file
myisamchk -r -f 強制修復也無效
排查過程
- 嘗標準修復流程:CHECK → REPAIR → ANALYZE → OPTIMIZE,全軍覆沒
- 檢查文件權限、磁盤掛載、inode 用盡,均正常
- 檢查磁盤剩餘空間 → 發現磁盤 100% 滿
根因確認
MyISAM 修復/優化需要創建臨時文件(.TMD 中間文件、.MYI 索引重建文件),磁盤空間耗盡導致無法創建臨時文件,所有維護操作失敗。
解決方案:釋放磁盤空間
緊急清理命令
# 查看磁盤使用
df -h
# 查找大文件/目錄
du -h /var/lib/mysql | sort -hr | head -20
# 清理常見佔空間項
# 1. 舊備份文件
rm -f /backup/mysql_*.sql.gz
# 2. 過期日誌
find /var/log -name "*.log.*" -mtime +30 -delete
# 3. 臨時文件
rm -rf /tmp/mysql_* /tmp/#sql_*
# 4. 空表優化(釋放碎片空間)
mysql -e "SHOW DATABASES" | while read db; do
mysql -e "SHOW TABLES FROM $db" | while read tbl; do
mysql -e "OPTIMIZE TABLE $db.$tbl" 2>/dev/null
done
done
標準修復流程(空間釋放後)
# 1. 停止 MySQL
systemctl stop mysqld
# 2. 備份數據目錄(關鍵!)
cp -r /var/lib/mysql /backup/mysql_$(date +%F)
# 3. 處理損壞表的 .TMD 文件
cd /var/lib/mysql/your_database
mv broken_table.TMD broken_table.MYD # 重命名臨時文件
# 4. 離線修復(MySQL 停止狀態)
myisamchk -r /var/lib/mysql/your_database/*.MYI
# 5. 啟動 MySQL
systemctl start mysqld
# 6. 在線檢查優化
mysqlcheck -o -r your_database -u root -p
預防措施
- 磁盤告警:Zabbix/Prometheus 監控磁盤使用率 > 80% 報警
- 定期清理:定時任務清理舊備份、臨時文件、錯誤日誌
- 表優化排程:低峰期定期
OPTIMIZE TABLE 釋放碎片
- 存儲引擎選型:核心業務表遷移至 InnoDB,避免 MyISAM 修復依賴臨時文件
關鍵教訓
「使用中」狀態往往是 MyISAM 崩潰標記,但修復失敗的深層原因多為資源瓶頸(磁盤空間、inode、內存、文件句柄)。資源健康是數據庫穩定的前提。