遊戲 Lag 白皮書 › L12 資料庫
長時間未結束的 transaction Long-running transaction / MVCC purge lag
原因 ID db-long-tx · 主要負責 遊戲開發團隊(伺服器開發) · 協同 基礎設施團隊(DB 基礎設施)
在含圖解與實驗的完整版中開啟卡片 →
一個 transaction 長時間不結束時,會一直持有鎖定,DB 也無法清理(purge)舊版本的資料,整體會越來越慢。
為什麼 開著 transaction 等待其他伺服器的回應,或在營運中於主 DB 上執行長時間的彙總查詢 → 於是 持有的鎖定一直不釋放,待清理的舊版本資料持續累積 → 畫面上 使用那些資料列的功能逾時,存檔與查詢在幾個小時內全面變慢
- 症狀
- 輸入延遲, 吃指令/回檔
- 因素
- 延遲, 停滯
- 誰會遇到
- 只有特定功能, 整個伺服器
- 何時
- 開越久越嚴重, 偶爾隨機發生
- 負責單位
- 主要負責 遊戲開發團隊(伺服器開發) · 協同 基礎設施團隊(DB 基礎設施)
- 遊戲開發團隊要做的事
- 不在 transaction 中等待網路呼叫或使用者輸入,彙總查詢改在複本上執行。
- 基礎設施團隊要做的事
- 對長時間未結束的 transaction 發出警示並強制終止、提供彙總用的複本、監看 undo log 與失效資料列的增加。
- 圖表上
- 緩慢爬升 · undo log 長度(History list length)、失效資料列數
- 查看位置
- MySQL 用 INFORMATION_SCHEMA.INNODB_TRX 的 trx_started 找出最舊的 transaction,並看 SHOW ENGINE INNODB STATUS 的 TRANSACTIONS 區段中的 History list length(尚未清理的 undo log 量)。PostgreSQL 看 pg_stat_activity 的 xact_start、state 為 idle in transaction 的 session,以及 pg_stat_user_tables 的 n_dead_tup
- 符合的跡象
- 存在已開啟幾分鐘~幾小時的 transaction,期間 History list length 或 n_dead_tup 持續上升,結束該 transaction 後隨著清理(purge、VACUUM)執行而下降
- 不符合的跡象
- 沒有長時間的 transaction 卻全面變慢時,是檢查點(db-checkpoint)或磁碟的問題
- 確認方式
- 用基礎設施工具確認(不需要遊戲程式碼)
- 深入了解
- DB 會保留舊版本,讓讀取端能看到修改前的樣子(MVCC)。這些紀錄要等最舊的 transaction 結束後才能刪除,所以一個 transaction 開著好幾個小時的話,MySQL 會累積 undo log,PostgreSQL 會累積 VACUUM 清不掉的失效資料列(dead tuple)。SQL Server 則可能因 transaction log 無法縮減而塞滿磁碟。
出處
- InnoDB Multi-Versioning MySQL
只要還有能看到舊版本的 transaction,update undo log 就無法丟棄,rollback segment 會越來越大;建議即使是唯讀的 transaction 也要經常 commit - Routine Vacuuming (PostgreSQL Documentation) PostgreSQL
舊的資料列版本在其他 transaction 還看得到時無法刪除,長時間未結束的 transaction 必須結束或終止其 session - Client Connection Defaults (PostgreSQL Documentation) PostgreSQL
idle_in_transaction_session_timeout:中斷開著 transaction 卻閒置的 session,避免長時間持有鎖定 - Troubleshoot a full transaction log (SQL Server Error 9002) Microsoft SQL Server
長時間執行中的活躍 transaction 會妨礙 transaction log 的清理 - The INFORMATION_SCHEMA INNODB_TRX Table MySQL
TRX_STARTED:transaction 的開始時間 - Purge Configuration MySQL
purge 負責清理已 commit 的 transaction 的 undo log 清單(history list),積壓量顯示在 SHOW ENGINE INNODB STATUS 的 TRANSACTIONS 區段的 History list length - The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
pg_stat_activity 的 xact_start(transaction 開始時間)與 state(idle in transaction)、pg_stat_user_tables 的 n_dead_tup(失效資料列的估計值)
相關原因
同一層:L12 資料庫
同一症狀(輸入延遲)在其他層的原因
查看含圖解與實驗的完整版卡片