探究InnoDB可重復(fù)讀

在RC(Read Committed)和RR(Repeatable Read)兩種事務(wù)隔離級別下驯绎,InnoDB存在兩種數(shù)據(jù)讀取方式:

快照讀(Snapshot Read)

故名思意完慧,快照讀讀取的都是快照數(shù)據(jù),快照怎么來条篷,在InnoDB引擎下是基于undo log骗随,那undo log又是什么?舉例說明赴叹,假設(shè)有這樣一個表:

-- 表結(jié)構(gòu)
CREATE TABLE `innodb_test` (
    `id` INT(11) NOT NULL AUTO_INCREMENT,
    `name` VARCHAR(100) NOT NULL DEFAULT '0',
    `age` INT(11) NOT NULL DEFAULT '0',
    PRIMARY KEY (`id`),
    INDEX `idx_age` (`age`)
)
ENGINE=InnoDB;

-- 初始數(shù)據(jù)
INSERT INTO `innodb_test` (`id`, `name`, `age`) VALUES (1, '貂蟬', 100),(2, '莊周', 120),(3, '項羽', 130);
  • id=1的初始數(shù)據(jù)行


  • 事務(wù)A執(zhí)行如下語句

    UPDATE innodb_test SET name='嬴政', age=90 WHERE id=1;
    

    此時innodb會做如下操作:

    1. 把該行修改前的值Copy到undo log(Copy on write)鸿染;
    2. 修改當前行的值,填寫事務(wù)編號乞巧,使回滾指針指向undo log中的修改前的行涨椒。


  • 事務(wù)B執(zhí)行如下語句

    UPDATE innodb_test SET name='甄姬', age=91 WHERE id=1;
    

    此時undo log中有2條記錄,它們通過回滾指針相連绽媒。


undo log的存在解決了兩個問題蚕冬,一是數(shù)據(jù)回滾,二是實現(xiàn)了MVCC (Multi-Version Concurrency Control) 是辕,快照讀讀取的就是undo log中的數(shù)據(jù)囤热,所以這種讀取是不需要加鎖的,避免了讀寫沖突获三。常見的快照讀語句就是最常見的SELECT旁蔼,比如:

SELECT * FROM innodb_test WHERE id=1;

快照讀在RC和RR隔離級別下的表現(xiàn)卻是不一樣的锨苏,為了方便說明,現(xiàn)在將數(shù)據(jù)還原到初始數(shù)據(jù)棺聊,然后按照下表的順序操作伞租。

# 事務(wù)1 事務(wù)2
1 begin; begin;
2 SELECT * FROM innodb_test WHERE id=1;// 輸出1-貂蟬-100
3 UPDATE innodb_test SET name='嬴政', age=90 WHERE id=1;
4 commit;
5 SELECT * FROM innodb_test WHERE id=1;// 輸出?限佩?葵诈?
  • RC
    輸出的是最新提交的結(jié)果(1-嬴政-90),RC級別的快照讀遵循以下規(guī)則:

    • 優(yōu)先讀取當前事務(wù)修改的數(shù)據(jù)祟同,自己修改的作喘,當然可以讀到了;
    • 其次讀取最新已提交數(shù)據(jù)耐亏。

    會出現(xiàn)前后讀取結(jié)果不一樣的情況徊都,但讀取的是最新數(shù)據(jù)。

  • RR
    輸出結(jié)果和第一次查詢是一樣的(1-貂蟬-100)广辰,RR級別的快照讀遵循以下規(guī)則:

    • 優(yōu)先讀取當前事務(wù)修改的數(shù)據(jù),和RC一樣主之;
    • 其次讀取小于當前事務(wù)id的最新一條已提交數(shù)據(jù)择吊,此時數(shù)據(jù)版本已經(jīng)確定了,后面的快照讀取始終讀取這個版本槽奕。

    通過這樣的機制几睛,保證了快照讀的可重復(fù)讀,但讀取到的數(shù)據(jù)很可能已經(jīng)過期了粤攒。

當前讀(Current Read)

而當前讀所森,讀取的是最新已提交數(shù)據(jù),并且都會加行鎖夯接,如下語句都會產(chǎn)生當前讀:

SELECT balabala LOCK IN SHARE MODE;
SELECT balabala FOR UPDATE;
INSERT balabala;
UPDATE balabala;
DELETE balabala;

