Db2運用者の宿命「SQL0911N」を攻略する:デッドロックとタイムアウトの正体

Db2運用者の宿命「SQL0911N」を攻略する:デッドロックとタイムアウトの正体

Db2を運用していて最も遭遇する頻度が高く、かつ厄介なエラーといえば SQL0911N です。アプリケーションのログにこの文字が躍ったとき、インフラSEやDBAとしてどう動くべきか。今回はその「処方箋」をまとめます。

この記事のポイント:

  • SQL0911N の理由コード(2と68)の違いを理解する
  • 「実際にエラーを起こす」再現手順で挙動を掴む
  • 現場で即効性のあるロック回避設定を紹介

1. SQL0911N の正体:理由コードを読み解く

SQL0911N は、大きく分けて2つのパターンがあります。メッセージ末尾の Reason Code を確認してください。

  • Reason Code 2:デッドロック
    2つ以上のトランザクションがお互いのロック解除を待ち合い、身動きが取れなくなった状態。Db2が強制的に片方をロールバックさせます。
  • Reason Code 68:ロック・タイムアウト
    誰かが資源を掴んだまま離さず、待機時間が上限(LOCKTIMEOUT)を超えた状態です。

2. 【実践】SQL0911N (RC 68) を再現させる

理解を深めるために、あえてロック・タイムアウトを発生させてみましょう。ターミナル(db2bp)を2つ用意します。

準備:タイムアウト時間を5秒に設定

db2 update db cfg for [データベース名] using LOCKTIMEOUT 5
db2 terminate

再現手順

この手順は Db2 標準の SAMPLE データベースにある STAFF テーブルを使用しています

【ターミナル A:更新担当】          【ターミナル B:参照担当】
--------------------------          --------------------------
$ db2 +c "UPDATE STAFF              
  SET SALARY = 10000 
  WHERE ID = 10"
(未コミットのまま放置)

                                    $ db2 "SELECT * FROM STAFF 
                                      WHERE ID = 10"

                                    ... 5秒間、応答が止まる ...

                                    SQL0911N  The current transaction 
                                    has been rolled back because of 
                                    a deadlock or timeout. 
                                    Reason code "68".
    

※ `+c` オプションは自動コミットをオフにします。

3. 現場で使える 3 つの処方箋

① 現在コミット済み (CUR_COMMIT) の活用

Db2 V9.7以降の強力な機能です。書き込み中のデータがあっても、待たされる代わりに「直前の確定データ」を読みに行きます。

db2 get db cfg for [DB名] | grep CUR_COMMIT

② 適切な LOCKTIMEOUT の設定

デフォルトの LOCKTIMEOUT = -1 は「無限待ち」を意味します。これは本番環境では非常に危険です。

システム特性に合わせて 30秒〜60秒 程度に設定し、アプリケーション側で「リトライ処理」を実装するのがSEの定石です。

③ db2pd コマンドによる犯人の特定

「今まさに待たされている」状況なら、以下のコマンドで犯人を特定できます。

db2pd -db [DB名] -wlocks

出力結果の `TranHdl` を追いかけることで、どのアプリケーション・ハンドルがロックを握りつぶしているかが見えてきます。

システムカタログ表へのロックにも注意

REORGなどのDb2のユーティリティを同時に実施すると、システムカタログ表(SYSCAT)でもロック競合が発生します。

4. 犯人を逃さない「イベント・モニター」の設定

SQL0911N が発生した瞬間に現場にいなくても、後から「どのSQL同士が衝突したか」を詳細に調査する方法があります。それがデッドロック・イベント・モニターです。

重要:イベント・モニターを作成しただけでは機能しません。必ず SET EVENT MONITOR ... STATE 1 で有効化する必要があります。

① イベント・モニターの作成と有効化

まずはデッドロック情報をファイルに書き出すモニターを作成します。

— イベント・モニターの作成(詳細情報を含む)
CREATE EVENT MONITOR DLMON FOR DEADLOCKS WITH DETAILS
  WRITE TO FILE ‘/tmp/db2_event_mon’ MAXFILES 5 MAXFILESIZE 1000;

— モニターをアクティブにする
SET EVENT MONITOR DLMON STATE 1;

② 発生した情報の取り出し

デッドロックが発生した後、書き出されたバイナリファイルをテキスト形式で読み取ります。ここで db2evmon ツールを使用します。

db2evmon -db [データベース名] -evm DLMON > dl_report.txt

この dl_report.txt を開くと、以下のような「犯人の特定」に直結する情報が得られます。

  • Appl Id:ロックを保持していたアプリケーションのID
  • Text:実行されていた SQL文そのもの
  • Sequence number:どの順番で処理が行われたか
  • Statement text という行を探せば、ぶつかったSQLが見つかります

③ 運用上の注意点

イベント・モニターはファイル容量を消費するため、調査が終わったら停止・削除しておくのがSEとしての作法です。

— 停止
SET EVENT MONITOR DLMON STATE 0;
— 削除
DROP EVENT MONITOR DLMON;

5. まとめ

SQL0911N は敵ではありません。システムの整合性を守るための「防衛反応」です。
エラーを恐れてロックを無視するのではなく、適切なタイムアウト設定とリトライ設計を組み込むことで、堅牢なシステムを構築しましょう。
さらにステップアップしたい方へ
Db2のロック・メカニズムや内部構造を深く理解するには、体系的な学習が近道です。
現場で役立つリファレンスとして、以下の書籍が非常に参考になります。


© 2026 fire-se.com – Systems Engineer’s Tech Blog

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA