Mysql MVCC機制


之前有說到mysql事務隔離級別和鎖mysql事務隔離級別有:讀未提交,讀已提交,可重復讀,串行化。

可重復讀,當開啟事務之后,在此次事務中讀到的數據都不會變化(除開新增的數據(可重復讀隔離級別不能解決幻讀)),為什么可重復讀隔離級別能做到這樣呢,這就不得不提mysqlMVCCMulti-Version Concurrency Control)多版本並發控制機制。對同一行記錄的讀寫操作不會通過加鎖來互斥。Mysql在讀已提交和可重復隔離級別下面都實現了MVCC機制

 

undo日志版本鏈與read view機制

Mvcc機制主要是依靠undo日志版本鏈與一致性視圖read view來實現的。

undo日志版本鏈是指一數據被多個事務依次修改過后,在每個事務修改完后,Mysql會保留修改前的數據undo回滾日志,通過事務ID(trx_id)roll_pointe(指向上一條undo日志記錄)把這些undo日志串聯起來形成一個歷史記錄版本鏈

begin/start transaction 命令並不是一個事務的起點,在執行到它們之后的第一個修改操作InnoDB表的語句, 事務才真正啟動,才會向mysql申請事務idmysql內部是嚴格按照事務的啟動順序來分配事務id的。

在可重復讀隔離級別,當事務開啟時,執行第一條查詢sql時會生成當前事務的一致性視圖read-view,注意並不是在開啟事務的時候生成一致性視圖,該視圖在事務結束之前都不會變化(如果是讀已提交隔離級別在每次執行查詢sql時都會重新生成一致性視圖),這個視圖由執行查詢時所有未提交事務ID數組(數組里最小的idmin_id)和已創建的最大事務IDmax_id)組成,事務里的任何sql查詢結果需要從對應版本鏈里的最新數據開始逐條跟read-view做比對從而得到最終的快照結果。

如下圖:

 

 

如果此時這些事務都沒有提交,在這個時候我們進行查詢語句的時候,在生成的一致性視圖就是:[5,6,7],7 ,[5,6,7]查詢時未提交的事務ID數組,執行此查詢的時候已創建的最大事務ID。

Undo日志版本鏈和read view對比規則:

從版本鏈依次開始比對:

1.如果 版本鏈中記錄的行的(row) trx_id 小於視圖中的未提交事務數組ID最小的值( trx_id<min_id ),表示這個版本是已提交的事務生成的,這個數據是可見的;

 2.如果 row 的 trx_id 大於數組的最大ID( trx_id>max_id ),表示這個版本是由后來啟動的事務生成的,是不可見的(若 row 的 trx_id 就是當前自己的事務是可見的);

 3. row 的 trx_id 在視圖數組中(min_id <=trx_id< max_id),表示這個版本是由還沒提交的事務生成的,不可見

 4.若 row 的 trx_id 不在視圖數組中,表示這個版本是已經提交了的事務生成的,可見。

舉個例子:

開啟事務,按下面sql的執行循序執行sql

 

 

 

 結合上面undo日志版本鏈,日志版本鏈和此表sql的順序是一致的:

當我們執行查詢1的第一條查詢的時候生成一致性視圖: [5,6],7 在可重復讀隔離級別當前這次事務中的查詢只會生成一次視圖,不會再改變。開始執行比對規則。

版本鏈第一條數據trx_id5,命中比對規則3: 在視圖數組(未提交的ID數組)中,因此不可見;繼續比對trx_id7,命中規則4,那么則可見。

查詢1剩下的兩條的sql,因為在第一次執行查詢已經生成了一致性視圖,雖然在步驟8的時候事務5提交了,但是並不會改變查詢1的一致性視圖,所以查詢1三條查詢結果都是一致,這也就實現可重復讀。

查詢2的查詢語句是在事務5提交之后執行的,因此它生成的一致性視圖和查詢1是不一樣的,它的視圖中未提交事務ID數組只有事務6,因此它能夠查詢得到xiaohong55 事務1提交的結果。

如果是讀已提交,那么就是每次執行查詢語句都會生成新的一致性視圖,試想查詢1如果在已提交的隔離級別下面,那么執行最后一次的查詢生成的一致性視圖是和查詢2一致的,就能讀到事務5已提交的數據了。

對於刪除,會將版本鏈上最新的數據復制一份,然后將trx_id修改成刪除操作的 trx_id,同時在該條記錄的頭信息(record header)里的(deleted_flag刪除標記為true,來表示當前記錄已經被刪除,在查詢時按照上面的規則查到對應的記錄如果delete_flag標記為true,意味着記錄已被刪除,則不返回數據。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM