中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么淺析數據庫并發控制

發布時間:2021-12-02 11:27:30 來源:億速云 閱讀:161 作者:柒染 欄目:數據庫

怎么淺析數據庫并發控制,相信很多沒有經驗的人對此束手無策,為此本文總結了問題出現的原因和解決方法,通過這篇文章希望你能解決這個問題。

數據庫事務隔離發展標準一文中,從標準制定的角度介紹了數據庫的隔離級別,介紹了Read Uncommitted、Read Committed、Repeatable Read、Serializable等隔離級別的定義。下面就來看看究竟有哪些常見的實現事務隔離的機制,稱之為并發控制(Concurrency Control)。

原理

所謂并發控制,就是保證并發執行的事務在某一隔離級別上的正確執行的機制。需要指出的是并發控制由數據庫的調度器負責,事務本身并不感知,如下圖所示,Scheduler將多個事務的讀寫請求,排列為合法的序列,使之依次執行:

怎么淺析數據庫并發控制

這個過程中,對可能破壞數據正確性的沖突事務,調度器可能選擇下面兩種處理方式:

  • Delay:延遲某個事務的執行到合法的時刻

  • Abort:直接放棄事務的提交,并回滾該事務可能造成的影響

可以看出Abort比Delay帶來更高的成本,接下來我們就介紹不同的并發控制機制在不同情況下的處理方式。

分類

怎么淺析數據庫并發控制

如上圖所示,這里從橫縱兩個維度,對常見的并發控制機制進行分類:

1. 樂觀程度

不同的實現機制,基于不同的對發生沖突概率的假設,悲觀方式認為只要兩個事務訪問相同的數據庫對象,就一定會發生沖突,因而應該盡早阻止;而樂觀的方式認為,沖突發生的概率不大,因此會延后處理沖突的時機。如上圖橫坐標所示,樂觀程度從左向右增高:

  • 基于Lock:最悲觀的實現,需要在操作開始前,甚至是事務開始前,對要訪問的數據庫對象加鎖,對沖突操作Delay;

  • 基于Timestamp:樂觀的實現,每個事務在開始時獲得全局遞增的時間戳,期望按照開始時的時間戳依次執行,在操作數據庫對象時檢查沖突并選擇Delay或者Abort;

  • 基于Validation:更樂觀的實現,僅在Commit前進行Validate,對沖突的事務Abort

可以看出,不同樂觀程度的機制本質的區別在于,檢查或預判沖突的時機,Lock在事務開始時,Timestamp在操作進行時,而Validation在最終Commit前。相對于悲觀的方式,樂觀機制可以獲得更高的并發度,而一旦沖突發生,Abort事務也會比Delay帶來更大的開銷。

2. 單版本 VS 多版本

如上圖縱坐標所示,相同的樂觀程度下,還存在多版本的實現。所謂多版本,就是在每次需要對數據庫對象修改時,生成新的數據版本,每個對象的多個版本共存。讀請求可以直接訪問對應版本的數據,從而避免讀寫事務和只讀事務的相互阻塞。當然多版本也會帶來對不同版本的維護成本,如需要垃圾回收機制來釋放不被任何事物可見的版本。

需要指出的是這些并發控制機制并不與具體的隔離級別綁定,通過沖突判斷的不同規則,可以實現不同強度的隔離級別,下面基于Serializable具體介紹每種機制的實現方式。

基于Lock

基于Lock實現的Scheduler需要在事務訪問數據前加上必要的鎖保護,為了提高并發,會根據實際訪問情況分配不同模式的鎖,常見的有讀寫鎖,更新鎖等。最簡單地,需要長期持有鎖到事務結束,為了盡可能的在保證正確性的基礎上提高并行度,數據庫中常用的加鎖方式稱為兩階段鎖(2PL),Growing階段可以申請加鎖,Shrinking階段只能釋放,即在第一次釋放鎖之后不能再有任何加鎖請求。需要注意的是2PL并不能解決死鎖的問題,因此還需要有死鎖檢測及處理的機制,通常是選擇死鎖的事務進行Abort。

