MySql的併發控制和故障恢復技術

2021-09-23 06:08:50 字數 3888 閱讀 9242

併發控制技術是實現事務隔離性以及不同隔離級別的關鍵,實現方式有很多,按照其對可能衝突的操作採取的不同策略可以分為樂觀併發控制和悲觀併發控制兩大類。

基於封鎖的併發控制

核心思想:對於併發可能衝突的操作,比如讀-寫,寫-讀,寫-寫,通過鎖使它們互斥執行。

鎖通常分為共享鎖和排他鎖兩種型別

1.共享鎖(s):事務t對資料a加共享鎖,其他事務只能對a加共享鎖但不能加排他鎖。

2.排他鎖(x):事務t對資料a加排他鎖,其他事務對a既不能加共享鎖也不能加排他鎖

基於鎖的併發控制流程:

事務根據自己對資料項進行的操作型別申請相應的鎖(讀申請共享鎖,寫申請排他鎖)

申請鎖的請求被傳送給鎖管理器。鎖管理器根據當前資料項是否已經有鎖以及申請的和持有的鎖是否衝突決定是否為該請求授予鎖。

若鎖被授予,則申請鎖的事務可以繼續執行;若被拒絕,則申請鎖的事務將進行等待,直到鎖被其他事務釋放。

可能出現的問題:

對於可能發生衝突的併發操作,鎖使它們由並行變為序列執行,是一種悲觀的併發控制。

基於時間戳的併發控制

核心思想:對於併發可能衝突的操作,基於時間戳排序規則選定某事務繼續執行,其他事務回滾。

系統會在每個事務開始時賦予其乙個時間戳,這個時間戳可以是系統時鐘也可以是乙個不斷累加的計數器值,當事務回滾時會為其賦予乙個新的時間戳,先開始的事務時間戳小於後開始事務的時間戳。

每乙個資料項q有兩個時間戳相關的字段:

時間戳排序規則如下:

假設事務t發出read(q),t的時間戳為ts

a.若ts(t)=w-timestamp(q),則執行read操作,同時把

r-timestamp(q)設定為ts(t)與r-timestamp(q)中的最大值

假設事務t發出write(q)

a.若ts(t)基於時間戳排序和基於鎖實現的本質一樣:對於可能衝突的併發操作,以序列的方式取代併發執行,因而它也是一種悲觀併發控制。它們的區別主要有兩點:

基於有效性檢查的併發控制

核心思想:事務對資料的更新首先在自己的工作空間進行,等到要寫回資料庫時才進行有效性檢查,對不符合要求的事務進行回滾。

基於有效性檢查的事務執行過程會被分為三個階段:

有效性檢查通常也是通過對事務的時間戳進行比較完成的,不過和基於時間戳排序的規則不一樣。

該方法允許可能衝突的操作併發執行,因為每個事務操作的都是自己工作空間的區域性變數,直到有效性檢查階段發現了衝突才回滾。因而這是一種樂觀的併發策略。

基於快照隔離的併發控制

快照隔離是多版本併發控制(mvcc)的一種實現方式。

其核心思想是:資料庫為每個資料項維護多個版本(快照),每個事務只對屬於自己的私有快照進行更新,在事務真正提交前進行有效性檢查,使得事務正常提交更新或者失敗回滾。

由於快照隔離導致事務看不到其他事務對資料項的更新,為了避免出現丟失更新問題,可以採用以下兩種方案避免:

事務間可能衝突的操作通過資料項的不同版本的快照相互隔離,到真正要寫入資料庫時才進行衝突檢測。因而這也是一種樂觀併發控制。

關於併發控制技術的總結

以上只是對常見的幾種併發控制技術進行了介紹,不涉及特別複雜的原理的講解。之所以這麼做一是要真的把原理和實現細節講清楚需要涉及的東西太多,篇幅太長,從作者和讀者角度而言都不是一件輕鬆的事,所以只對其實現的核心思想和實現要點進行了簡單的介紹,其他部分就一筆帶過了。二是併發控制的實現的方式太過多樣,基於封鎖的實現就有很多變體,mvcc多版本併發控制的實現方式就更是多樣,而且很多時候會和其他併發控制方式比如封鎖的方式結合起來使用。

通常使用的mysql innodb引擎在資料庫層面上使用悲觀鎖的方式來控制併發事物,而為了提公升資料庫併發的效能,程式設計時可採用樂觀鎖的模式,避免加鎖,即在表中新增版本號或者時間戳字段通過有效性檢查來作為是否可以成功提交的關鍵因素。

詳細可參考:

為什麼需要故障恢復技術

資料庫執行過程中可能會出現故障,這些故障包括事務故障和系統故障兩大類

