成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

MVCC 機制的原理及實現

數據庫 其他數據庫
在InnoDB中的實現主要是為了提高數據庫并發性能,用更好的方式去處理讀-寫沖突,做到即使有讀寫沖突時,也能做到不加鎖,非阻塞并發讀,而這個讀指的就是快照讀,而非當前讀。當前讀實際上是一種加鎖的操作,是悲觀鎖的實現。而MVCC本質是采用樂觀鎖思想的一種方式。

什么是 MVCC

MVCC(Multiversion Concurrency Control)翻譯過來是多版本并發控制,和數據庫鎖一樣,也是一種并發控制的解決方案。

在InnoDB中的實現主要是為了提高數據庫并發性能,用更好的方式去處理讀-寫沖突,做到即使有讀寫沖突時,也能做到不加鎖,非阻塞并發讀,而這個讀指的就是快照讀,而非當前讀。當前讀實際上是一種加鎖的操作,是悲觀鎖的實現。而MVCC本質是采用樂觀鎖思想的一種方式。

快照讀

所謂快照讀,就是讀取的是快照數據,即快照生成的那一刻的數據,像我們常用的普通的SELECT語句在不加鎖情況下就是快照讀:

SELECT * FROM xx_table WHERE ...

注意:快照讀的前提是隔離級別不是串行級別,串行級別下的快照讀會退化成當前讀。

當前讀

當前讀讀取的是記錄的最新版本(最新數據,而不是歷史版本的數據),讀取時還要保證其他并發事務不能修改當前記錄,會對讀取的記錄進行加鎖。加鎖的SELECT,或者對數據進行增刪改都會進行當前讀:

SELECT * FROM xx_table LOCK IN SHARE MODE; #共享鎖
SELECT * FROM xx_table FOR UPDATE;         #排他鎖
INSERT INTO xx_table values ...        #排他鎖
DELETE FROM xx_table WHERE ...        #排他鎖
UPDATE xx_table SET ...         #排他鎖

解決什么問題

我們知道,在數據庫中,對數據的操作主要有2種,分別是讀和寫,而在并發場景下,就可能出現以下三種情況:

  • 讀-讀并發:不存在任何問題,也不需要并發控制
  • 讀-寫并發:有線程安全問題,可能會造成事務隔離性問題,可能遇到臟讀,幻讀,不可重復讀
  • 寫-寫并發:有線程安全問題,可能會存在更新丟失問題

在沒有寫的情況下讀-讀并發是不會出現問題的,而寫-寫并發這種情況比較常用的就是通過加鎖的方式實現。那么,讀-寫并發則可以通過MVCC的機制解決。

實現原理

Undo Log

undo log是Mysql中比較重要的事務日志之一,是一種用于回退的日志,在事務沒提交之前,MySQL會先記錄更新前的數據到undo log日志文件里面,當事務回滾時或者數據庫崩潰時,可以利用undo log來進行回退。

  • insert undo只在事務回滾時起作用,當事務提交后,該類型的undo日志就沒用了,它占用的Undo Log Segment也會被系統回收
  • update或delete時產生的undo log,不僅在事務回滾時需要,在快照讀時也需要;所以不能隨便刪除,只有在快速讀或事務回滾不涉及該日志時,對應的日志才會被purge線程統一清除

一條記錄在同一時刻可能有多個事務在執行,那么undo log會有一條記錄的多個快照,那么在這一時刻發生SELECT要進行快照讀的時候,要讀哪個快照呢?

行記錄的隱式字段

其實,數據庫中的每行記錄中,除了保存了我們自己定義的一些字段以外,還有一些重要的隱式字段的:

  • db_row_id:隱藏主鍵,如果我們沒有給這個表創建主鍵,那么會以這個字段來創建聚簇索引
  • db_trx_id:對這條記錄做了最新一次修改的事務的ID
  • db_roll_ptr:回滾指針,指向這條記錄的上一個版本,其實他指向的就是Undo Log中的上一個版本的快照的地址

注意:以上字段只有在聚簇索引的行記錄中才會有,而在普通二級索引中是沒有這些值的。

每一次記錄變更之前都會先存儲一份快照到undo log中,那么這幾個隱式字段也會跟著記錄一起保存在undo log中,就這樣,每一個快照中都有一個db_trx_id字段表示了對這個記錄做了最新一次修改的事務的ID ,以及一個db_roll_ptr字段指向了上一個快照的地址。(db_trx_id和db_roll_ptr是重點,后面還會用到)

這樣就形成了一個快照鏈表:

圖片圖片

有了undo log,又有了幾個隱式字段,我們好像還是不知道具體應該讀取哪個快照,那怎么辦呢?

Read View

Read View 是InnoDB中一個至關重要的概念,是實現MVCC的基礎,同時也是支持不同的事務隔離級別的基礎,同時提高系統的并發能力和性能。

Read View主要來幫我們解決可見性的問題的, 即他會來告訴我們本次事務應該看到哪個快照,不應該看到哪個快照。

  • 在可重復讀(Repeatable Read)級別下,快照(Read View)在事務開始后第一次查詢時創建一次,并在整個事務期間保持不變。
  • 在讀已提交(Read Committed)級別下,快照(Read View)會在每次查詢時重新創建,以反映數據庫中的最新提交更改。

