ディスク I/O の競合を抑えるようにデータベースを調整すると、デッドロックを軽減するのに役立ちます。それでも、new_edit_state ストアド プロシージャ呼び出しによって呼び出し元のアプリケーションがデッドロックに陥り、ジオデータベースが使用不能になることは決してめずらしいことではありません。
たとえば、ストアド プロシージャが STATE_LINEAGES テーブルから大量の行のロックを取得して、ロックの最大数を超えてしまい、テーブルの排他ロックへのエスカレーションを試みたとします。ところが、呼び出し元のアプリケーションのクエリがすでに STATE_LINEAGES テーブルの共有ロックを取得していたために、デッドロックに陥ってしまいます。ステート系統が深くなると、大量の行がロックされる原因になります。この場合、ロック リストのサイズが小さく設定されていれば、問題は避けられません。ロック エスカレーションの仕組みを理解すれば、デッドロックが発生する状況がこれだけではないことがわかります。
このことは、ユーザーのアプリケーションやデータベースの設定によっては、特定のサイトでのデッドロックの発生が決してめずらしくないことを意味します。繰り返しますが、ステート系統が深くなると、この問題が悪化する可能性があります。
幸い、IBM Db2 には、ロックリストのサイズ (LOCKLIST)、アプリケーションのロックがロック リストに占める割合 (MAXLOCKS)、リクエストがロックの取得を待つ時間の長さ (LOCKTIMEOUT)、デッドロック検知の間隔 (DLCHKTIME)、およびデッドロックのロールバック (DB2LOCK_TO_RB) を制御するチューニング パラメーターがあります。
ロック リストの容量とロック エスカレーションの閾値を引き上げるには、それぞれ LOCKLIST パラメーターと MAXLOCKS パラメーターを変更します。
LOCKLIST および MAXLOCKS のデフォルト値は AUTOMATIC であり、これらのパラメーターはセルフ チューニングされます。そのため、Db2 のメモリ チューナでは、メモリ消費が異なるときにメモリ リソースのサイズが動的に決定されます。自動チューニングが動作するのは、データベースでセルフ チューニング メモリが有効 (SELF_TUNING_MEM=ON) な場合だけです。
また、Db2 のロック保留レジストリ変数 DB2_EVALUNCOMMITED、DB2_SKIPDELETED、および DB2_SKIPINSERTED を使用してロックを回避すれば、同時実行性を改善することもできます。これらのレジストリ変数によって、コミットされていない削除と挿入がスキャンで無条件にスキップされます。
デフォルトでは、ロックがタイムアウトすると、リクエストされたトランザクションがロールバックします。Db2 のジオデータベースでは、このデフォルトの動作で十分です。
これらのパラメーターの適切な設定については、IBM Knowledge Center で Db2 のドキュメントをご参照ください。
以下では、デッドロックを診断するためのヒントについて説明します。
ロック問題の診断
次に、ロック問題を診断するのに役立つツールを紹介します。
- ArcGIS プロセスの 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)