3.4.8 残存エントリによる排他待ちの回避(行識別子の再利用抑止)
インデクスキー値無排他を適用している場合,インデクスのキー値を削除した際に,インデクス格納ページに残存エントリが発生します。この場合,複数のトランザクションでINSERT文,UPDATE文,又はDELETE文を実行したり,定義系SQL文やpdmodを繰り返し実行したりすると,異なるインデクスキー値の操作であっても排他待ちが発生することがあります。ユーザ表の排他待ち発生例を次の図に示します。
- [説明]
-
-
インデクスページには,キーAが格納されています。キーAは,データAの行識別子を持っています。
データページには,データAが格納されています。また,データページの管理領域には,データAに対応するスロット(行識別子)があります。
キーAとデータAは,このスロットが示す行識別子によって関連づけられています。
-
トランザクション1によってキーA及びデータAが削除されます。このとき,トランザクション1は決着します。
-
インデクスキー値無排他を適用しているため,インデクスページのキーAは残存エントリとなります。
データページでは,データAが削除され空き領域ができます。また,スロットの情報も削除され,空きスロットができます。
-
トランザクション2によってキーB及びデータBが追加されます。このとき,トランザクション2は未決着です。
-
未使用領域にデータBが入らないため,データページではページコンパクションが発生します。
-
インデクスページにキーBが格納されます。
データページにはデータBが格納されます。このとき,空きスロットが存在するため,データBの行識別子はこの空きスロットを再利用します。
なお,トランザクション2は未決着のため,キーB(データB)はこのスロットに排他を掛けたままになっています。
-
トランザクション3によって再びキーA及びデータA’が追加されます。
-
キーAには残存エントリがあるため,その残存エントリが前回使用していたスロットを再利用できるかどうか確認します。このとき,スロットは既にキーB(データB)によって排他が掛けられているため,排他待ちが発生します。
-
この排他待ちは,行識別子の割り当て方法を変えることで回避できます。行識別子は,データを一意に識別するためにシステムが割り当てますが,行が削除されると,その行識別子は再利用されます。同様に,行識別子に対応していたスロットも再利用されます。そのため,残存エントリによる排他待ちが発生してしまいます。この行識別子の再利用を抑止することによって,スロットも再利用されなくなり,排他待ちを回避できます。行識別子の再利用抑止による排他待ちの回避例を次の図に示します。
- [説明]
-
-
インデクスページには,キーAが格納されています。キーAは,データAの行識別子を持っています。
データページには,データAが格納されています。また,データページの管理領域には,データAに対応するスロット(行識別子)があります。
キーAとデータAは,このスロットが示す行識別子によって関連づけられています。
-
トランザクション1によってキーA及びデータAが削除されます。このとき,トランザクション1は決着します。
-
インデクスキー値無排他を適用しているため,インデクスページのキーAは残存エントリとなります。
データページでは,データAが削除され空き領域ができます。また,スロットの情報も削除され,空きスロットができます。
-
トランザクション2によってキーB及びデータBが追加されます。このとき,トランザクション2は未決着です。
-
未使用領域にデータBが入らないため,データページではページコンパクションが発生します。
-
インデクスページにキーBが格納されます。
データページには,データBが格納されます。データBの行識別子には,新たなスロットが割り当てられます。このとき,トランザクション2は未決着のため,キーB(データB)はこのスロットに排他を掛けたままになっています。
-
トランザクション3によって再びキーA及びデータA’が追加されます。
-
データA’の行識別子にも新たなスロットが割り当てられるため,排他待ちは発生しません。
-
- 〈この項の構成〉
(1) 適用基準
行識別子の再利用を抑止すると,ページ内の管理領域(行識別子に対応するスロットの数)が増えるため,格納効率が低下する場合があります。
そのため,格納効率を下げてでも残存エントリの排他待ちを回避したい場合に適用してください。
格納効率の詳細は,「格納効率が低下するケース」を参照してください。
(2) 指定方法
行識別子の再利用を抑止するには,システム共通定義のpd_dbreuse_remaining_entriesオペランドにALL以外を指定します。
なお,pd_dbreuse_remaining_entriesオペランドの指定値によって,排他待ちの軽減対象が異なります。詳細は,マニュアル「HiRDB システム定義」の「排他制御に関するオペランド」を参照してください。
(3) 格納効率が低下するケース
行識別子を再利用しない場合,INSERT文,UPDATE文,及びDELETE文を頻繁に実行したり,定義系SQL文やpdmodを繰り返し実行したりすると,ページ内の管理領域(行識別子に対応するスロットの数)が極端に増加します。管理領域は,1ページ当たり最大で次の値まで増加します。
1スロットの容量2バイト×1ページ当たりの最大格納行数255行=510バイト
そのため,次のような場合は,1ページに格納できるデータの件数が減少し,格納効率が低下することがあります。
-
1件ごとのデータサイズが大きい,又はページサイズが小さいため,1ページ当たりのデータ件数が少ない場合
-
未使用領域に余裕を持たせた見積もりをしていない場合
ユーザ表での行識別子の再利用抑止によって格納効率が低下する場合の例を次の図に示します。
この例では,データページのサイズが5,000バイトで,1件のデータサイズが1,500バイトとします。行識別子の再利用を抑止している状態で,データの挿入と削除を繰り返します。
- [説明]
-
-
データの挿入と削除を繰り返します。行識別子の再利用を抑止しているため,その都度使用済みの空きスロットが増加します。
-
未使用領域が494バイトとなり,1,500バイトのデータが挿入できなくなったところで,ページコンパクションが発生します。このとき,空きスロットはそのまま残ります。
-
さらに挿入と削除を繰り返し,空きスロットが250個(500バイト)になります。
-
ここでデータを挿入すると,新たなスロットが3件目のデータ領域を使用してしまいます。そのため,次にデータを挿入するときにはページコンパクションが発生します。以降,このページには2件のデータしか格納できなくなり,格納効率が低下します。
-
なお,スロット数が1ページ当たりの最大格納行数である255に達した場合は,ページ内に存在する残存エントリの中で行識別子の値が一番小さいものから順に再利用されます。