怎么淺析數據庫并發控制

Scheduler對沖突的判斷還需要配合Lock Table,如下圖所示是一個可能得Lock Table信息示意,每一個被訪問的數據庫對象都會在Lock Table中有對應的表項,其中記錄了當前最高的持有鎖的模式、是否有事務在Delay、以及持有或等待對應鎖的事務鏈表;同時對鏈表中的每個事務記錄其事務ID,請求鎖的模式以及是否已經持有該鎖。Scheduler會在加鎖請求到來時,通過查找Lock Table判斷能否加鎖或是Delay,如果Delay需要插入到鏈表中。對應的當事務Commit或Abort后需要對其持有的鎖進行釋放,并按照不同的策略喚醒等待隊列中Delay的事務。

怎么淺析數據庫并發控制

基于Timestamp

基于Timestamp的Scheduler會在事務開始時候分配一個全局自增的Timestamp,這個Timestamp通常由物理時間戳或系統維護的自增id產生,用于區分事務開始的先后。同時,每個數據庫對象需要增加一些額外的信息,這些信息會由對應的事務在訪問后更新,包括:

  • RT(X): 最大的讀事務的Timestamp

  • WT(X): 最大的寫事務的Timestamp

  • C(X): 最新修改的事務是否已經提交

基于Timestamp假設開始時Timestamp的順序就是事務執行的順序,當事務訪問數據庫對象時,通過對比事務自己的Timestamp和該對象的信息,可以發現與這種與開始順序不一致的情況,并作出應對:

  • Read Late:比自己Timestamp晚的事務在自己想要Read之前對該數據進行了寫入,并修改了WT(X),此時會Read不一致的數據。

  • Write Late: 比自己Timestamp晚的事務在自己想要Write之前讀取了該數據,并修改了RT(X),如果繼續寫入會導致對方讀到不一致數據。

這兩種情況都是由于實際訪問數據的順序與開始順序不同導致的,Scheduler需要對沖突的事務進行Abort。

  • Read Dirty:通過對比C(X),可以發現是否看到的是已經Commit的數據,如果需要保證Read Commit,則需要Delay事務到對方Commit之后再進行提交。

基于Validation(OCC)

基于Validation的方式,有時也稱為Optimistic Concurrency Control(OCC),大概是因為它比基于Timestamp的方式要更加的樂觀,將沖突檢測推遲到Commit前才進行。不同于Timestamp方式記錄每個對象的讀寫時間,Validation的方式記錄的是每個事物的讀寫操作集合。并將事物劃分為三個階段:

  • Read階段:從數據庫中讀取數據并在私有空間完成寫操作,這個時候其實并沒有實際寫入數據庫。維護當前事務的讀寫集合,RS、WS;

  • Validate階段:對比當前事務與其他有時間重疊的事務的讀寫集合,判斷能否提交;

  • Write階段:若Validate成功,進入Write階段,這里才真正寫入數據庫。

怎么淺析數據庫并發控制

