對於使用InnoDB存儲引擎的表來說,它的聚簇索引記錄中都包含兩個必要的隱藏列:
trx_id:每次一個事務對某條聚簇索引記錄進行改動時,都會把該事務的事務id賦值給trx_id隱藏列。roll_pointer:每次對某條聚簇索引記錄進行改動時,都會把舊的版本寫入到undo日志中,然后這個隱藏列就相當於一個指針,可以通過它來找到該記錄修改前的信息。
每次對記錄進行改動,都會記錄一條undo日志,每條undo日志也都有一個roll_pointer屬性(INSERT操作對應的undo日志沒有該屬性,因為該記錄並沒有更早的版本),可以將這些undo日志都連起來,串成一個鏈表,所以現在的情況就像下圖一樣:

對該記錄每次更新后,都會將舊值放到一條undo日志中,就算是該記錄的一個舊版本,隨着更新次數的增多,所有的版本都會被roll_pointer屬性連接成一個鏈表,我們把這個鏈表稱之為版本鏈,版本鏈的頭節點就是當前記錄最新的值。另外,每個版本中還包含生成該版本時對應的事務id,這個信息很重要,在根據ReadView判斷版本可見性的時候會用到。
ReadView和版本的生成時間?
- ReadView在事物開始或者每條Select語句開始生成,與事務隔離級別有關。
- 版本是在對記錄進行改動的時候生成。
所以在事務並發的場景下,如果本事務存在對數據的改動,要注意記錄trx_id的變化對接下來數據可見性的影響。
