資料庫複習8——並發,資料庫複習8

來源:互聯網
上載者:User

資料庫複習8——並發,資料庫複習8
資料庫複習CH15 並發15.1 並發的問題

由事務ACID性質的I(Isolation,獨立性),並發的事務間是透明的,穿插執行的事務會產生多種資料不一致問題(區別於資料庫不一致狀態):

  • Lost Update problem:事務TA更新一個資料X後,事務TB又更新資料X,導致TA對X的更新被衝掉,即TA中“看見”的X和資料庫中的X不一致
  • Uncommitted Dependency problem:TB更新了資料X後TA讀取X/更新X,但TB由於某種失敗rollback,導致TA中“看見”的X和資料庫中的X不一致
  • Inconsistent Analysis problem:TA是一個先於TB開始的事務(商務邏輯上的先於),但由於並發,先執行的TA中讀取了X後,後執行的TB修改X或修改了TA開始執行時刻對於TA本來一致的但TA還未讀取並即將讀取的資料Y,導致TA“看見”的資料X、Y和其執行時的X、Y不一致

註:事務並髮帶來的問題還有很多,上面只是原書作者的一種歸類方法

15.2 並發調度和序列化(1)定義

並發調度就是安排並發的事務的所有指令執行先後順序,並保持事務內部指令順序的操作;最常見的調度是串列調度,即多個事務仍然按照串列的順序一個接一個的執行全部指令,但顯然串列調度並發度極差

不是所有調度都能保證資料庫的一致性,但是我們總期待找到一個等價於串列調度的並行調度方案(即不破壞資料庫一致性的並行調度);一般稱這樣的調度是可序列化(Serializable)的

在考慮事務的序列化時作以下幾點假設:

  • 每個事務是保持資料庫一致性的,即沒有邏輯錯誤
  • 串列地執行一系列事務也是保持資料庫一致性的
  • 為了簡化,只考慮讀寫操作,讀寫之間可能會包含各種各樣的計算

定義事務間的兩條指令oi、oj存在衝突(Conflict)若且唯若oi、oj訪問同一資料項目X並至少有一條指令試圖write(X);定義兩調度S1、S2是衝突等價的,若且唯若S1可以通過交換一系列非衝突指令得到S2;顯然一個可序列化衝突等價於串列調度

(2)可串列性檢測

一般通過構造事務先序圖(事務間的有向圖)來檢測調度的可串列性;考慮並發事務集合T1,…,Tn,若Ti到Tj有弧,則Ti和Tj之間存在衝突指令Oi和Oj,並且在調度方案中Ti的衝突指令Oi靠前

構造好先序圖後根據如下定理判斷調度的可串列性:

一個調度是可串列的若且唯若它構造的先序圖無環,若先序圖無環可以通過拓撲排序構造無衝突的調度

(3)評價

可串列性檢測是事後發生的,並不適用於即時的並發控制!學習可串列性是為了更好地理解下面的並發協議

15.3 基於鎖的並發協議

鎖機制我們並不陌生,作業系統中處理進程、線程同步時很詳細地討論過
Lock(X)

並發中最簡單的鎖是二值鎖(也叫互斥鎖),一個事務Lock(X)只有等其Unlock(X)其他事務才能訪問;由於互斥鎖中只允許一個事務對同一資料訪問,因此不允許並發的讀操作,較為低效

更常用的高效的鎖是共用/獨佔鎖定(Shared/Exclusive Lock、S-X Lock)

(1)共用/獨佔鎖定

S-X鎖有共用和排他兩種狀態:

  • 通過Lock-S指令擷取共用鎖定,只能對擷取了共用鎖定的資料讀取操作
  • 通過Lock-X指令擷取獨佔鎖定,可以對擷取了獨佔鎖定的資料讀寫操作

對S-X鎖的申請由並發控制管理器管理,一個事務必須擷取了某種鎖才能繼續對某資料操作

S-X鎖協議如下:

  • 事務在retrieve元組t之前必須獲得t上的S鎖
  • 事務在upate元組t之前必須獲得t上的X鎖,若已有S鎖則需升級到X鎖
  • 如果事務A在元組t上有X鎖,則某其他事務B對t的任何一種鎖的申請都將被拒絕
  • 如果事務A在元組t上有S鎖,則某其他事務B對t的X鎖的申請將被拒絕,而對t的S鎖的申請將被允許
  • 如果對某個鎖的申請一直沒有被允許,事務將一直等待,直到其他事務釋放它申請的鎖
  • 通常commit和rollback時預設為釋放該事務申請的所有鎖

