トランザクション処理(続) - 喜連川研究室

トランザクション処理(続)
東京大学生産技術研究所
概念情報工学研究センタ
喜連川優
Serializabilityの意義
 Serializability


If a schedule S is conflict equivalent to a serial schedule,
then S is correct.
オペレーションのインターリーブを可能とし、性能向上
に寄与
 Serializability test is quite difficult.



OS
事前スケジュール 現実的ではない。
適当に実行した後にserializabilityをチェック?
プロトコル
 現実的なアプローチ

スケジュールをテストする事無くserializabilityを
保証するプロトコルを考え出すこと。全てのトラ
ンザクションはそのプロトコルに従うものとする。
 プロトコル



Two phase lock protocol
Time Stamp
Multi-version
View Serializability
 これまでの議論はconflict serializability
 view equivalence
 Two schedules S and S’ are said to be view equivalent if the
following three conditions hold:



The same set of transactions participates in S and S’, and S and S’
include the same operations of those transactions.
For any operation ri(X) of Ti in S, if the value of X read by the
operation has been written by an operation wj(X) of Tj ( or if it is the
origin value of X before the schedule started), the same condition
must hold for the value of X read by operation ri(X) of Ti in S’.
If the operation wk(Y) of Tk is the last operation to write item Y in S,
then wk(Y) of Tk must also the last operation to write item Y in S’.
View equivalenceの意味
 個々のread操作が2つのスケジュールにおいて同じwrite操作の
結果を読むのであれば、read操作は2つのスケジュールにおいて
同じ世界を見る(view)ことになるので等価。
 Conflict serializabilityとview serializabilityは constrained write
assumptionが成り立つ限りにおいて等価
 Constrained write assumption:全てのwi(X)はそれに先立つri(X)
があり、それのみに依存。
 Unconstrained write assumptionにおいては view serializabilityは
より緩い。
より柔軟なスケジュール
 Conflict serializability は時として厳しすぎる
 例 debit-credit トランザクション





銀行口座への預け入れと引き出し操作
Serializableで無くとも、正しい結果を生成し得る。
T1:r1(X);X=X-10;w1(X);r1(Y);Y=Y+10;w1(Y);
T2:r2(Y);Y:=Y-20;w2(Y);r2(X);X:=X+20;w2(X);
Sh:r1(X);w1(X);r2(Y);w2(Y);r1(Y);w1(Y);r2(X);w
2(X);
SQLにおけるトランザクション
 Begin_trans文は無い。SQL文がトランザク
ションの開始を意味する。
 パラメータ



Access mode( read only, read write)
Diagnostic area size int.
Isolation level( read uncommitted, read
committed, repeatable read, serializable)
Isolation Level
 Isolation level
Type of violation

Dirty/Read Non-repeatable-read
Phantom
 Read uncommitted Y
Y
Y
 Read committed
N
Y
Y
 Repeatable read
N
N
Y
 Serializable
N
N
N
Isolation Levelの意味
 Dirty Read
 Nonrepeatable Read
 Phantom
Concurrency Control
同時実行制御方式
 ロックに基づく方式
 タイムスタンプに基づく方式
 多版制御方式
 楽観的制御方式
ロックに基づく方式
 Binary Locks:2つの状態を有する。
(locked, unlocked)



LOCK(X):ロックの状態 (1,0) (locked,
unlocked)
lock_item(X):
unlock_item(X):
ロック
 lock_item(X):






B: if LOCK(X)=0 (*if item is unlocked*)
then LOCK(X) ←1(* lock the item*)
else begin
wait (until LOCK(X)=0 and the lock
manager wakes up the transaction);
goto B
end;
 クリティカルセクションとして実装
アンロック
 unlock_item(X):
 LOCK(X) ← 0;(* unlock the item*)
 if any transaction are waiting

then wake up one of the waiting transactions
Binary Lock
 実装:極めて簡易
 ロックテーブル
 <data item name, LOCK, locking transaction>
+ 待ちトランザクションキュー
Shared/Exclusive Locks
 Binary Lockは制約が強すぎる。
 読む場合には多くのトランザクションが同時に読み出
すことを許すべき
 書き込む場合には排他制御が必須
 Multi-mode Lock



Shared/Exclusive Lock, 別名 read/write lock
3つの操作 read_lock, write_lock, unlock
LOCK(X): read-locked(shared-lock), write-locked(exclusivelock), unlockedの3状態
実装
 ロックテーブル構造



