分為兩個要點簡述:
要點一:行記錄的歷史版本是什麼樣子的?
innodb 將行記錄及其歷史行記錄通過隱藏字段(data_roll_ptr)鏈成乙個鍊錶。歷史行記錄其實就是 undo log,放在共享表空間的 undo 段。
要點二:當前事務進行快照讀時,如何選擇歷史版本?
每個行記錄及其歷史行記錄都有乙個隱藏字段(data_trx_id),記錄了最後更新該行記錄的事務 id。
事務的事務 id 由 innodb 統一分配,越是後分配,事務 id 越大,即事務 id 是單增的。
rr 級別下,事務在第乙個快照讀時生成乙個 read view。
rc 級別下,事務在每一次快照讀都重新生成一次 read view。
每次事務進行快照讀時,都會根據 read view,按照只能讀取在建立 read view 之前已提交事務所做的修改的原則,選擇最新的符合要求的歷史行記錄讀取。
2.1 undo log
同一行記錄各個版本構成的鍊錶,示意圖(非原創):
事務每對行記錄 update 一次,就會產生乙個歷史行記錄。
乙個可以加深理解的點是:行記錄的 undo 鍊錶,尾結點一定是某個事務對該記錄的 insert 操作,中間結點都是事務對該記錄的 update 操作,頭結點可能是事務的 update 操作,也可能是事務的 delete 操作。
2.2 選擇歷史版本的具體實現
innodb 會維護乙個所有當前活躍事務 id 的列表。
當事務需要建立 read view 時:
有了這三樣東西,再加上只能讀取在建立 read view 之前提交事務所做的修改的原則,估計大家已經知道是怎麼選擇判斷的了。
選擇歷史版本的流程:
從頭結點依次向後判斷,因為越在前面的記錄越新,所以返回第乙個符合要求的版本。
如果頭結點就滿足要求,還需要特判一下記錄是否被刪除,如果被刪除,則返回空。
判斷是否符合要求的流程:
取出該版本的事務 id,判斷該事務在建立 read view 時是否已提交。
拿該事務 id 和 up_limit_id 比較,如果小於,則可以讀取。
再拿該事務 id 和 low_limit_id 比較,如果大於等於,說明該事務是建立 read view 後,新開啟的事務,不可以讀取。
最後判斷該事務 id 是否在 trx_ids 裡,如果不在,則可以讀取,否則不可以讀取。
mvcc原理 Innodb的MVCC原理
該文章是 innodb的mvcc簡介 中的細節作出解釋。在mvcc出現之前的資料庫,為了實現一致性讀,如sqlserver,db2均採用鎖定讀技術,寫操作往往會阻塞讀操作,導致資料庫併發效能不高。oracle與postgre相繼推出自己的多版本併發控制技術,這一技術的核心是在發生讀寫衝突時候,讀操作...
innoDB的MVCC實現方式
innodb的mvcc是通過在每行記錄後面儲存兩個隱藏的列來實現。乙個儲存行的建立時間,乙個儲存行的過期時間,儲存的值為系統版本號。每開啟乙個新的事務,系統版本號都會自動增加。在repeatable read隔離級別下,mvcc的具體操作 insert delete update 儲存這兩個額外系統...
mysql 關於innodb中MVCC的一些理解
mvcc multiversion concurrency control 即多版本併發控制技術,它使得大部分支援行鎖的事務引擎,不再單純的使用行鎖來進行資料庫的併發控制,取而代之的是把資料庫的行鎖與行的多個版本結合起來,只需要很小的開銷,就可以實現非鎖定讀,從而大大提高資料庫系統的併發效能 讀鎖 ...