同時,Scheduler會記錄每個事務的開始時間START(T),驗證時間VAL(T),完成寫入時間FIN(T),基于Validataion的方式假設事務Validation的順序就是事務執行的順序,因此驗證的時候需要檢查訪問數據順序可能得不一致:

  • RS(T)和WS(U) 是否有交集,對任何事務U,FIN(U) > START(T),如果有交集,則T的讀可能與U的寫亂序;

  • WS(T)和WS({U) 是否有交集,對任何事務U, Fin(U) > VAL(T),如果有交集,則T的寫可能與U的寫亂序。

Multiversion(MVCC)

對應上述每種樂觀程度,都可以有多版本的實現方式,多版本的優勢在于,可以讓讀寫事務與只讀事務互不干擾,因而獲得更好的并行度,也正是由于這一點成為幾乎所有主流數據庫的選擇。為了實現多版本的并發控制,需要給每個事務在開始時分配一個唯一標識TID,并對數據庫對象增加以下信息:

  • txd-id,創建該版本的事務TID

  • begin-ts及end-ts分別記錄該版本創建和過期時的事務TID

  • pointer: 指向該對象其他版本的鏈表

怎么淺析數據庫并發控制

其基本的實現思路是,每次對數據庫對象的寫操作都生成一個新的版本,用自己的TID標記新版本begin-ts及上一個版本的end-ts,并將自己加入鏈表。讀操作對比自己的TID與數據版本的begin-ts,end-ts,找到其可見最新的版本進行訪問。根據樂觀程度多版本的機制也分為三類:

1. Two-phase Locking (MV2PL)

與單版本的2PL方式類似,同樣需要Lock Table跟蹤當前的加鎖及等待信息,另外給數據庫對象增加了多版本需要的begin-ts和end-ts信息。寫操作需要對最新的版本加寫鎖,并生成新的數據版本。讀操作對找到的最新的可見版本加讀鎖訪問。

2. Timestamp Ordering (MVTO)

對比單版本的Timestamp方式對每個數據庫對象記錄的Read TimeStamp(RT),Write TimeStamp(WT),Commited flag(C)信息外增加了標識版本的begin-ts和end-ts,同樣在事務開始前獲得唯一遞增的Start TimeStamp(TS),寫事務需要對比自己的TS和可見最新版本的RT來驗證順序,寫入是創建新版本,并用自己的TS標記新版本的WT,不同于單版本,這個WT信息永不改變。讀請求讀取自己可見的最新版本,并在訪問后修改對應版本的RT,同樣通過判斷C flag信息避免Read Uncommitted。

3. Optimistic Concurrency Control (MVOCC)

對比單版本的Validataion(OCC)方式,同樣分為三個階段,Read階段根據begin-ts,end-ts找到可見最新版本,不同的是在多版本下Read階段的寫操作不在私有空間完成,而是直接生成新的版本,并在其之上進行操作,由于其commit前begin-ts為INF,所以不被其他事務課件;Validation階段分配新的Commit TID,并以之判斷是否可以提交;通過Validation的事務進入Write階段將begin-ts修改為Commit TID。

相對于悲觀的鎖實現,樂觀的機制可以在沖突發生較少的情況下獲得更好的并發效果,然而一旦沖突,需要事務回滾帶來的開銷要遠大于悲觀實現的阻塞,因此他們各自適應于不同的場景。而多版本由于避免讀寫事務與只讀事務的互相阻塞, 在大多數數據庫場景下都可以取得很好的并發效果,因此被大多數主流數據庫采用。可以看出無論是樂觀悲觀的選擇,多版本的實現,讀寫鎖,兩階段鎖等各種并發控制的機制,歸根接地都是在確定的隔離級別上盡可能的提高系統吞吐,可以說隔離級別選擇決定上限,而并發控制實現決定下限。

從樂觀悲觀的程度以及單版本多版本選擇上對可用的并發控制機制選擇進行了劃分,并介紹了各種機制大體的設計思路,而距離真正的實現還有比較大的距離,包括實現細節和配套機制。比如常用的各種類型的MVCC中,由于多版本的存在而帶來的一些列如垃圾回收、索引管理、版本存儲等相關問題。我們之后將以MyRocks為例看看并發控制在工程上的具體實現。

看完上述內容,你們掌握怎么淺析數據庫并發控制的方法了嗎?如果還想學到更多技能或想了解更多相關內容,歡迎關注億速云行業資訊頻道,感謝各位的閱讀!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

信丰县| 石林| 孟村| 乌鲁木齐市| 博客| 南汇区| 辉县市| 沐川县| 洪江市| 漳平市| 昂仁县| 泗阳县| 资讯| 道孚县| 古交市| 丽江市| 花莲市| 德安县| 福泉市| 青海省| 峨边| 汾阳市| 博爱县| 博白县| 赞皇县| 汉沽区| 诸暨市| 商水县| 镇平县| 清水河县| 合作市| 察隅县| 广元市| 沙湾县| 平罗县| 华坪县| 永康市| 棋牌| 旺苍县| 诸暨市| 县级市|