資料量達百萬/千萬級時,MySQL 響應逐漸變慢。需系統性排查而非盲目調參數。
sar -u 2 10 # 每 2 秒採樣,共 10 次
關鍵欄位:
%user 用戶進程佔用
%sys 系統核心佔用
%wio 等待 I/O 佔用(>35% 疑似 I/O 瓶頸)
%idle 空閒(長期 0 表示 CPU 滿載)
vmstat 1 10
關注欄位:
r 運行隊列進程數(> CPU 核心數 4 倍即 CPU 瓶頸)
si/so swap in/out(持續非 0 表示記憶體不足)
bi/bo 磁碟讀/寫塊數
us/sy/id/wa CPU 細分
innodb_flush_method=O_DIRECT 避免雙重緩衝telnet host 3306 測試連通性skip-networking 是否關閉netstat -antp | grep 3306 觀察連線狀態[mysqld]
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 1 # 超過 1 秒記錄
log_queries_not_using_indexes = 1
分析工具:pt-query-digest、mysqldumpslow
SHOW FULL PROCESSLIST;
-- 或
SELECT * FROM information_schema.PROCESSLIST WHERE TIME > 10;
SHOW ENGINE INNODB STATUS\G
關注:
- SEMAPHORES:鎖等待
- TRANSACTIONS:長事務
- FILE I/O:I/O 併發
- BUFFER POOL:命中率、髒頁比例
| 瓶頸 | 對策 |
|---|---|
| CPU 高 | 優化慢 SQL、加索引、減少複雜 JOIN、啟用 Query Cache(低寫入場景) |
| 記憶體不足 | 增加 RAM、調大 innodb_buffer_pool_size (60-80% RAM)、減少 sort_buffer_size 等線程私有緩衝 |
| I/O 高 | RAID 10、SSD、分離 redo log/undo log/data 到不同磁碟、innodb_flush_neighbors=0 (SSD) |
| 鎖競爭 | 縮短事務、避免大事務、行鎖升級表鎖檢查、innodb_lock_wait_timeout 調整 |
| 連線過多 | 連線池複用、max_connections 評估、thread_cache_size 調大 |
監控先行:部署 Prometheus + Grafana + node_exporter + mysqld_exporter,建立基準線,變慢時才有比較依據。