在Read View中有幾個重要的屬性:

  • trx_ids,表示在生成Read View時當前系統中活躍的讀寫事務的事務id列表。
  • low_limit_id,應該分配給下一個事務的id值。
  • up_limit_id,未提交的事務中最小的事務ID。
  • creator_trx_id,創建這個Read View的事務ID。

Read View遵循一個可見性算法,主要是將要被修改的數據的最新記錄中的DB_TRX_ID(即當前事務ID )取出來,與系統當前其他活躍事務的ID去對比(由Read View 維護),如果DB_TRX_ID跟Read View的屬性做了某些比較,不符合可見性,那就通過DB_ROLL_PTR回滾指針去取出Undo Log中的DB_TRX_ID再比較,即遍歷鏈表的DB_TRX_ID(從鏈首到鏈尾,即從最近的一次修改查起),直到找到滿足特定條件的DB_TRX_ID,那么這個DB_TRX_ID所在的舊記錄就是當前事務能看見的最新老版本。

案例

假如一個ReadView的內容為:

trx_ids = [5,6,8)
low_limit_id = 8
up_limit_id = 5
creator_trx_id = 7

假設當前事務要讀取某一個記錄行,該記錄行的db_trx_id(即最新修改該行的事務ID)為 trx_id,那么,就有以下幾種情況了:

1、trx_id<up_limit_id,即小于5的事務,說明這些事務在生成ReadView之前就已經提交了,那么該事務的結果就是可見的。

2、trx_id>=low_limit_id,即大于8的事務,說明該事務在生成ReadView后才生成,所以該事務的結果就是不可見的。

3、up_limit_id<trx_id<low_limit_id,即大于等于5,小于8,這種情況下會再拿事務ID和Read View中的trx_ids進行逐一比較。

如果,事務ID在trx_ids列表中,如6,那么表示在當前事務開啟時,這個事務還是活躍的,那么這個記錄對于當前事務來說應該是不可見的。

如果,事務id不在trx_ids列表中,如7,那么表示的是在當前事務開啟之前,其他事務對數據進行修改并提交了,所以,這條記錄對當前事務就應該是可見的。

當然這里有個例外情況,那就是這個trx_id=creator_trx_id,那么就肯定是可見的

總結一下就是,一個事務能看到的是在他開始之前就已經提交的事務的結果,而未提交的結果都是不可見的。

當數據的事務ID不符合Read View規則時候,那就需要從undo log里面獲取數據的歷史快照,然后數據快照的事務ID再來和Read View進行可見性比較,如果找到一條快照,則返回,找不到則返回空。

總結

圖片圖片

在InnoDB中MVCC就是通過Read View + Undo Log來實現的,undo log中保存了歷史快照,而Read View用來判斷具體哪一個快照是可見的。

責任編輯:武曉燕 來源: 一安未來
相關推薦

2023-01-30 18:44:45

MVCC事務

2017-08-17 15:13:52

PostgreSQL MVCC機制

2021-11-04 08:16:50

MySQL SQL 語句數據庫

2021-04-06 06:23:18

MVCC并發事務

2014-06-13 11:08:52

Redis主鍵失效

2014-06-17 10:27:39

Redis緩存

2013-08-28 10:11:37

RedisRedis主鍵失效NoSQL

2010-10-12 14:22:41

PHP異常機制

2024-11-19 15:13:02

2023-12-27 18:16:39

MVCC隔離級別幻讀

2022-03-17 08:55:43

本地線程變量共享全局變量

2024-11-01 05:10:00

2023-10-31 10:51:56

MySQLMVCC并發性

2015-03-10 13:55:31

JavaScript預解析原理及實現

2025-05-20 05:53:07

DubboSPI機制

2018-08-20 16:00:23

MySQL并發控制MVCC

2024-08-12 14:37:38

2018-11-30 09:03:55

HTTP緩存Web

2018-06-05 08:58:38

Docker存儲容器

2017-03-02 10:49:37

推薦算法原理實現
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91免费版在线观看 | 国产传媒毛片精品视频第一次 | 国产精品久久久久久久久久久免费看 | 91视频精选| 一区二区三区四区国产 | 一区二区三区欧美 | 欧美日韩专区 | 欧美午夜精品理论片a级按摩 | 国产精品视频久久久 | 色一级片| 国产精品久久久久久久久免费 | 国产欧美在线 | 免费视频二区 | 国产亚洲精品久久久优势 | 亚洲一区免费 | 国产大学生情侣呻吟视频 | 黄网站免费在线看 | 精品网站999 | 亚洲精品福利在线 | 久久久久久久av麻豆果冻 | 国产成人久久精品 | 伊人网站| 亚洲国产欧美在线 | 久久不卡区 | 色综合色综合色综合 | 中文字幕 国产 | 欧美日韩精品在线一区 | 久艹网站 | 日韩欧美在线不卡 | 久久99久久久久 | 免费在线观看av片 | 在线国产视频 | 久久久xxx | 久草免费视 | 国产亚洲欧美日韩精品一区二区三区 | 欧美日韩中文字幕在线播放 | 午夜激情视频 | 欧美淫片 | 中文字幕一区二区三 | 亚洲精品在线免费观看视频 | 日日夜夜精品视频 |