<data item name, LOCK, no_of_reads, locking_transaction(s)>
LOCKがwriteの時はnoは1, readの時は待ちトランザクション数
read_lock(X), write_lock(X), unlock(X)
read lock__
 read_lock(X):
 B: if LOCK(X)=‘unlocked’

then begin LOCK(X) ←‘read_locked’;

no_of_reads(X)←1

end

else if LOCK(X)=‘read_locked’

then no_of_reads(X)←no_of_reads(X) + 1

else begin wait(until LOCK(X)=‘unlocked’

and the lock manager wakes up the TR);

goto B

end;
write lock
 write_lock(X):
 B:if LOCK(X)=‘unlocked’
 then LOCK(X) ← ‘write_locked’
 else begin

wait(until LOCK(X)=‘unlocked’ and

the lock manager wake up TR);

gotoB

end;
unlock
 unlock(X):
 if LOCK(X)=‘write_locked’

then begin LOCK(X)←‘unlocked’

wakeup one of the waiting TR, if any

end

else if LOCK(X)=‘read_locked’

then begin

no_of_reads(X)←no_of_reads(X) ー1

if no_of_reads(X) = 0

then begin LOCK(X)←‘unlocked’;

wakeup one of TR, if any

end

end;
lock conversion
 最初にread_lock(X) , 後からwrite_lock(X)
にupgrade

Read_lockを持っているトランザクションが一つ
だけの場合、upgrade可能、そうでない場合は
待つ
 最初にwrite_lock(X),後からread_lock(X)に
downgrade
lockとserializability
 lockだけでは serializabilityを保証するも
のではない。
 次ページの例

Unlock操作が早すぎて適正な結果を生まない。
Unlockが早すぎる例 (C)は誤った結果を生む
Two Phase Lock
(2相ロック)
 Two phase locking protocol




全てのロック操作が終了した後、アンロックする
ロックフェーズとアンロックフェーズが分離
expanding/growing phase(ロック獲得)と
shrinking phase(ロック開放)に分離
Lock upgradeはexpanding phaseにおいて、lock
downgradeはshrinking phaseにおいて実行可
例の2相化









T1
read_lock(Y);
read_item(Y);
write_lock(X);
unlock(Y);
read_item(X);
X:=X+Y;
write_item(X);
unlock(X);
T2
read_lock(X);
read_item(X);
write_lock(Y);
unlock(X);
read_item(Y);
Y:=X+Y;
write_item(Y);
unlock(Y);
2相ロックとserializability
 全てのトランザクションが2相ロックプロトコルに従
う場合、当該スケジュールは直列可能である。
 2相ロックはある程度の並行性を犠牲にしている。
しかし、serializability チェック不要というメリットの
代償と言える。
Variations
 Basic 2PL:これまでの定義
 Conservative 2PL(Static 2PL)



トランザクションは実行開始以前に全てのロックを取得(predeclaration)
デッドロックフリー
実際には全てを申告するのは現実的でない
 Strict 2PL



コミット・アボート時点まで全てのexclusiveロックを開放しない。
Strict scheduleを実現
デッドロックフリーではない
 rigorous 2PL

コミット・アボート時点まで全てのロックを開放し
ない。
 conservative 2PL : shrinking phaseのみ
 rigorous 2PL: expanding phaseのみ
Deadlock and Starvation

T1
 read_lock(Y)
 read_item(Y)


 write_lock(X)

T2
read_lock(X)
read_item(X)
write_lock(Y)
Deadlock prevention protocol
 必要なロックを実行前に全て獲得する



Conservative 2PLで利用される手法
一つでもロック出来ないデータがあると、何れ
のデータもロックしない。一定時間待ち、リトライ
する。
現実的でない為実際には利用されることは無
い
Deadlock prevention
protocol(2)
 データベースの全てのデータに順番を付け
て、その順にロックする手法

プログラマが順序を気遣うのは非現実的
Transaction time stamp based
methods
 Timestamp TS(T) T:transaction, the starting time of the
transaction T.
 TiがXのロックを獲得しようとするが、Tjが既に当該ロックを有す
る場合の手順
 Wait-die: If TS(Ti) < TS(Tj),

then (Ti is older than Tj) Ti is allowed to wait;

otherwise(Ti is younger than Tj) abort Ti(Ti dies)
and
restart it later with the same timestamp
 Wound-wait: If TS(Ti) <TS(Tj)

then (Ti is older than Tj) abort Tj(Ti wound Tj) and restart it
later with the same timestamp;

otherwise (Ti younger than Tj) Ti is allowed to wait.
wait-dieとwound-die
 Wait-die

