InnoDB 的四種隔離級別不僅決定資料一致性語義,更直接影響 MVCC 版本鏈長度、Undo Log 累積、鎖競爭與 I/O 模式,進而決定系統吞吐量。本文結合 sysbench 實測數據,從效能視角剖析各級別優劣與適用場景。
| 隔離級別 | MVCC 行版本可見性 | Undo 保留壓力 | 鎖開銷 | 典型效能表現 |
|---|---|---|---|---|
| SERIALIZABLE | 所有 SELECT 加鎖 | 極高 | 極大(表/行鎖) | 吞吐量最低,極少使用 |
| REPEATABLE READ (RR) | 事務啟動時建立 Read View,全程可見同一快照 | 高(長事務導致版本鏈暴增) | 中(間隙鎖/Next-Key Lock) | 預設級別,長事務/熱點更新時寫入效能崩塌 |
| READ COMMITTED (RC) | 每條語句建立新 Read View | 中(語句級釋放舊版本) | 較低(無間隙鎖,僅行鎖) | 寫入延遲穩定,適合高併發 OLTP |
| READ UNCOMMITTED | 可見未提交變更(髒讀) | 理論最低,實際仍保留版本 | 最低(無版本檢查) | 讀取最快,但數據不一致風險極高 |
環境:全記憶體 sysbench,64 線程,800 萬行,update_index 負載。開啟長事務並執行全表掃描:
BEGIN; SELECT AVG(LENGTH(c)) FROM sbtest1; SELECT SLEEP(300); -- 模擬長事務 COMMIT;
結果:RR 隔離級別下,寫入吞吐量隨時間劇烈下降並持續走低;RC 則相對平穩。原因在於 RR 需維護事務開始時的 Read View,長事務導致 Undo Log 無法清理,版本鏈遍歷成本指數級上升,MySQL 5.6+ 更會引發嚴重鎖競爭。
mysqldump --single-transaction 與 mydumper 均在 RR 下啟動長事務備份大表,會產生相同的效能抖動。對於 TB 級資料、高寫入系統,建議:
雖理論上可避免版本鏈遍歷,但 InnoDB 實現上語句開始時仍會建立版本,長查詢同樣導致版本堆積。唯一優勢是讀取時跳過版本可見性檢查,Undo Log 在磁碟時可減少隨機 I/O,但髒讀風險極大,僅適用於「近似統計、監控大屏」等容忍不一致場景。
SET GLOBAL transaction_isolation='READ-COMMITTED'; 並配合 binlog_format=ROW 確保複制正確。SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;information_schema.innodb_trx,超時自動 Kill。正確選擇隔離級別,往往比加索引、調參數更能帶來數量級的效能提升。請根據業務一致性需求,在「正確性」與「效能」間做出理性取捨。