MySQL 表在長期增刪改後會產生統計信息過期、碎片堆積、甚至頁損壞。本文系統講解 ANALYZE TABLE、CHECK TABLE、OPTIMIZE TABLE 三大維護命令的原理、適用引擎、輸出解讀、加鎖行為,並給出生產環境排程建議與避坑指南。
ANALYZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...
Msg_type=status, Msg_text='Table is already up to date' 表示統計信息已最新,無需重建。SHOW TABLE STATUS 顯示 Rows 與實際 COUNT(*) 差距大、執行計劃突然走全表掃描。CHECK TABLE tbl_name [, tbl_name] ... [QUICK | FAST | MEDIUM | EXTENDED | CHANGED]
QUICK:僅檢查索引樹結構(最快)。FAST:僅檢查未正確關閉的表。MEDIUM(默認):掃描行校驗校驗和,檢查索引鍵順序。EXTENDED:全行掃描,極慢但最徹底。CHANGED:僅檢查上次檢查後被修改的表。Msg_type=status, Msg_text='OK' 正常;Error/Corrupt 需修復。DROP TABLE base_table; CHECK TABLE view_name; 會報 Table 'base_table' doesn't exist。OPTIMIZE [LOCAL | NO_WRITE_TO_BINLOG] TABLE tbl_name [, tbl_name] ...
Data_free 佔比 > 20% 或文件體積明顯大於邏輯數據量。myisamchk -r)。Table does not support optimize, doing recreate + analyze instead),實質執行 ALTER TABLE ... ENGINE=InnoDB 重建表 + ANALYZE。# /etc/cron.d/mysql-maintain # 每天 03:00 分析核心表(統計信息輕量) 0 3 * * * mysql -uroot -p'xxx' -e "ANALYZE TABLE db.core_orders, db.core_users;" >> /var/log/mysql/analyze.log 2>&1 # 每周日 04:00 檢查所有表(輕量 QUICK) 0 4 * * 0 mysql -uroot -p'xxx' -e "CHECK TABLE db.core_orders, db.core_users FAST;" >> /var/log/mysql/check.log 2>&1 # 每月 1 號 05:00 優化碎片重表(排他鎖,預留維護窗口) 0 5 1 * * mysql -uroot -p'xxx' -e "OPTIMIZE TABLE db.core_orders;" >> /var/log/mysql/optimize.log 2>&1
# 分析所有庫所有表 mysqlcheck -A -a -u root -p # 檢查所有表(MEDIUM) mysqlcheck -A -c -u root -p # 優化所有表 mysqlcheck -A -o -u root -p # 修復損壞表 mysqlcheck -A -r -u root -p
pt-online-schema-change 在線重建。Threads_running 避免業務堵塞。innodb_stats_persistent 持久化統計,重啟不丟失,可適當降低分析頻率。innodb_force_recovery 導出重建。將三板斧納入常態化運維體系,配合監控告警(Data_free 告警、執行計劃變更告警),可將「表級故障」壓縮至最低概率。