古いトランザクションは若いトランザクションを待つことが許される。
 Wound-wait: wait-dieの逆

古いトランザクションが若いトランザクションと競合すると若いトラン
ザクションをアボートする。
 両手法ともデッドロックフリー

常に待つ方向が一定。例えばwait-dieでは古い方が若い方を待つ
no waiting / cautious waiting
(デッドロックフリー)
 no waiting: もしロックが獲得出来ない場合、即座
にアボートする。不要なアボート多発するため、利
用困難
 cautious waiting: トランザクションTiがTjの有する
データをロックしようとした時を想定


If Tj is not blocked( not waiting for some other locked
item), then Ti is blocked, otherwise abort Ti.
No waitingの改良
Deadlock detection and timeouts
 Deadlockが発生しているかどうかをチェック
 トランザクション間の競合が少ないと予想される場
合は得策。
 長いトランザクション、多くのデータを参照するトラ
ンザクションでは不適切
 Wait-for graph


Ti → Tj : トランザクションTiがトランザクションTjの有
するロックを待つことを示す
サイクル:デッドロック
種々の側面
 いつデッドロック検出を行うか?


ロック待ち時間が閾値を越す場合
同時実行トランザクションが一定数を越える場合
 Victim selection

長時間走行し、多くの更新を行ったトランザクションを選択
しないようにする。
 タイムアウト

一定時間以上待ちが発生すると、デッドロックが実際に発
生しているかどうかによらず、アボートする。簡単に実装可
能なため良く利用される。
Starvation
 特定のトランザクションが長時間に渡り待たされ、
他のトランザクションは正常に処理される場合
 フェアなスケジューリングがなされていないことに
よる。
 プライオリティを付加しても良いが、待ち時間がた
つにつれて、プライオリティを上げる
 常にvictimに選択されないように、何度も選ばれる
とそのプライオリティを上げるなどして回避する。
Timestampに基づく
同時実行制御方式
 Timestamp




トランザクションを識別するためにDBMSによって生成
されたユニークな値
(通常)トランザクション投入時刻
TS(T)
ロックを利用しないので デッドロックフリー
 timestampの付け方


トランザクション毎に整数を付与。1づつ増やす
時刻を利用。完全に同時に2つのトランザクションが駆
動されることが無いことを保証しておく。
TOアルゴリズム
 タイムスタンプ順にserializableにする。
 したがって TO timestamp orderingと呼ばれる
 Read_TS(X): read timestamp of itemX


Xを読むことが出来たトランザクションのタイムスタンプ
の中で最大の値
Read_TS(X)=TS(T)

T:Xを読んだ最も若いトランザクション
 Write_TS(X): write timestamp of X

Xに書き込むことの出来たトランザクションのタイムスタ
ンプの値で最大のものを指す。
Basic TO algorithm




トランザクションTがread_item(X), write_item(Y)を発行す
る時点でトランザクションのタイムスタンプと read_TS(X),
write_TS(X)を比較。
トランザクションのタイムスタンプ順序が正しいかどうかを
チェック。
順序が不正な場合には当該トランザクションをアボート、
新しいタイムスタンプを付加して再投入
あるトランザクションがアボートするとそれの書いたデータ
を参照したトランザクションもアボートする必要がある
(cascade rollback)
Basic TO
 Tが write_item(X)を発行すると

If read_TS(X)>TS(T) or if write_TS(X)>TS(T)


Then abort and rollback T
Else write_item(X), set write_TS(X) to TS(T)
 Tが read_item(X)を発行すると


If write_TS(X)>TS(T) then abort and rollback T
If write_TS(X) <=TS(T), then read_item(X) and
set read_TS(X) to the larger of TS(T) and the current
readTS(X)
 特徴:


2PLと同様にserializable (許容クラスはそれぞれ異なる)
デッドロックフリー
Strict TO
 Strictにすることにより cascadeless
 TS(T)>write_TS(X)の場合、TS(T’)=write_TS(X)
なるT‘がコミットするまでread/writeを延期させる。
 実現のためには ロックに相当する機構が必要
となる(デッドロックフリー)
Thomas‘s Write
 Conflict serializabilityは保証されない。書き込み
rejectをより少なくする効果を有する。
 If read_TS(X)>TS(T) then abort and rollback T
 If write_TS(X)>TS(T)


then do not execute write operation but continue!
write_item(X) could be ignored. 問題が生じると上の条件
で検出される。
 If neither of the above conditions occurs,

Then execute the write_item(X) operation