1.1 實現InnoDB下的快照讀
然后,接下來說說,在READ-COMMITTED和REPEATABLE-READ級別下的InnoDB的非阻塞讀是如何實現的。
實際上,在InnoDB存儲數據的時候,還會額外存儲三個不顯示出來的字段:DB_TRX_ID、DB_ROLL_PTR、DB_ROW_ID,下面來簡單介紹一下字段的含義。
DB_TRX_ID:最后一次修改本行記錄的事務ID。
DB_ROLL_PTR:滾指針,指向這條記錄的上一個版本(存儲於rollback segment里)。
DB_ROW_ID:隱含的自增ID,如果數據表沒有主鍵,InnoDB會自動以DB_ROW_ID產生一個聚簇索引。
然后再額外解釋一下什么是undo日志:
undo日志:邏輯日志,其記錄時間點為修改緩沖中頁面之前
2. 內在:next-key鎖(行鎖+gap鎖)
行鎖
所謂行鎖,就是對行上鎖
Gap鎖
Gap:索引樹中,插入新紀錄的空隙
Gap鎖:指一段距離,將插入的索引占用的空隙用鎖包住。Gap鎖的目的是,防止事務因為兩次當前讀出現幻讀的情況。但是READ-COMMITTED及以下的級別都沒有Gap鎖,所以無法避免幻讀。
而在REPEATABLE-READ級別下,無論是刪改查,如果我們要使用到主鍵索引或者唯一索引,會需要到gap鎖嗎?
其實是視情況而定的,如果where條件全部命中,就可以不用gap鎖,否則,就得用gap鎖。(命中:比如我們where id in (1,3,5),id是主鍵,1 3 5在table中都能查到東西,就是全部命中,只查到一部分,就是部分命中)