遊戲 Lag 白皮書 › L12 資料庫
大量批次作業 Batch jobs during service
原因 ID db-batch · 主要負責 遊戲開發團隊(伺服器開發) · 協同 基礎設施團隊(DB 基礎設施)
在含圖解與實驗的完整版中開啟卡片 →
在營運時段執行排行榜彙總、信件批次發送、舊資料清理時,會占用鎖定與磁碟。
為什麼 在營運時段執行大量作業 → 於是 大範圍鎖定,占用磁碟與 CPU → 畫面上 特定時段交易、存檔失敗,載入變慢
- 症狀
- 輸入延遲, 吃指令/回檔
- 因素
- 延遲, 停滯
- 誰會遇到
- 只有特定功能, 整個伺服器
- 何時
- 固定週期
- 負責單位
- 主要負責 遊戲開發團隊(伺服器開發) · 協同 基礎設施團隊(DB 基礎設施)
- 遊戲開發團隊要做的事
- 切成小批分次執行,彙總改在複本上進行。
- 基礎設施團隊要做的事
- 提供彙總用的複本,把批次作業排在離峰時段,監看鎖定擴大與 gap lock 等待。
- 圖表上
- 固定週期飆高 · DB 查詢延遲、鎖定等待
- 查看位置
- 找出 lag 發生時正在執行的長查詢。MySQL 看 slow query log,PostgreSQL 看 pg_stat_activity 的 query_start、query,再與同一時間的鎖定等待指標及批次排程(cron、DB 事件排程器)比對。SQL Server 用 lock_escalation 擴充事件記錄鎖定擴大
- 符合的跡象
- 每次都在同一時間執行大量 UPDATE、DELETE 或彙總查詢,期間鎖定等待與磁碟使用率一起上升
- 不符合的跡象
- 那個時間沒有長查詢時,是檢查點(db-checkpoint)或伺服器備份(dk-backup)
- 確認方式
- 用基礎設施工具確認(不需要遊戲程式碼)
- 深入了解
- SQL Server 在單一陳述式持有超過約 5,000 個資料列鎖定時,會改成資料表鎖定(鎖定擴大)。那一刻所有使用同一張資料表的請求都會停住。MySQL 在預設設定下,以範圍條件修改資料時,也會連資料列之間的間隙一起鎖住(gap lock),擋住新資料列的新增。
出處
- Transaction Locking and Row Versioning Guide Microsoft SQL Server
單一陳述式在一張資料表(或索引)上持有 5,000 個以上的鎖定時會發生鎖定擴大,可用 lock_escalation 擴充事件記錄 - InnoDB Locking MySQL
在 InnoDB 預設的隔離等級 REPEATABLE READ 下,搜尋與掃描使用 next-key lock,gap lock 會擋住在該間隙新增資料列 - The Slow Query Log MySQL
記錄超過 long_query_time 的查詢,連同執行時間(Query_time)、鎖定時間(Lock_time)、讀取的資料列數 - The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
pg_stat_activity:每個 session 目前執行中的查詢(query)與開始時間(query_start)
相關原因
同一層:L12 資料庫
同一症狀(輸入延遲)在其他層的原因
查看含圖解與實驗的完整版卡片