DB2 データベースでのデッドロック
ディスク I/O の競合を抑えるようにデータベースを調整すると、デッドロックを軽減するのに役立ちますが、new_edit_state ストアド プロシージャ呼び出しによって呼び出し元のアプリケーションがデッドロックに陥り、ArcSDE データベースが使用不能になることは決してめずらしいことではありません。
たとえば、ストアド プロシージャが STATE_LINEAGES テーブルから大量の行のロックを取得して、ロックの最大数を超えてしまい、テーブルの排他ロックへのエスカレーションを試みたとします。ところが、呼び出し元のアプリケーションのクエリがすでに STATE_LINEAGES テーブルの共有ロックを取得していたために、デッドロックに陥ってしまいます。ステート系統が深くなると、大量の行がロックされる原因になります。この場合、ロック リストのサイズが小さく設定されていれば、問題は避けられません。ロック エスカレーションの仕組みを理解すれば、デッドロックが発生する状況がこれだけではないことがわかります。
このことは、ユーザのアプリケーションやデータベースの設定によっては、デッドロックが決してめずらしい現象ではないことを意味します。繰り返しますが、ステート系統が深くなると、この問題が悪化する可能性があることに注意してください。
幸い、IBM DB2 には、ロックリストのサイズ(LOCKLIST)、アプリケーションのロックがロック リストに占める割合(MAXLOCKS)、リクエストがロックの取得を待つ時間の長さ(LOCKTIMEOUT)、デッドロック検知の間隔(DLCHKTIME)、およびデッドロックのロールバック(DB2LOCK_TO_RB)を制御するチューニング パラメータがあります。
ロック リストの容量とロック エスカレーションの閾値を引き上げるには、それぞれ LOCKLIST パラメータと MAXLOCKS パラメータを変更します。
DB2 9 では、LOCKLIST および MAXLOCKS のデフォルト値は AUTOMATIC で、パラメータがセルフ チューニングされます。そのため、DB2 のメモリ チューナでは、メモリ消費が異なるときにメモリ リソースのサイズが動的に決定されます。自動チューニングが動作するのは、データベースでセルフ チューニング メモリが有効(SELF_TUNING_MEM=ON)な場合だけです。
また、DB2 のロック保留レジストリ変数 DB2_EVALUNCOMMITED、DB2_SKIPDELETED、および DB2_SKIPINSERTED を使用してロックを回避すれば、同時実行性を改善することもできます。これらのレジストリ変数によって、コミットされていない削除と挿入がスキャンで無条件にスキップされます。
デフォルトでは、ロックがタイムアウトすると、リクエストされたトランザクションがロールバックします。この振舞いを変更して、ロック リクエストを発行したステートメントだけをロールバックするには、DB2LOCK_TO_RB を「db2set DB2LOCK_TO_RB=STATEMENT」により変更します。ただし、ArcSDE に関しては、デフォルトの設定で十分です。
これらのパラメータを正しく設定する方法については、DB2 のドキュメントまたはパフォーマンス チューニング ガイドをご参照ください。次に、これらのパラメータを使用する方法を簡単に説明します。
ロック問題の診断
次に、ロック問題を診断するのに役立つツールを紹介します。
- SDE プロセスの DB2 アプリケーション ID を検出します。
SELECT appl_id FROM TABLE(SNAPSHOT_APPL_INFO('SDE',-1)) AS SNAPSHOT_APPL_INFO WHERE appl_name LIKE 'gsrvr%' SELECT appl_id,appl_name FROM TABLE(SNAPSHOT_APPL_INFO('SDE',-1))
- ロックとアプリケーション情報のスナップショットを使用します。
db2 get snapshot for locks on sde > all_locks.txt db2 get snapshot for locks for application applid '*LOCAL.DB2.00AB42215335' > app_locks.txt db2 get snapshot for application applid '*LOCAL.DB2.00AB42215335' > app_info.txt
Application status = Lock-wait Locks held by application = 1254 Number of SQL requests since last commit = 12 Open local cursors = 1 Most recent operation = Execute Object type = Table Tablespace name = USERSPACE1 Table schema = SDE Table name = STATE_LINEAGES Mode = X Status = Converting Current mode = IX Lock escalation = YES
- 先に述べたように、ステート系統が深いと、大量の行がロックされる原因になります。次の SQL ステートメントで、ステート系統の深さとその最大値を簡単にチェックすることができます。
SELECT COUNT (*) FROM state_lineages GROUP BY lineage_name SELECT MAX(a.depth) FROM (SELECT COUNT (*) FROM state_lineages GROUP BY lineage_name) a(depth)
デッドロックに対処するためのパラメータ設定
ロック リストの設定を表示するには、次のコマンドを実行します。
db2 get db cfg
次に、このコマンドを実行した結果として返される情報の例を示します。
Max storage for lock list (4KB) (LOCKLIST) = 50 Interval for checking deadlock (ms) (DLCHKTIME) = 10000 Percent. of lock lists per application (MAXLOCKS) = 22 Lock time out (sec) (LOCKTIMEOUT) = -1 Max number of active applications (MAXAPPLS) = AUTOMATIC
これらのパラメータの設定については、IBM DB2 インフォメーション センターをご参照ください。