Mysql 事務可見性


Mysql 為了控制事務隔離,防止數據跑偏采用了多種機制來保證事務的准確性;

背景:

1、log

使用(write ahead log),落盤前先寫log;

事務開始的時候就記錄undo log,用於失敗回滾;

事務提交的時候會記錄redo log,可以用來回放保證事務提交的一致性;當然redo log 也不一定都會提交,這個涉及到事務的兩階段提交;

2、事務標記

每條記錄都會記錄一個事務id,用於標記記錄當前所處的上下文環境;

事務是連續性的(事務id trx_id是在系統變量max_trx_id自增);

只有寫操作事務id才會自增;

事務id 的大小為8個字節,也就是自增到8個字節后就會從0開始,這個時候就會出現【臟讀】;

3、MVCC

MVCC即版本控制,原始的版本控制是串行的,類似於悲觀鎖,Mysql的MVCC一條記錄是可以有多個版本,即樂觀鎖;

事務中可見性如何保證:

每條記錄都包含一個 trx_id 標記記錄的事務id;

當mysql 開啟一個事務的時候,會記錄這個事務中數據的上下文信息 read view:

read view 生成時機:

RC 每次讀操作都會生成read view, 比較消耗資源;

RR 事務的首次讀操作會生成read view;

read view 中關鍵數據:up_trx_id(低水位事務id) - low_trx_id(高水位事務id),以及這個階段的活躍事務id 列表;

讀操作讀取數據判斷是否可見:

如果數據的trx_id 小於 低水位事務id,則表示數據的事務已經提交,可見;

如果數據的trx_id 大於 高水位事務id,則表示數據的事務id 是在當前事務之后,不可見,在undo log中讀取舊版本數據;

如果數據的trx_id 在 低水位事務id 和 高水位事務id 之間,則表示數據在當前事務開啟的時候正處於一個未提交事務中,當然在生成read view 的時候可能事務已經提交,

所以:

如果事務id在低水位 - 高水位之間,且在read view 列表中,則表示在生成read view 時仍然未提交事務,則可以讀取 undo log中的數據;

如果事務id在低水位 - 高水位之間,但是不在read view列表中,則表示在生成read view的時候已經提交了事務,則數據可見,直接使用;

 


免責聲明!

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



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