仔細思考上述對S-X鎖的描述,很容易發現會出現饑餓甚至是死結(死結的事務將強行釋放掉它們擁有的鎖並復原)

(2)兩階段鎖協議

兩階段鎖(Two Phase Lock)協議是一個能夠保證衝突可序列化調度方案的協議,兩階段鎖協議中事務劃分成兩個階段(兩階段之間的時間點稱作Lock Point):

兩階段鎖不能避免死結,除非加上限制條件[事務擷取的所有X鎖必須在事務結束時才被釋放],此時稱為嚴格的兩階段鎖協議

(3)自動擷取鎖

一般的資料庫語言中並不直接提供顯式鎖語句,而是將鎖協議嵌入到**原子的**read和write中,如下是一種實現方式:

READ(Ti, D) {    if Ti has no lock on D {        wait until no other T has a X-lock on D;        grant Ti a S-lock on D;    }    read(D);}WRITE(Ti, D) {    if Ti has no X-lock on D {        wait until no other T has any lock on D;        if Ti has a S-lock on D {            upgrade S-lock to X-lock;        } else {            grant Ti a X-lock on D;        }    }    write(D);}
(4)鎖機制的實現

一般鎖的實現由DBMS的lock manager完成,事務向lock manager發送上鎖和釋放鎖的請求,lock manager向事務發送批准(grant)申請、拒絕申請以及強制會滾的訊息(防止死結)

lock manager在名為lock table的雜湊表記錄鎖管理相關的資訊,以元組做索引,其中記錄批准鎖的事務列表(包括批准了什麼類型鎖)以及等待

15.5 鎖粒度(1)鎖的粒度

資料庫中資料的粒度從高層到底層分別是:資料庫、地區(不知道這是什麼)、檔案以及元組紀錄,可以針對不同粒度的資料上鎖

粒度較細是指對粒度層級較低的資料上鎖,這樣可以擷取更高並發度,但鎖管理開銷負載較大;粒度較粗是指對粒度層級較高的資料上鎖,這樣可以擷取低開銷的鎖管理,但並發度較低

(2)S-X鎖的粒度擴充——意圖鎖定

意圖鎖定(Intention Lock)的提出是基於一個運用粒度適中的鎖機制的資料庫系統,假設事務T申請某個關係變數R(即某表)上的X鎖,若全域掃描R中所有元組是否被其他事務鎖住,這樣開銷很大

因此為了檢測這樣粒度劃分後的鎖的衝突,必須完善X-S鎖協議,下列意圖鎖定協議應運而生:

  • IS意圖共用鎖:T對某個粒度的資料對象加IS鎖,表明T意欲對該對象的後繼節點(粒度層級更低的資料對象)設定S鎖,如T想要對R的元組t設定S鎖,則先要對關係變數R加IS鎖(或對R所在的資料庫加IS鎖)
  • IX意向獨佔鎖定:T對某個粒度的資料對象加IX鎖,表明T意欲對該對象的後繼節點(粒度層級更低的資料對象)設定X鎖
  • SIX共用意向獨佔鎖定:T對某個粒度的資料對象加SIX鎖,相當於先加S鎖再加IX鎖,例如需要讀關係變數R的所有元組並修改某些元組,則申請SIX鎖

基於意圖鎖定的多粒度擴充協議的基本原則就是:T要對某個資料對象上鎖,則需要對它上層節點上鎖,並且申請鎖時自上而下、釋放鎖時自下而上

15.5 死結處理

DBMS的事務並發管理器處理死結有兩種機制:死結預防死結檢測

(1)死結預防

死結預防顧名思義就是保證資料庫絕對不會進入死結狀態,一些策略如下:

  • 要求所有事務在開始執行操作前擷取所有需要的鎖,叫做預先申請
  • 事務對資料的上鎖順序取決於[偏序],類似於死結檢測中的等待圖
  • 設定事務等待鎖的時間上限,逾時則會滾事務,稱之為逾時策略
(2)死結檢測

死結檢測是去檢測等待圖(Wait-For Graph,一種描述事務鎖依賴的有向圖)是否成環的機制,當檢測到死結時選取部分鎖會滾或者直接所有事務會滾

等待圖中有:

  • 頂點V代表所有活躍的事務
  • 有向邊E=Ti->Tj表示Ti正在等待Tj釋放某個元組t上的鎖,並有Tj釋放鎖後Ti申請到時,刪除邊E

可以用有向圖成環檢測的演算法來檢測是否存在死結

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.