InnoDB的MVCC機制

在講解InnoDB的MVCC機制之前,我們應該了解MySQL所支持的事務,以及各個事務級別的區別和每一個事務級別所存在的問題。

1. 事務

事務必須保證ACID,而ACID表示原子性、一致性、隔離性和持久性

1.1 事務的隔離級別

事務可以通過start transaction語句開始一個事務,然后要么使用commit提交事務將所修改的數據持久保存,要么使用rollback撤銷所有修改

1.1.2 READ UNCOMMITTED (未提交讀 RU)

在READ UNCOMMITTED級別,事務中的修改,即使沒有提交,對其他事務也都是可見的。事務可以讀取未提交的數據,這也被稱為臟讀

1.1.3 READ COMMITTED (提交讀 RC)

大多數的數據庫系統的默認隔離級別都是READ COMMITTED(MySQL 不是)。READ COMMITTED滿足前面提到的隔離級別的簡單定義:一個事務開始時,只能“看見” 已提交的事務所做的修改。換句話說,一個事務從開始知道提交之前,所做的任何修改對其他事務都是不可見的。這個級別也叫不可重復讀,因為在同一事務內執行兩次相同的查詢,可能會得到不一樣的結果。

例子: 當事務的隔離級別在RC級別的時候,事務A和事務B同時對數據D操作,當事務A開始的時候,讀取的數據D保存下來了,這是事務B也在修改數據D,并且先于事務A提交。這是事務A再讀數據D的時候,就會出現前后不一致情況,這就是所謂的不可重復讀。

1.1.4 REPEATABLE READ (可重復讀 RR)

這是MySQL的默認事務隔離級別,它確保同一事務的多個實例在并發讀取數據時,會看到同樣的數據行。不過理論上,這會導致另一個棘手的問題:幻讀 (Phantom Read)。簡單的說,幻讀指當用戶讀取某一范圍的數據行時,另一個事務又在該范圍內插入了新行,當用戶再讀取該范圍的數據行時,會發現有新的“幻影” 行。InnoDB和Falcon存儲引擎通過多版本并發控制(MVCC,Multiversion Concurrency Control)機制解決了該問題。

例子:mysql的默認事務隔離級別是RR級別的,同樣是上述例子,當時不同的是當事務A和事務B開始的時候,都保存一份自己的快照,每一份快照中都有數據D的值,所以這樣在同一事務中,無論重讀讀多少次都是正確的。

例子:在RR級別中,可能出現幻讀。同樣是上述例子,事務A和事務B同時查詢數據D,事務A發現數據D為空,就想插入數據,但是這是事務B已經插入了數據D并且已經提交。這時事務A的提交就會出錯。這是因為事務A的寫操作是當前讀操作。

1.1.5 SERIALIZABLE (可串行化 S)

這是最高的隔離級別,它通過強制事務排序,使之不可能相互沖突,從而解決幻讀問題。簡言之,它是在每個讀的數據行上加上共享鎖。在這個級別,可能導致大量的超時現象和鎖競爭。

隔離級別 臟讀可能性 不可重復可能性 幻讀可能性 加鎖讀
READ UNCOMMITTED Yes Yes Yes No
READ COMMITTED No Yes Yes No
REPEATABLE READ No No Yes No
SERIALIZABLE No No No Yes

2. MVCC機制

InnoDB的一致性的非鎖定讀就是通過在MVCC實現的,Mysql的大多數事務型存儲引擎實現的都不是簡單的行級鎖。基于提升并發性能的考慮,它們一般都同時實現了多版本并發控制(MVCC)。MVCC的實現,是通過保存數據在某一個時間點的快照來實現的。因此每一個事務無論執行多長時間看到的數據,都是一樣的。所以MVCC實現可重復讀。

  • 快照讀:select語句默認,不加鎖,MVCC實現可重復讀,使用的是MVCC機制讀取undo中的已經提交的數據。所以它的讀取是非阻塞的
  • 當前讀:select語句加S鎖或X鎖;所有的修改操作加X鎖,在select for update 的時候,才是當地前讀。

RR隔離級別下的快照讀,不是以begin開始的時間點作為snapshot建立時間點,而是以第一條select語句的時間點作為snapshot建立的時間點。

2.1. MVCC依賴數據

行記錄隱藏字段

  • db_row_id,行ID,用來生成默認聚簇索引(聚簇索引,保存的數據在物理磁盤中按順序保存,這樣相關數據保存在一起,提高查詢速度)
  • db_trx_id,事務ID,新開始一個事務時生成,實例內全局唯一
  • db_roll_ptr,undo log指針,指向對應記錄當前的undo log
  • deleted_bit,刪除標記位,刪除時設置

undo log

  • 用于行記錄回滾,同時用于實現MVCC


    圖片1.png

2.2 操作方式

  1. update
  • 行記錄數據寫入undo log,事務的回滾操作就需要undo log
  • 更新行記錄數據,當前事務ID寫入db_trx_id,undo log指針寫入db_roll_ptr
  1. delete
  • 和update一樣,只增加deleted_bit設置
  1. insert
  • 生成undo log
  • 插入行記錄數據,當前事務ID寫入db_trx_id, db_roll_ptr為空

這樣設計使得讀操作很簡單,性能很好,并且也能保證只會讀到符合標準的行,不足之處是每行記錄都需要額外的儲存空間,需要做更多的行檢查工作,以及額外的維護工作

2.3 MVCC如何實現RR

  • RR定義:在一個事務內同一快照讀執行任意次數,得到的數據一致;且只能讀到第一次執行前已經提交的數據或本事務內更改的數據
  • 原理:對符合查詢條件的記錄進行可見性判斷就是那些數據本事務可以看見,那些數據看不見
  • read view:記錄當前處于活動狀態的所有事務ID,RR級別下,第一次快照讀時創建,RC級別下,每次快照讀均會創建新的
  • 缺點: 可能出現幻讀
圖片2.png
圖片3.png

3 總結

在事務隔離級別為RC和RR級別下, InnnoDB存儲引擎使用的才是多版本并發控制。然而,對于快照數據的定義卻不相同。在RC事務隔離級別下,對于快照數據(undo端數據),總是讀取被鎖定行的最新的一份快照數據。而在RR事務隔離級別下,對于快照數據,多版本并發控制總是讀取事務開始時的行數據。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,327評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,996評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,316評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,406評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,128評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,524評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,576評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,759評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,310評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,065評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,249評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,821評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,479評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,909評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,140評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,984評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,228評論 2 375

推薦閱讀更多精彩內容