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

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

大規模なバッチ処理 Batch jobs during service

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

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

ランキング集計、郵便の一括送信、古いデータの整理をサービス中に実行すると、ロックとディスクを占有します。

なぜ サービス時間中に大量の処理を実行 → すると 広い範囲のロック、ディスク・CPUの占有 → 画面では 特定の時間帯に取引・保存が失敗、ロード遅延

症状
入力遅延, 不発・ロールバック
要因
遅延, ストール
誰に起きるか
特定の機能だけ, サーバー全体
いつ
一定の周期で
担当
主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
ゲーム開発チームの対応
細かく分けて少しずつ、集計はレプリカで。
インフラチームの対応
集計用レプリカの提供、バッチは空いている時間帯に予約、ロックエスカレーション・ギャップロック待ちの監視。
グラフでは
周期的なスパイク · DBクエリの遅延、ロック待ち
確認箇所
ラグが出た時刻に動いていた長いクエリを探す。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は、1つのステートメントが約5,000個を超える行ロックを取ると、テーブルロックに切り替えます(ロックエスカレーション)。その瞬間、同じテーブルを使うすべての要求が止まります。MySQLもデフォルト設定では、範囲条件で更新すると行と行の間の隙間までロックし(ギャップロック)、新しい行の挿入を止めます。

出典

  1. Transaction Locking and Row Versioning Guide Microsoft SQL Server
    1つのステートメントが1つのテーブル(またはインデックス)で5,000個以上のロックを取るとロックエスカレーション、lock_escalation拡張イベントで記録
  2. InnoDB Locking MySQL
    InnoDBのデフォルトの分離レベルREPEATABLE READでは、検索・スキャンにnext-keyロックを使うため、ギャップロックがその隙間への新しい行の挿入を止める
  3. The Slow Query Log MySQL
    long_query_timeを超えたクエリを、実行時間(Query_time)・ロック時間(Lock_time)・読んだ行数とともに記録
  4. The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
    pg_stat_activity:セッションごとの現在実行中のクエリ(query)と開始時刻(query_start)

あわせて読みたい原因

同じ層:L12 データベース

同じ症状(入力遅延)を起こすほかの層の原因

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