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

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

長時間開いたままのトランザクション Long-running transaction / MVCC purge lag

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

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

1つのトランザクションが長く開いたままだと、ロックを持ち続けるうえ、DBが古いバージョンのデータを整理(purge)できないため、全体が徐々に遅くなります。

なぜ トランザクションを開いたまま別サーバーの応答を待つ、またはサービス中にプライマリで長い集計クエリを実行 → すると 取ったロックが解放されず、整理すべき古いバージョンのデータがたまり続ける → 画面では その行を使う機能がタイムアウト、数時間かけて保存・読み込みが全体的に遅くなる

症状
入力遅延, 不発・ロールバック
要因
遅延, ストール
誰に起きるか
特定の機能だけ, サーバー全体
いつ
長時間稼働するほど, ときどきランダムに
担当
主担当 ゲーム開発チーム・サーバー開発 · 副担当 インフラチーム・DBインフラ
ゲーム開発チームの対応
トランザクション内でネットワーク呼び出し・ユーザー入力を待たない、集計クエリはレプリカで。
インフラチームの対応
長時間開いたままのトランザクションのアラートと強制終了、集計用レプリカの提供、UNDOログ・デッドタプルの増加の監視。
グラフでは
徐々に上昇 · UNDOログの長さ(History list length)、デッドタプル数
確認箇所
MySQLはINFORMATION_SCHEMA.INNODB_TRXのtrx_startedで最も古いトランザクションを探し、SHOW ENGINE INNODB STATUSのTRANSACTIONSセクションに出るHistory list length(まだ整理できていないUNDOログの量)を確認。PostgreSQLはpg_stat_activityのxact_startと、stateがidle in transactionのセッション、pg_stat_user_tablesのn_dead_tupを確認
該当する場合
数分〜数時間経ったトランザクションがあり、その間History list lengthやn_dead_tupが上がり続け、そのトランザクションを終えた後に整理(purge・VACUUM)が走って減る
該当しない場合
古いトランザクションがないのに全体的に遅いなら、チェックポイント(db-checkpoint)かディスク側
確認手段
インフラのツールで確認(ゲームコード不要)
もっと詳しく
DBは、読む側が更新前の状態を見られるように、古いバージョンを残しておきます(MVCC)。最も古いトランザクションが終わるまでこの記録は消せないため、1つのトランザクションが数時間開いたままだと、MySQLではUNDOログが、PostgreSQLではVACUUMが整理できないデッドタプル(dead tuple、不要になった古い行)がたまります。SQL Serverではトランザクションログが縮まず、ディスクを埋めてしまうこともあります。

出典

  1. InnoDB Multi-Versioning MySQL
    古いバージョンを参照しうるトランザクションが残っていると、update UNDOログを破棄できずロールバックセグメントが大きくなる、読み取りだけのトランザクションもこまめにコミットするよう推奨
  2. Routine Vacuuming (PostgreSQL Documentation) PostgreSQL
    古い行バージョンは他のトランザクションから見える間は削除できず、長時間開いたままのトランザクションは終了させるかセッションを切断する必要がある
  3. Client Connection Defaults (PostgreSQL Documentation) PostgreSQL
    idle_in_transaction_session_timeout:トランザクションを開いたままアイドル状態になっているセッションを切断し、ロックを長く保持できないようにする
  4. Troubleshoot a full transaction log (SQL Server Error 9002) Microsoft SQL Server
    長時間実行中のアクティブなトランザクションが、トランザクションログの切り捨てを妨げる
  5. The INFORMATION_SCHEMA INNODB_TRX Table MySQL
    TRX_STARTED:トランザクションの開始時刻
  6. Purge Configuration MySQL
    コミット済みトランザクションのUNDOログの一覧(history list)をpurgeが整理、滞っている量はSHOW ENGINE INNODB STATUSのTRANSACTIONSセクションのHistory list lengthで表示
  7. The Cumulative Statistics System (PostgreSQL Documentation) PostgreSQL
    pg_stat_activityのxact_start(トランザクションの開始時刻)とstate(idle in transaction)、pg_stat_user_tablesのn_dead_tup(デッドタプル数の推定値)

あわせて読みたい原因

同じ層:L12 データベース

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

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