久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

MySQL多版本并發控制機制源碼分析

141次閱讀
沒有評論

共計 2575 個字符,預計需要花費 7 分鐘才能閱讀完成。

本篇內容主要講解“MySQL 多版本并發控制機制源碼分析”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓丸趣 TV 小編來帶大家學習“MySQL 多版本并發控制機制源碼分析”吧!

MVCC(多版本并發控制機制)

隔離性也可以被稱作并發控制、可串行化等。談到并發控制首先想到的就是鎖,MySQL 通過使用兩階段鎖的方式實現了更新的可串行化,同時為了加速查詢性能,采用了 MVCC(Multi Version Concurrency Control)的機制,使得不用鎖也可以獲取一致性的版本。

Repeatable Read

MySQL 的通過 MVCC 以及 (Next-Key Lock) 實現了可重復讀 (Repeatable Read), 其思想(MVCC) 就是記錄數據的版本變遷,通過精巧的選擇不同數據的版本從而能夠對用戶呈現一致的結果。如下圖所示:

上圖中,(A=50|B=50)的初始版本為 1。

1. 事務 t1 在 select A 時候看到的版本為 1,即 A =50

2. 事務 t2 對 A 和 B 的修改將版本升級為 2, 即 A =0,B=100

3. 事務 t1 再此 select B 的時候看到的版本還是 1, 即 B =50

這樣就隔離了版本的影響,A+ B 始終為 100。

Read Commit

而如果不通過版本控制機制,而是讀到最近提交的結果的話,則隔離級別是 read commit, 如下圖所示:

在這種情況下,就需要使用鎖機制 (例如 select for update) 將此 A,B 記錄鎖住,從而獲得正確的一致結果, 如下圖所示:

MVCC 的優勢

當我們要對一些數據做一些只讀操作來檢查一致性,例如檢查賬務是否對齊的操作時候,并不希望加上對性能損耗很大的鎖。這時候 MVCC 的一致性版本就有很大的優勢了。

MVCC(實現機制)

本節就開始談談 MVCC 的實現機制, 注意 MVCC 僅僅在純 select 時有效(不包括 select for update,lock in share mode 等加鎖操作, 以及 updateinsert 等)。

select 運行棧

首先我們追蹤一下一條普通的查詢 sql 在 mysql 源碼中的運行過程,sql 為(select * from test);

其運行棧為:

由于 mysql 默認隔離級別是 repeatable_read(RR), 所以 read_record 重載為 rr_sequential(當前我們并不關心 select 通過 index 掃描出 row 之后再通過 condition 過濾的過程)。繼續追蹤:

讓我們看下該函數內部: 

bool lock_clust_rec_cons_read_sees(const rec_t* rec /* 由 innodb 掃描出來的一行 */,....){ ... //  從當前掃描的行中獲取其 *** 修改的版本 trx_id(事務 id) trx_id = row_get_rec_trx_id(rec, index, offsets); //  通過參數 (一致性快照視圖和事務 id) 決定看到的行快照  return(read_view_sees_trx_id(view, trx_id)); }

read_view 的創建過程

我們先關注一致性視圖的創建過程, 我們先看下 read_view 結構:

然后通過 debug,發現創建 read_view 結構也是在上述的 rr_sequential 中操作的,繼續跟蹤調用棧:

我們看下 row_search_for_mysql 里的一個分支: 

row_search_for_mysql: //  這邊只有 select 不加鎖模式的時候才會創建一致性視圖  else if (prebuilt- select_lock_type == LOCK_NONE) { //  創建一致性視圖  trx_assign_read_view(trx); prebuilt- sql_stat_start = FALSE; }

上面的注釋就是 select for update(in share model)不會走 MVCC 的原因。讓我們進一步分析 trx_assign_read_view 函數:

好了,終于到了創建 read_view 的主要階段, 主要過程如下圖所示:

代碼過程為:

MySQL 多版本并發控制機制源碼分析

行版本可見性:

由上面的 lock_clust_rec_cons_read_sees 可知, 行版本可見性由 read_view_sees_trx_id 函數判斷:

MySQL 多版本并發控制機制源碼分析

其實上述函數就是一個二分法,read_view 其實保存的是當前活躍事務的所有事務 id, 如果當前行版本對應修改的事務 id 不在當前活躍事務里面的話,就返回 true, 表示當前版本可見,否則就是不可見, 如下圖所示。

MySQL 多版本并發控制機制源碼分析

接上述 lock_clust_rec_cons_read_sees 的返回:

MySQL 多版本并發控制機制源碼分析

undolog 搜索可見版本的過程

我們現在考察一下 row_sel_build_prev_vers_for_mysql 函數: 

row_sel_build_prev_vers_for_mysql |-row_vers_build_for_consistent_read

主要是調用了 row_ver_build_for_consistent_read 方法返回可見版本:

MySQL 多版本并發控制機制源碼分析

整個過程如下圖所示:

MySQL 多版本并發控制機制源碼分析

至于 undolog 怎么恢復出對應版本的 row 記錄就又是一個復雜的過程了,由于篇幅原因,在此略過不表。

read_view 創建時機再討論

在創建一致性視圖的 row_search_for_mysql 的代碼中

MySQL 多版本并發控制機制源碼分析

trx_assign_read_view 中由這么一段代碼

MySQL 多版本并發控制機制源碼分析

所以綜合這兩段代碼,即在一個事務中,只有 *** 次運行 select(不加鎖)的時候才會創建一致性視圖, 如下圖所示:

MySQL 多版本并發控制機制源碼分析

筆者構造了此種場景模擬過,確實如此。

MVCC 和鎖的同時作用導致的一些現象

MySQL 是通過 MVCC 和二階段鎖 (2PL) 來兼顧性能和一致性的,但是由于 MySQL 僅僅在 select 時候才創建一致性視圖,而在 update 等加鎖操作的時候并不做如此操作,所以就會產生一些詭異的現象。如下圖所示:

MySQL 多版本并發控制機制源碼分析

如果理解了 update 不走一致性視圖(read_view),而 select 走一致性視圖(read_view),就可以很好解釋這個現象。如下圖所示:

MySQL 多版本并發控制機制源碼分析

到此,相信大家對“MySQL 多版本并發控制機制源碼分析”有了更深的了解,不妨來實際操作一番吧!這里是丸趣 TV 網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-18發表,共計2575字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 江北区| 贡嘎县| 独山县| 林芝县| 怀宁县| 长汀县| 政和县| 武川县| 河北区| 宜宾市| 禹州市| 潼关县| 盘山县| 灯塔市| 于都县| 吉安县| 通海县| 惠州市| 额尔古纳市| 新余市| 锡林郭勒盟| 垣曲县| 铜鼓县| 建昌县| 库尔勒市| 普定县| 潜山县| 靖边县| 化州市| 常州市| 雷州市| 乐安县| 湾仔区| 丰县| 宣武区| 磐安县| 东港市| 克东县| 博湖县| 会理县| 邹平县|