1.MVCC
MVCC(Mutil-Version Concurrency Control),就是多版本并發(fā)控制箩兽。這種并發(fā)控制的方法津肛,主要應(yīng)用在RC和RR隔離級別的事務(wù)當(dāng)中,利用執(zhí)行select操作時汗贫,訪問記錄版本鏈身坐,使得不同事物的讀寫,寫讀可以并發(fā)執(zhí)行落包,提高系統(tǒng)性能部蛇。
2.版本鏈
Innodb 有兩個隱藏字段 trx_id(事務(wù)id)和roll_pointer(回滾指針)。
transaction id:
innoDB里面每個事務(wù)有一個唯一的事務(wù)ID咐蝇,叫作transaction id涯鲁,它是在事務(wù)開始的時候向InnoDB的事務(wù)系統(tǒng)申請的,是按申請順序嚴(yán)格遞增的嘹害。
roll_pointer:
指向上一事務(wù)版本的指針撮竿。
版本鏈:
是一個單鏈表結(jié)構(gòu)吮便,對于同一行數(shù)據(jù)笔呀,每一個事務(wù)對其進(jìn)行更新的時候都會產(chǎn)生一個新的版本,就會存儲在這個鏈表當(dāng)中髓需。
3.ReadView
一個存儲事務(wù)id的列表许师。
readview的幾個參數(shù):
m_ids:表示活躍事務(wù)id列表
min_trx_id:活躍事務(wù)中的最小事務(wù)id
max_trx_id:已創(chuàng)建的最大事務(wù)id
creator_trx_id:當(dāng)前的事務(wù)id。
readview的生成時機(jī):
RC隔離級別:每次讀取數(shù)據(jù)前僚匆,都生成一個readview微渠;
RR隔離級別:在第一次讀取數(shù)據(jù)前,生成一個readview咧擂;
使用場景:
[ 創(chuàng)建事務(wù)節(jié)點 ] 當(dāng)我創(chuàng)建一個新的事務(wù)需要讀取一行數(shù)據(jù), 我會查詢活躍的事務(wù)列表; 假設(shè)我當(dāng)前的事務(wù)id是200, 當(dāng)前活躍的事務(wù)id沒有我的200, 因此需要去拷貝一個最新的不活躍事務(wù)并在版本鏈最后插入一個新節(jié)點200; mysql會去對比版本鏈和readView, 假設(shè)版本鏈數(shù)據(jù)為[1,50,100,150], 活躍列表為[100,150], 說明100和150都是未提交的活躍事務(wù), 再向前一個節(jié)點50不在活躍事務(wù)列表說明事務(wù)50已經(jīng)提交, 所以事務(wù)200拷貝事務(wù)50并插入版本鏈最后, 且將200追加到readView活躍列表的最后一個元素
[ 使用事務(wù)節(jié)點 ] 當(dāng)我再次進(jìn)行200號事務(wù)的查詢或修改, 我需要讀版本鏈的數(shù)據(jù), 因為上一次操作已經(jīng)在版本鏈做了200號節(jié)點, 因此我讀的數(shù)據(jù)都是200號節(jié)點的數(shù)據(jù), 這樣就隔離了其他未提交的事務(wù); 我的全部增刪查改都在200號版本鏈上進(jìn)行
[ readView實現(xiàn)事務(wù)隔離級別 ]以上兩點都是基于隔離級別"讀已提交"來進(jìn)行說明的; 當(dāng)mysql設(shè)置為"可重復(fù)讀"時, 不同事務(wù)仍然是保存在版本鏈的不同節(jié)點上, 只不過新的事務(wù)創(chuàng)建的時候拷貝了當(dāng)下的readView列表, 只要新事物不提交就一直使用這個拷貝的活躍列表; 假設(shè)此時100號數(shù)據(jù)提交了, 我在新事務(wù)執(zhí)行了select 會去查活躍列表發(fā)現(xiàn)100號事務(wù)還是未提交狀態(tài), 因此讀取到的還是50號事務(wù)提交的記錄逞盆。
4.事務(wù)的四大特性
原子性,一致性松申,隔離性云芦,持久性。
- 原子性(Atomicity) :強(qiáng)調(diào)的事務(wù)的不可分割.
- 一致性(Consistency) :強(qiáng)調(diào)的事務(wù)的執(zhí)行前后,數(shù)據(jù)庫的的完整性保持一致.
- 隔離性(Isolation) :強(qiáng)調(diào)的事務(wù)的并發(fā)的訪問,一個事務(wù)的執(zhí)行,不應(yīng)該受到另一個事務(wù)的打擾.
- 持久性(Durability) :強(qiáng)調(diào)的事務(wù)結(jié)束之后,數(shù)據(jù)就永久的保存的數(shù)據(jù)庫中.
5.事務(wù)隔離級別
未提交讀(read uncommitted)贸桶、提交讀(read committed)舅逸、可重復(fù)讀(repeatable read)、序列化讀(serializable)
- read uncommitted:
可以讀到其他事務(wù)未提交的數(shù)據(jù)皇筛,有可能產(chǎn)生臟讀 - read committed:
讀提交琉历,就是一個事務(wù)要等另一個事務(wù)提交后才能讀取數(shù)據(jù)。
有可能產(chǎn)生無法讀取到最初的原數(shù)據(jù),即不可重復(fù)讀旗笔。 - repeatable read:
重復(fù)讀彪置,就是在開始讀取數(shù)據(jù)(事務(wù)開啟)時,不再允許修改操作换团。
但是悉稠,不可重復(fù)讀對應(yīng)的是修改,即UPDATE操作艘包。但是可能還會有幻讀問題的猛。因為幻讀問題對應(yīng)的是插入INSERT操作,而不是UPDATE操作想虎。 - Serializable :
Serializable 是最高的事務(wù)隔離級別卦尊,在該級別下,事務(wù)串行化順序執(zhí)行舌厨,可以避免臟讀岂却、不可重復(fù)讀與幻讀。但是這種事務(wù)隔離級別效率低下裙椭,比較耗數(shù)據(jù)庫性能躏哩,一般不使用。