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

ゲームラグ白書 › L12 データベース

DBのデッドロック Database deadlock

原因ID db-deadlock · 主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ

図と実験のあるメインページでこのカードを開く →

2つのトランザクション(ひとまとまりで処理されるDB操作)が互いに相手のロックした行を待つと、DBが片方を強制的に取り消します。

なぜ 取引Aはアイテム→通貨、Bは通貨→アイテムの順にロック → すると DBがデッドロックを検知して片方をロールバック → 画面では 取引・製作がときどき失敗、アイテムが元に戻る

症状
不発・ロールバック, 入力遅延
要因
パケットロス, ストール
誰に起きるか
特定の機能だけ
いつ
人が集中したとき, 特定の操作をしたとき
担当
主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
ゲーム開発チームの対応
ロック順序の統一、トランザクションを短く、失敗時の自動再試行。
インフラチームの対応
デッドロック検知を有効にしておき、デッドロックの記録を収集して共有、検知を無効にしたMySQLサーバーはロック待ちの上限(デフォルト50秒)を短縮。
数値の目安
検知までに、MySQL(InnoDB)はほぼ即時、PostgreSQLはデフォルトで1秒、SQL Serverは最大5秒ほどかかります。その間、両方の要求が止まっています。同時要求が非常に多いためにMySQLの検知を無効にしているサーバーでは、ロック待ちの上限(デフォルト50秒)まで待ちます。
グラフでは
不定期なスパイク · デッドロック数、取引失敗数
確認箇所
MySQLはSHOW ENGINE INNODB STATUSのLATEST DETECTED DEADLOCK(直近の1件)、innodb_print_all_deadlocksを有効にするとエラーログに残るすべてのデッドロック、INFORMATION_SCHEMA.INNODB_METRICSのlock_deadlocksを確認。PostgreSQLはpg_stat_databaseのdeadlocks、SQL Serverはデフォルトで有効なsystem_healthセッションのxml_deadlock_reportを確認。ゲームサーバー側のエラーコードはMySQL 1213、PostgreSQL 40P01、SQL Server 1205
該当する場合
取引・製作の失敗時刻にデッドロック数が増え、記録された2つのトランザクションが同じテーブル群を互いに逆の順序でロックしている
該当しない場合
デッドロック数は変わらないのに失敗するなら、ロック待ちの上限超過(MySQLエラー1205)かホットスポット(db-hot-row)
確認手段
インフラのツールで確認(ゲームコード不要)

出典

  1. InnoDB Startup Options and System Variables MySQL
    検知が有効なら(デフォルト)InnoDBはデッドロックを即座に検知してロールバック、innodb_lock_wait_timeoutのデフォルトは50秒
  2. Deadlock Detection MySQL
    同時実行性が非常に高いと検知自体が遅くなることがあるため、無効にしてロック待ちの上限に任せることもある
  3. Lock Management (PostgreSQL Documentation) PostgreSQL
    deadlock_timeoutのデフォルトは1秒:この時間ロックを待ってから初めてデッドロックを検査
  4. Deadlocks guide Microsoft SQL Server
    デッドロック検査のデフォルト間隔は5秒、デッドロックが頻発すると100msまで短縮、デフォルトで有効なsystem_healthセッションがxml_deadlock_reportを収集、犠牲になった側はエラー1205
  5. How to Minimize and Handle Deadlocks MySQL
    複数の行・テーブルは常に同じ順序で更新する、失敗したら再試行、innodb_print_all_deadlocksですべてのデッドロックを記録
  6. InnoDB Standard Monitor and Lock Monitor Output MySQL
    LATEST DETECTED DEADLOCK:直近のデッドロックの2つのトランザクション、保持したロック・待ったロック、ロールバックした側
  7. InnoDB INFORMATION_SCHEMA Metrics Table MySQL
    INNODB_METRICSのlock_deadlocksカウンター(デフォルトで有効)
  8. Server Error Message Reference MySQL
    1213 ER_LOCK_DEADLOCK(デッドロック)、1205 ER_LOCK_WAIT_TIMEOUT(ロック待ちの上限超過)
  9. The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
    pg_stat_databaseのdeadlocks:このDBで検知したデッドロックの数
  10. PostgreSQL Error Codes (PostgreSQL Documentation) PostgreSQL
    40P01 deadlock_detected

あわせて読みたい原因

同じ層:L12 データベース

同じ症状(不発・ロールバック)を起こすほかの層の原因

図と実験のあるメインページでこのカードを見る