한국어English日本語简体中文繁體中文DeutschไทยTiếng ViệtРусскийPortuguês (Brasil)EspañolBahasa Indonesia

遊戲 Lag 白皮書 › L12 資料庫

營運中 schema 變更(DDL)的鎖定 Schema change lock (DDL / metadata lock)

原因 ID db-ddl-lock · 主要負責 基礎設施團隊(DB 基礎設施) · 協同 遊戲開發團隊(伺服器開發)

在含圖解與實驗的完整版中開啟卡片 →

在服務中替資料表新增欄位或索引時,可能因為一個只需要短暫持有的鎖定,讓所有使用該資料表的請求都在等待。

為什麼 以 hotfix 替營運中的資料表新增欄位或索引 → 於是 schema 變更在等待先前開啟的長 transaction,後面進來的所有請求又在等待這個 schema 變更 → 畫面上 使用該資料表的功能(背包、信件等)整個停住並逾時

症狀
輸入延遲, 吃指令/回檔, 連不上/無限讀取
因素
停滯
誰會遇到
只有特定功能, 整個伺服器
何時
偶爾隨機發生, 剛登入/維護剛結束
負責單位
主要負責 基礎設施團隊(DB 基礎設施) · 協同 遊戲開發團隊(伺服器開發)
遊戲開發團隊要做的事
含 schema 變更的 hotfix 要與 DB 基礎設施協調時程;先部署在沒有新欄位時也能運作的程式碼。
基礎設施團隊要做的事
把鎖定等待上限設短、失敗就重試,在沒有長 transaction 時執行,使用線上 schema 變更工具,大型資料表留到維護時間處理。
圖表上
從某個時間點起階梯式上升 · 等待鎖定的 session 數、該資料表的查詢延遲
查看位置
MySQL 統計 SHOW PROCESSLIST 中 State 為 Waiting for table metadata lock 的 session 數,並用 sys.schema_table_lock_waits 找出造成阻擋的 session(blocking_pid)。PostgreSQL 看 pg_locks 中 granted 為 false 的請求與 AccessExclusiveLock,並用 pg_blocking_pids() 找出造成阻擋的 session
符合的跡象
從開始 schema 變更的時間點起,所有使用該資料表的查詢都卡在鎖定等待,最前面是尚未結束的 transaction 或 schema 變更陳述式
不符合的跡象
等待只集中在特定資料列、同一張資料表的其他資料列處理正常時,是熱點資料列(db-hot-row)
確認方式
用基礎設施工具確認(不需要遊戲程式碼)
深入了解
MySQL 變更 schema 時會短暫取得中繼資料鎖定(metadata lock),PostgreSQL 則會短暫取得最強的資料表鎖定。即使變更本身瞬間就完成,只要前面有一個尚未結束的 transaction,後面所有請求都得等待。

出處

  1. Online DDL Performance and Concurrency MySQL
    online DDL 在收尾時也需要短暫的排他中繼資料鎖定;有長 transaction 時會等待,而這個等待中的鎖定請求會擋住後面所有的 transaction
  2. Server System Variables MySQL
    lock_wait_timeout:中繼資料鎖定的等待上限,預設值 31,536,000 秒(1 年)
  3. ALTER TABLE (PostgreSQL Documentation) PostgreSQL
    沒有另外註明的 ALTER TABLE 會取得最強的 ACCESS EXCLUSIVE 鎖定
  4. Client Connection Defaults (PostgreSQL Documentation) PostgreSQL
    lock_timeout:等待鎖定超過此時間時中止陳述式
  5. General Thread States MySQL
    Waiting for table metadata lock:等待中繼資料鎖定的執行緒狀態
  6. The schema_table_lock_waits and x$schema_table_lock_waits Views MySQL
    等待中繼資料鎖定的 session(waiting_query)與造成阻擋的 session(blocking_pid)
  7. pg_locks (PostgreSQL Documentation) PostgreSQL
    granted 為 false 表示正在等待鎖定,mode 顯示 AccessExclusiveLock 等鎖定種類
  8. System Information Functions and Operators (PostgreSQL Documentation) PostgreSQL
    pg_blocking_pids():阻擋指定 session 取得鎖定的 session 清單

相關原因

同一層:L12 資料庫

同一症狀(輸入延遲)在其他層的原因

查看含圖解與實驗的完整版卡片