面對 MySQL 變慢、CPU 飆高、IO 瓶頸、鎖等待,資深 DBA 遵循「由外而內、由宏觀到微觀」的系統化排查路徑。本文構建完整定位體系:系統層、網絡層、存儲層、負載層、鎖層、引擎層、監控層,附關鍵指標閾值與實戰 SQL。
top -c # 顯示完整命令行
# 關鍵行解讀:
# 1st: load average (1,5,15min) ≤ CPU核心數為健康
# 3rd: %Cpu(s): us用戶態 sy系統態 ni低優先級 id空閒 wa IO等待
# 4th: 物理內存 total/used/free/buff/cache
# 5th: Swap total/used/free -- 生產環境 Swap used 應為 0
MySQL 進程關鍵列:%CPU、%MEM、VIRT/RES/SHR、S 狀態(D=不可中斷睡眠/IO阻塞、R=運行、S=睡眠、Z=殭屍)。
nmon -f -s 30 -c 2880 # 每30秒采樣,生成 .nmon 文件,nmon_analyser 生成報表
dstat -dcnml 10 # 磁盤、CPU、網絡、內存、負載 綜合輸出
# 1. 丟包/錯誤統計
netstat -i 1 # 持續顯示介面錯誤、丟包、碰撞
# 2. 連接流量分布
iftop -i eth0 # 按 S/D 切換顯示源/目標端口,定位大流量連接
# 1. 設備級 IO 統計
iostat -x 2 # 關注 %util(接近100%為瓶頸)、await、svctm、rrqm/s、wrqm/s
# 2. 進程級 IO
iotop -o # 只顯示正在做IO的進程,定位MySQL佔比
# 3. 磁盤基準測試(維護窗口執行)
dd if=/dev/zero of=/data/test bs=64k count=16k conv=fsync # 寫入測試
dd if=/data/test of=/dev/null bs=64k # 讀取測試
# 參考:企業級存儲 寫 500MB/s+、讀 600MB/s+
# 實時 QPS/TPS
mysqladmin -uroot -p -ri 1 extended-status | grep -i "queries\|questions\|com_select\|com_insert\|com_update\|com_delete"
# 或用 sysbench/tpcc 測壓建立基線
SELECT
r.trx_id AS waiting_trx_id,
r.trx_mysql_thread_id AS waiting_thread,
r.trx_query AS waiting_query,
b.trx_id AS blocking_trx_id,
b.trx_mysql_thread_id AS blocking_thread,
b.trx_query AS blocking_query
FROM information_schema.innodb_lock_waits w
JOIN information_schema.innodb_trx b ON b.trx_id = w.blocking_trx_id
JOIN information_schema.innodb_trx r ON r.trx_id = w.requesting_trx_id\G
輸出直接展示「誰被誰阻塞、執行什麼 SQL」,秒級定位阻塞源頭。
SELECT * FROM information_schema.innodb_trx\G
SELECT * FROM information_schema.innodb_locks\G -- 5.7+
-- 8.0+ 合併為 performance_schema.data_locks
SHOW ENGINE INNODB STATUS\G
# 重點關注區塊:
# SEMAPHORES: 信號量等待、自旋輪數、OS等待計數
# TRANSACTIONS: 活躍事務數、鎖結構數、等待鎖數、死鎖信息
# FILE I/O: 文件IO線程狀態、待處理IO
# INSERT BUFFER AND ADAPTIVE HASH INDEX: 插入緩衝合併、自適應哈希命中
# LOG: 日志序列號(LSN)、刷盤進度、檢查點年齡
# BUFFER POOL AND MEMORY: 命中率、免費列表、髒頁比例、自適應哈希內存
# ROW OPERATIONS: 讀寫行數、死鎖計數
pt-query-digest / mysqldumpslow 定期分析 Top 慢查詢,驅動索引優化。| 現象 | 首查層級 | 核心動作 |
|---|---|---|
| CPU 100% | 系統→負載→引擎 | top 定進程 → SHOW PROCESSLIST 找高消耗 SQL → EXPLAIN 優化/殺進程 |
| IO 瓶頸 | 存儲→引擎 | iostat 確認設備 → innodb_status 看髒頁/檢查點 → 調 innodb_io_capacity/flush_neighbors |
| 鎖等待/死鎖 | 引擎→負載 | innodb_lock_waits 找阻塞鏈 → 分析事務隔離級/索引缺失 → 改寫 SQL/調隔離級 |
| 主從延遲 | 負載→網絡→引擎 | Seconds_Behind_Master → 從庫 top/iostat → 並行複製/拆大事務 |
| 內存不足/OOM | 系統→引擎 | free -g → innodb_buffer_pool_size 佔比 ≤ 70% 物理內存 → 縮減/擴容 |
性能定位無銀彈,有體系:**系統資源 → 網絡/存儲 → MySQL 負載 → 鎖/事務 → 引擎內部 → 歷史趨勢**。將上述命令封裝為巡檢腳本、接入監控平台、建立慢查詢治理閉環,才能從「救火」進化到「防火」。