3.4.12 行に掛かる排他制御の順序
HiRDBはSQLの最適化によって決定されたアクセスパスに従ってデータにアクセスします。通常,行排他の順序はこのアクセスパスによって決まります。ただし,SQL実行時の条件によって行排他の順序が異なるケースがあります。次に示すSQL実行時の条件では,行排他の順序が異なります。
-
パラレルサーバで,かつ複数のBESを使用してデータにアクセスする場合
-
スナップショット方式を適用する場合
ここでは,アクセスパスに従った行排他の順序,及び行排他の順序が異なるケースについて説明します。
(1) アクセスパスに従った行排他の順序
HiRDBはSQLの最適化によって決定されたアクセスパスに従ってデータにアクセスします。行排他の順序はこのアクセスパスによって決まります。
基本的なデータアクセスの順序を次に示す例で説明します。
- 例
-
- 実行するSQL:
select * from t1,t2 where t1.c1=t2.c1 and t1.c1>3
- [条件]
-
-
HiRDB/シングルサーバで実行します。
-
t1.c1及びt2.c1にインデクスを定義しています。
-
t1.c1のインデクスを用いてt1にアクセスします。
-
t1の各行に対してt2.c1のインデクスを用いてネストループジョインを行います。
-
t1.c1>3の条件でt1の行5,2,1,6がヒットし,インデクスによってこの順にアクセスします。
-
t1の行に対してヒットするt2行は次のとおりです。
・t1の行1に対してヒットするt2の行は6です。
・t1の行2に対してヒットするt2の行は2です。
・t1の行5に対してヒットするt2の行は4,及び7であり,インデクスによってこの順にアクセスします。
・t1の行6に対してヒットするt2の行は3,及び8であり,インデクスによってこの順にアクセスします。
-
スナップショット方式は適用しません。
-
(2) 行排他の順序が異なるケース
SQLを実行するときの条件によって行排他の順序が異なるケースについて説明します。
(a) HiRDB/パラレルサーバの場合
処理性能向上のために,表を並列に検索,又は更新する場合,HiRDBはデータの先読みや並列での読み込みをします。そのため,結合する表の間でのデータのアクセス順序がシングルサーバの場合と異なることがあります。アクセス順序が異なるため,行排他の順序も異なります。その結果,デッドロックが発生するおそれがあります。
- ●分割表検索の場合
-
分割表検索の場合の,データアクセスの順序を次に示す例で説明します。
- 例
-
実行するSQL:
select * from t1 where t1.c1>3
- [条件]
-
-
HiRDB/パラレルサーバで実行します。
-
表t1は,行1〜8をBES1に,行9〜16をBES2に分割して格納しています。
-
t1.c1>3の条件で,表T1の行1,2,5,6,10,11,14,15がヒットします。このとき,BES1中では行5,2,1,6の順序でインデクスによってアクセスします。BES2中では行10,14,11,15の順序でインデクスによってアクセスします。
-
スナップショット方式は適用しません。
-
- [説明]
-
各BES内でのアクセス順序は決まりますが,データの先読みや並列での読み込みが発生するため,BES1とBES2のアクセス順序は決まりません。また,BES1の行とBES2の行とのアクセス順序も決まりません。
- ●結合検索の場合
-
結合検索の場合の,データアクセスの順序を次に示す例で説明します。
- 例
-
実行するSQL:
select * from t1,t2 where t1.c1=t2.c1 and t1.c1>3
- [条件]
-
-
HiRDB/パラレルサーバで実行します。
-
t1.c1及びt2.c1にインデクスを定義しています。
-
t1.c1のインデクスを用いてt1にアクセスします。
-
t1の各行に対してt2.c1のインデクスを用いてネストループジョインを行います。
-
t1.c1>3の条件でt1の行5,2,1,6がヒットし,インデクスによってこの順にアクセスします。
-
t1の行に対してヒットするt2行は次のとおりです。
・t1の行1に対してヒットするt2の行は6です。
・t1の行2に対してヒットするt2の行は2です。
・t1の行5に対してヒットするt2の行は4,及び7であり,インデクスによってこの順にアクセスします。
・t1の行6に対してヒットするt2の行は3,及び8であり,インデクスによってこの順にアクセスします。
-
スナップショット方式は適用しません。
-
BES間の転送行数は2行です。
-
- [説明]
-
図中のA〜Dのアクセス順序は次のようになります。
-
A〜D各グループ内のアクセス順序は丸付き数字の順になります。
-
B,CのアクセスはAのアクセス後になります。
-
データの先読み,又は並列読み込みが発生するため,B,Cのアクセス順序は決まりません。
-
データの先読み,又は並列読み込みが発生するため,Bの行とCの行とのアクセス順序も決まりません。
-
(b) スナップショット方式を適用する場合
スナップショット方式を適用する場合,SQLを実行するたびに行排他の順序が異なります。
次の三つのケースについて,行に掛かる排他制御の順序を説明します。
-
スナップショット方式を適用する場合(同時実行するトランザクションなし)
-
スナップショット方式を適用する場合(同時実行するトランザクションあり)
-
スナップショット方式を適用しない場合
次のSQLを例とします。
- 例
select * from t1,t2 where t1.c1=t2.c1 and t1.c1>3
- ●スナップショット方式を適用する場合(同時に実行するトランザクションなし)
-
スナップショット方式を適用する場合で,参照するページ内に更新中の行(排他オプションWITH EXCLUSIVE LOCKで検索した行を含む)がないとき,ページ内のすべての行にまとめて排他を掛けます。
SQL実行時のデータアクセスの順序を次に示します。
- [説明]
-
-
表T1,T2の行1は,結合条件に指定した列の値が同じであることを示します。
-
表T1,T2の行はすべて同じページに格納されています。
-
- ●スナップショット方式を適用する場合(同時に実行するトランザクションあり)
-
スナップショット方式を適用する場合で,参照するページ内に更新中の行(排他オプションWITH EXCLUSIVE LOCKで検索した行を含む)があるとき,その直前の行までまとめて排他を掛けます。その後排他処理を打ち切り,それまでに排他を掛けた行を参照します。また,排他を掛けられなかった行については,実際に参照するときに排他を掛けます。
SQL実行時のデータアクセスの順序を次に示します。
- [説明]
-
-
表T1,T2の行1は,結合条件に指定した列の値が同じであることを示します。
-
表T1,T2の行はすべて同じページに格納されています。
-
表T1の行3に,ほかのトランザクションがEXモードで排他を掛けています。
-
スナップショット方式を適用して結合検索を行う場合,表又はインデクスを更新するUAPや,排他オプションWITH EXCLUSIVE LOCKで検索するUAPがほかに存在すると,同じSQLを実行しても行排他の順序が入れ替わります。
-
スナップショット方式は参照するページの排他をまとめて行うため,インデクスページスプリットが発生した場合でも行排他の順序が入れ替わります。
-
- ●スナップショット方式を適用しない場合
-
スナップショット方式を適用しない場合,一行ごとに排他を掛けます。
SQL実行時のデータアクセスの順序を次に示します。
- [説明]
-
表T1,T2の行1は,結合条件に指定した列の値が同じであることを示します。
(3) デッドロックの対処方法
行排他の順序が異なるケースでは,EXモードで行排他を掛けるUAPが加わることによって,同じSQLの同時実行であってもデッドロックが発生するおそれがあります。デッドロックの発生例を次に示します。
- [説明]
-
-
UAP1とUAP2はPRモードで行排他を掛けるUAPです。
-
UAP1とUAP2は同じSQLを実行するUAPですが,(2)で説明した理由によって,排他の順序が次のように異なります。
UAP1:行1→行2→行3の順序で排他を掛けます。
UAP2:行1→行3→行2の順序で排他を掛けます。
-
UAP3とUAP4はEXモードで行排他を掛けるUAPです。
-
デッドロックの対処方法を次に示します。
-
排他オプションにWITHOUT LOCK NOWAIT又はWITHOUT LOCK WAITを指定して検索を行う。
-
IN EXCLUSIVE MODEのLOCK TABLE文を実行してから検索を行う。
-
トランザクションを再実行する。
デッドロックが発生した場合については,「デッドロックと回避策」を参照してください。