MySQL-InnoDB-MVCC多版本併發控制 剖析
什麼是MVCC?
MVCC的實現是通過保存數據在某個時間點的快照來實現的、也就是說,不管需要執行多長時間、每個事務看到的數據都是一致的。根據事務開始的時間不同,每個事務對同一張表,同一時刻看到的數據可能是不一樣的。
劃重點
MVCC(Multiversion concurrency control) 多版本控制、提供併發訪問數據庫時、對事務內讀取的到內存做處理,用來避免寫操作堵塞讀操作的併發問題
MVCC的背後邏輯是什麼 ?
InnoDB的MVCC,是通過每行記錄的後面保存兩個隱藏的列來實現的,這兩個列,一個保存了行的創建時間,另一個保存行的過期時間(或刪除時間),當然存儲的並不是實際時間值,而是系統的版本號,每開始一個新的事務,系統的版本號都會自動遞增,事務開始時刻的系統版本號會作爲事務的版本號,用來和查詢的每行記錄的版本號進行比較.
在RR(READ REPEATABLE)隔離級別下,MVCC的操作過程如下:
select操作
- InnoDb只查找版本早於(包含等於)當前事務版本的數據行。可以保證事務讀取的行,要麼在事務開始前已經存在的,要麼事務操作(插入或者修改)
- 行的刪除版本要麼未定義,要麼大於當前事務版本號。可以保證事務讀取到的行,在事務開始之前未被刪除
insert操作
- innodb爲新插入的每行保存當前的版本號作爲行插入標識
delete操作
- innodb爲刪除的行保存當前系統的版本號作爲行刪除標識
update操作
- innodb 爲插入行記錄、保存當前系統版本號作爲行版本號,同時保存當前系統版本號到原來的行作爲行刪除標識
好處
Innodb保存這兩個額外的系統版本號,是大多數都操作都可以不用加鎖,這樣設計使得都數據操作簡單、性能很好,並且保證只會讀取到符合標準的行。
不足之處
每行記錄都需要增加額外的存儲空間、需要更多的行檢查工作,以及一些額外的維護工作。
業餘擴展
- mysql默認的隔離級別是什麼呢?mysql默認採用RR隔離級別
- MVCC使用有哪些限制呢、MVCC可以在所有的隔離級別下工作嗎? NO,MVCC只在RR(repeatable read)和RC(read committed)這個兩個級別下工作。因爲RU(read uncommitted)總是讀取最新的數據行,而不是符合當前事務版本的數據行,而Serializable則會對所有讀取的行都鎖
- 那麼每次操作都會有快照的操作,什麼情況下會刪除呢?由於舊數據並不是真正的刪除,需要對這寫數據進行清理,Innodb會開啓一個後臺線程執行清理工作,清理的規則是:講刪除版本號小於當前系統版本的行刪除,這個操作叫做purge
4.RC和RR在鎖方面有什麼不同?- RR支持間隙鎖(gap lock)Next-Key Lock 而 RC不支持間隙鎖 (gap lock ) mysql的RR級別需要通過gap lock來解決幻讀的問題,在RC隔離級別則允許存在不可重複讀和幻讀的,因此RC的併發一般要好於RR
- RC 是通過where條件過濾之後,不符合條件的記錄上的行鎖,會釋放掉(顯然破壞了兩階段加鎖的原則)但是RR隔離級別,即使不符合where條件的積累也不會釋放行鎖和gap lock 所以從鎖的方面來看,RC的併發應該要好於RR