資料庫 - 併發控制
概述
多使用者資料庫系統
允許多個使用者同時使用的資料庫系統
特點: 在同一時刻併發執行的事務數可達數百上千個
多事務執行方式:
- 序列執行
順序執行 - 交叉併發(Interleaved Concurrency)
時間片輪轉 - 平行計算(simultaneous concurrency)
多處理機系統中,每個處理機可以真正的同時執行一個事務。所以:多個處理機可以真正的同時執行多個事務,此時成為並行
併發操作帶來的資料不一致性
- 丟失修改(Lost Update)
兩個事務T1和T2讀入同一資料並修改,T2的提交結果破壞了T1提交的結果,導致T1的修改被丟失。 - 不可重複讀(Non-repeatable Read)
不可重複讀是指事務T1讀取資料後,事務T2執行更新操作,使T1無法再現前一次讀取結果。 - 讀“髒”資料(Dirty Read)
讀“髒”資料是指:
-
- 事務T1修改某一資料,並將其寫回磁碟
-
- 事務T2讀取同一資料後,T1由於某種原因被撤銷
-
- 這時T1已修改過的資料恢復原值,T2讀到的資料就與資料庫中的資料不一致
-
- T2讀到的資料就為“髒”資料,即不正確的資料
併發控制的主要技術
封鎖(Locking)主流方案
時間戳(Timestamp)
樂觀控制法
多版本併發控制(MVCC)
封鎖(Locking)
什麼是封鎖
封鎖就是事務T在對某個資料物件(例如表、記錄等)操作之前,先向系統發出請求,對其加鎖。
加鎖後事務T就對該資料物件有了一定的控制,在事務T釋放它的鎖之前,其它的事務不能更新此資料物件。
基本封鎖型別
-
排它鎖(Exclusive Locks,簡記為X鎖)
排它鎖又稱為寫鎖
若事務T對資料物件A加上X鎖,則只允許T讀取和修改A,其它任何事務都不能再對A加任何型別的鎖,直到T釋放A上的鎖
保證其他事務在T釋放A上的鎖之前不能再讀取和修改A -
共享鎖(Share Locks,簡記為S鎖)
共享鎖又稱為讀鎖
若事務T對資料物件A加上S鎖,則事務T可以讀A但不能修改A,其它事務只能再對A加S鎖,而不能加X鎖,直到T釋放A上的S鎖
保證其他事務可以讀A,但在T釋放A上的S鎖之前不能對A做任何修改
封鎖協議
什麼是封鎖協議
在運用X鎖和S鎖對資料物件加鎖時,需要約定一些規則,這些規則為封鎖協議(Locking Protocol)。
考慮的問題:
- 何時申請X鎖或S鎖
- 持鎖時間
- 何時釋放
三級封鎖協議
一級封鎖協議
事務T在修改資料R之前必須先對其加X鎖,直到事務結束才釋放。
一級封鎖協議可防止丟失修改,並保證事務T是可恢復的。
在一級封鎖協議中,如果僅僅是讀資料不對其進行修改,是不需要加鎖的,所以它不能保證可重複讀和不讀“髒”資料。
二級封鎖協議
二級封鎖協議
一級封鎖協議加上事務T在讀取資料R之前必須先對其加S鎖,讀完後即可釋放S鎖。
二級封鎖協議可以防止丟失修改和讀“髒”資料。
在二級封鎖協議中,由於讀完資料後即可釋放S鎖,所以它不能保證可重複讀。
三級封鎖協議
三級封鎖協議
一級封鎖協議加上事務T在讀取資料R之前必須先對其加S鎖,直到事務結束才釋放。
三級封鎖協議可防止丟失修改、讀髒資料和不可重複讀。
活鎖和死鎖
活鎖
活鎖的情形:
事務T1封鎖了資料R
事務T2又請求封鎖R,於是T2等待。
T3也請求封鎖R,當T1釋放了R上的封鎖之後系統首先批准了T3的請求,T2仍然等待。
T4又請求封鎖R,當T3釋放了R上的封鎖之後系統又批准了T4的請求……
T2有可能永遠等待
產生原因: 有人插隊。
避免活鎖:
採用先來先服務的策略
- 當多個事務請求封鎖同一資料物件時
- 按請求封鎖的先後次序對這些事務排隊
- 該資料物件上的鎖一旦釋放,首先批准申請佇列中第一個事務獲得鎖
死鎖
活鎖的情形:
事務T1封鎖了資料R1
T2封鎖了資料R2
T1又請求封鎖R2,因T2已封鎖了R2,於是T1等待T2釋放R2上的鎖
接著T2又申請封鎖R1,因T1已封鎖了R1,T2也只能等待T1釋放R1上的鎖
這樣T1在等待T2,而T2又在等待T1,T1和T2兩個事務永遠不能結束,形成死鎖
產生死鎖的原因
兩個或多個事務都已封鎖了一些資料物件,然後又都請求對已為其他事務封鎖的資料物件加鎖,從而出現死等待。
解決死鎖的方法
1. 死鎖的預防
方式:
破壞產生死鎖的條件
預防死鎖的方法
(1)一次封鎖法
要求每個事務必須一次將所有要使用的資料全部加鎖,否則就不能繼續執行
存在的問題
- 降低系統併發度
- 很難事先精確確定封鎖物件
(2)順序封鎖法
2. 死鎖的診斷與解除
順序封鎖法是預先對資料物件規定一個封鎖順序,所有事務都按這個順序實行封鎖。
存在的問題
- 維護成本高
資料庫系統中封鎖的資料物件極多,並且隨資料的插入、刪除等操作而不斷地變化,要維護這樣的資源的封鎖順序非常困難,成本很高。 - 難以實現
事務的封鎖請求可以隨著事務的執行而動態地決定,很難事先確定每一個事務要封鎖哪些物件,因此也就很難按規定的順序去施加封鎖
總結:
在作業系統中廣為採用的預防死鎖的策略並不太適合資料庫的特點
資料庫管理系統在解決死鎖的問題上更普遍採用的是診斷並解除死鎖的方法
2. 死鎖的診斷與解除
死鎖的診斷
-
超時法
如果一個事務的等待時間超過了規定的時限,就認為發生了死鎖
優點:實現簡單
缺點
有可能誤判死鎖
時限若設定得太長,死鎖發生後不能及時發現 -
等待圖法
圖的限制:
事務等待圖是一個有向圖G=(T,U)
T為結點的集合,每個結點表示正執行的事務
U為邊的集合,每條邊表示事務等待的情況
若T1等待T2,則T1,T2之間劃一條有向邊,從T1指向T2
比如:
併發控制子系統週期性地(比如每隔數秒)生成事務等待圖,檢測事務。如果發現圖中存在迴路,則表示系統中出現了死鎖。
解除死鎖
- 選擇一個處理死鎖代價最小的事務,將其撤消
- 釋放此事務持有的所有的鎖,使其它事務能繼續執行下去