簡介
MVCC(Multi-Version Concurrency Control)即多版本并發(fā)控制。
MySQL的大多數(shù)事務(wù)型(如InnoDB,Falcon等)存儲引擎實(shí)現(xiàn)的都不是簡單的行級鎖崔兴≌玫迹基于提升并發(fā)性能的考慮,他們一般都同時(shí)實(shí)現(xiàn)了MVCC敲茄。當(dāng)前不僅僅是MySQL,其它數(shù)據(jù)庫系統(tǒng)(如Oracle,PostgreSQL)也都實(shí)現(xiàn)了MVCC位谋。值得注意的是MVCC并沒有一個統(tǒng)一的實(shí)現(xiàn)標(biāo)準(zhǔn),所以不同的數(shù)據(jù)庫堰燎,不同的存儲引擎的實(shí)現(xiàn)都不盡相同掏父。
作為MySQL中使用最廣泛的存儲引擎,本文主要討論的是InnoDB的多版本并發(fā)控制的實(shí)現(xiàn)
MVCC優(yōu)缺點(diǎn)
MVCC在大多數(shù)情況下代替了行鎖秆剪,實(shí)現(xiàn)了對讀的非阻塞赊淑,讀不加鎖,讀寫不沖突仅讽。缺點(diǎn)是每行記錄都需要額外的存儲空間陶缺,需要做更多的行維護(hù)和檢查工作。
MVCC的實(shí)現(xiàn)原理
undo log
為了便于理解MVCC的實(shí)現(xiàn)原理洁灵,這里簡單介紹一下undo log的工作過程
在不考慮redo log 的情況下利用undo log工作的簡化過程為:
序號 | 動作 |
---|---|
1 | 開始事務(wù) |
2 | 記錄數(shù)據(jù)行數(shù)據(jù)快照到undo log |
3 | 更新數(shù)據(jù) |
4 | 將undo log寫到磁盤 |
5 | 將數(shù)據(jù)寫到磁盤 |
6 | 提交事務(wù) |
1)為了保證數(shù)據(jù)的持久性數(shù)據(jù)要在事務(wù)提交之前持久化
2)undo log的持久化必須在在數(shù)據(jù)持久化之前饱岸,這樣才能保證系統(tǒng)崩潰時(shí),可以用undo log來回滾事務(wù)
Innodb中的隱藏列
Innodb通過undo log保存了已更改行的舊版本的信息的快照。
InnoDB的內(nèi)部實(shí)現(xiàn)中為每一行數(shù)據(jù)增加了三個隱藏列用于實(shí)現(xiàn)MVCC伶贰。
列名 | 長度(字節(jié)) | 作用 |
---|---|---|
DB_TRX_ID | 6 | 插入或更新行的最后一個事務(wù)的事務(wù)標(biāo)識符蛛砰。(刪除視為更新罐栈,將其標(biāo)記為已刪除) |
DB_ROLL_PTR | 7 | 寫入回滾段的撤消日志記錄(若行已更新黍衙,則撤消日志記錄包含在更新行之前重建行內(nèi)容所需的信息) |
DB_ROW_ID | 6 | 行標(biāo)識(隱藏單調(diào)自增id) |
結(jié)構(gòu)
數(shù)據(jù)列 | .. | DB_ROW_ID | DB_TRX_ID | DB_ROLL_PTR |
---|
MVCC工作過程
MVCC只在READ COMMITED 和 REPEATABLE READ 兩個隔離級別下工作。READ UNCOMMITTED總是讀取最新的數(shù)據(jù)行荠诬,而不是符合當(dāng)前事務(wù)版本的數(shù)據(jù)行琅翻。而SERIALIZABLE 則會對所有讀取的行都加鎖
SELECT
InnoDB 會根據(jù)兩個條件來檢查每行記錄:
- InnoDB只查找版本(DB_TRX_ID)早于當(dāng)前事務(wù)版本的數(shù)據(jù)行(行的系統(tǒng)版本號<=事務(wù)的系統(tǒng)版本號,這樣可以確保數(shù)據(jù)行要么是在開始之前已經(jīng)存在了,要么是事務(wù)自身插入或修改過的)
- 行的刪除版本號(DB_ROLL_PTR)要么未定義(未更新過)柑贞,要么大于當(dāng)前事務(wù)版本號(在當(dāng)前事務(wù)開始之后更新的)方椎。這樣可以確保事務(wù)讀取到的行,在事務(wù)開始之前未被刪除钧嘶。
INSERT
InnoDB為新插入的每一行保存當(dāng)前系統(tǒng)版本號作為行版本號
DELETE
InnoDB為刪除的每一行保存當(dāng)前的系統(tǒng)版本號作為行刪除標(biāo)識
UPDATE
InnoDB為插入一行新記錄棠众,保存當(dāng)前系統(tǒng)版本號作為行版本號,同時(shí)保存當(dāng)前系統(tǒng)版本號到原來的行作為行刪除標(biāo)識
參考資料
《高性能MYSQL》
轉(zhuǎn)載請注明出處: http://www.reibang.com/p/a3d49f7507ff