當前讀需要保證其他并發(fā)事務(wù)不能修改當前記錄焕济,對讀取記錄加鎖。其中盔几,第一條語句晴弃,對讀取記錄加S鎖(共享鎖),其他的操作逊拍,都加的是X鎖(排它鎖)上鞠。當前讀在RC和RR隔離級別下的表現(xiàn)也是不一樣的,為了方便說明芯丧,現(xiàn)在將數(shù)據(jù)還原到初始數(shù)據(jù)芍阎,然后按照下表的順序操作。

# 事務(wù)1 事務(wù)2
1 begin; begin;
2 SELECT * FROM innodb_test WHERE age=120 FOR UPDATE;
3 insert into innodb_test(name, age) values('嬴政', 120);// 此時會發(fā)生什么缨恒?
  • RC
    成功執(zhí)行谴咸,但會造成事務(wù)1的幻讀轮听,前后兩次讀取結(jié)果不一樣。

  • RR
    會鎖等待寿冕,在RR隔離級別下蕊程,事務(wù)1的sql不僅會對該記錄加X鎖,還會對上下兩個數(shù)據(jù)間隙加間隙鎖驼唱,以此確保在數(shù)據(jù)讀取期間藻茂,其它事物不會在該間隙內(nèi)增加數(shù)據(jù),從而保證可重復(fù)讀玫恳。

總結(jié)

RR隔離級別下辨赐,快照讀通過undo log來保證可重復(fù)讀,當前讀通過X(S)鎖+GAP鎖來保證可重復(fù)讀京办,但顯然快照讀和當前讀之間無法保證可重復(fù)讀掀序。本文對可重復(fù)讀的實現(xiàn)機制做了闡述,關(guān)于undo log惭婿、鎖等知識僅僅從簡描述不恭,后面有時間再詳細寫一下。


版權(quán)聲明
本博客所有的原創(chuàng)文章财饥,作者皆保留版權(quán)换吧。轉(zhuǎn)載必須包含本聲明,保持本文完整钥星,并以超鏈接形式注明作者高爽和本文原始地址:http://www.reibang.com/p/17967b72139a沾瓦。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市谦炒,隨后出現(xiàn)的幾起案子贯莺,更是在濱河造成了極大的恐慌,老刑警劉巖宁改,帶你破解...
    沈念sama閱讀 216,997評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件缕探,死亡現(xiàn)場離奇詭異,居然都是意外死亡透且,警方通過查閱死者的電腦和手機撕蔼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來秽誊,“玉大人鲸沮,你說我怎么就攤上這事」郏” “怎么了讼溺?”我有些...
    開封第一講書人閱讀 163,359評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長最易。 經(jīng)常有香客問我怒坯,道長炫狱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,309評論 1 292
  • 正文 為了忘掉前任剔猿,我火速辦了婚禮视译,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘归敬。我一直安慰自己酷含,他們只是感情好,可當我...
    茶點故事閱讀 67,346評論 6 390
  • 文/花漫 我一把揭開白布汪茧。 她就那樣靜靜地躺著椅亚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪舱污。 梳的紋絲不亂的頭發(fā)上呀舔,一...
    開封第一講書人閱讀 51,258評論 1 300
  • 那天,我揣著相機與錄音扩灯,去河邊找鬼媚赖。 笑死,一個胖子當著我的面吹牛珠插,可吹牛的內(nèi)容都是我干的省古。 我是一名探鬼主播,決...
    沈念sama閱讀 40,122評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼丧失,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了惜互?” 一聲冷哼從身側(cè)響起布讹,我...
    開封第一講書人閱讀 38,970評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎训堆,沒想到半個月后描验,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡坑鱼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,596評論 3 334
  • 正文 我和宋清朗相戀三年膘流,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鲁沥。...
    茶點故事閱讀 39,769評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡呼股,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出画恰,到底是詐尸還是另有隱情彭谁,我是刑警寧澤,帶...
    沈念sama閱讀 35,464評論 5 344
  • 正文 年R本政府宣布允扇,位于F島的核電站缠局,受9級特大地震影響则奥,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜狭园,卻給世界環(huán)境...
    茶點故事閱讀 41,075評論 3 327
  • 文/蒙蒙 一读处、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧唱矛,春花似錦罚舱、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至燥滑,卻和暖如春渐北,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背铭拧。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評論 1 269
  • 我被黑心中介騙來泰國打工赃蛛, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人搀菩。 一個月前我還...
    沈念sama閱讀 47,831評論 2 370
  • 正文 我出身青樓呕臂,卻偏偏與公主長得像,于是被迫代替她去往敵國和親肪跋。 傳聞我的和親對象是個殘疾皇子歧蒋,可洞房花燭夜當晚...
    茶點故事閱讀 44,678評論 2 354

推薦閱讀更多精彩內(nèi)容