這些故障可能會對事務和資料庫狀態造成破壞,因而必須提供一種技術來對各種故障進行恢復,保證資料庫一致性,事務的原子性以及永續性。資料庫通常以日誌的方式記錄資料庫的操作從而在故障時進行恢復,因而可以稱之為日誌恢復技術。

事務的執行過程以及可能產生的問題

事務的執行過程可以簡化如下:

由於資料庫存在立即修改和延遲修改,所以在事務執行過程中可能存在以下情況:

日誌的種類和格式

- :描述一次資料庫寫操作,t是執行寫操作的事務的唯一標識,x是要寫的資料項,v1是資料項的舊值,v2是資料項的新值。

- :對資料庫寫操作的撤銷操作,將事務t的x資料項恢復為舊值v1。在事務恢復階段插入。

- : 事務t開始

- : 事務t提交

- : 事務t中止

關於日誌,有以下兩條規則

日誌恢復的核心思想

撤銷事務undo:將事務更新的所有資料項恢復為日誌中的舊值,事務撤銷完畢時將插入一條 「t abort」 記錄。

重做事務redo:將事務更新的所有資料項恢復為日誌中的新值。

事務正常回滾/因事務故障中止將進行redo

系統從崩潰中恢復時將先進行redo再進行undo。

以下事務將進行undo:日誌中只包括"t start"記錄,但既不包括"t commit"記錄也不包括"t abort"記錄.

以下事務將進行redo:日誌中包括"t start"記錄,也包括"t commit"記錄或"t abort"記錄。

假設系統從崩潰中恢復時日誌記錄如下

由於t0既有start記錄又有commit記錄,將會對事務t0進行重做,執行相應的redo操作。

由於t1只有start記錄,將會對t1進行撤銷,執行相應的undo操作,撤銷完畢將寫入一條abort記錄。

事務故障中止/正常回滾的恢復流程

系統崩潰時的恢復過程(帶檢查點)

檢查點是形如的特殊的日誌記錄,l是寫入檢查點記錄時還未提交的事務的集合,系統保證在檢查點之前已經提交的事務對資料庫的修改已經寫入磁碟,不需要進行redo。檢查點可以加快恢復的過程。

系統崩潰時的恢復過程分為兩個階段:重做階段和撤銷階段。

重做階段:

撤銷階段:

總結:先將日誌記錄中所有事務的更新按順序重做一遍,在針對需要撤銷的事務按相反的順序執行其更新操作的撤銷操作。

乙個系統崩潰恢復的例子

恢復前的日誌如下,寫入最後一條日誌記錄後系統崩潰

//之前t2已經commit,故不用重做

//t0回滾完成,插入該記錄後系統崩潰

事務是資料庫系統進行併發控制的基本單位,是資料庫系統進行故障恢復的基本單位,從而也是保持資料庫狀態一致性的基本單位。acid是事務的基本特性,資料庫系統是通過併發控制技術和日誌恢復技術來對事務的acid進行保證的,從而可以得到如下的關於資料庫事務的概念體系結構。

mysql事務提交過程(一)

資料庫日誌redo和undo

這篇博文中有提到innodb引擎經過優化後,最終把redo-log和undo-log合併,放到redo-log中,減少磁碟i/o操作)

mysql 併發控制 mysql併發控制

mysql併發控制 當有多個查詢需要同時修改同乙個資料,就會產生併發控制的問題。mysql可以在兩個層面進行併發控制 伺服器層和儲存引擎層。mysql通過加鎖實現併發控制 鎖有兩類 讀鎖 共享鎖,即乙個讀鎖不會阻塞其它讀鎖,多個使用者可同時讀取同乙個資源,而不互相干擾。寫鎖 排他鎖,即乙個寫鎖會阻塞...

mysql 併發控制

1 多個執行緒同時修改資料,存在資料不一致的情況,也就是併發控制的問題。2 mysql提供讀鎖和寫鎖,讀鎖之上可以再加讀鎖,不能加寫鎖,而寫鎖之上不能加任何鎖。也就是說,讀鎖是共享的,寫鎖是排他的。3 鎖粒度,為了更好的併發控制,鎖的粒度應該盡可能小,也就是只鎖定修改的資料。但是,鎖本身也有一定的開...

mysql併發控制

mysql併發控制 當有多個查詢需要同時修改同乙個資料,就會產生併發控制的問題。mysql可以在兩個層面進行併發控制 伺服器層和儲存引擎層。mysql通過加鎖實現併發控制 鎖有兩類 讀鎖 共享鎖,即乙個讀鎖不會阻塞其它讀鎖,多個使用者可同時讀取同乙個資源,而不互相干擾。寫鎖 排他鎖,即乙個寫鎖會阻塞...