MYSQL- MYSQL日志 & MYSQL鎖 & MVCC

事務(wù)原理:

為了支持事務(wù)怜森,Innodb引入了下面幾個概念:

一谤牡、MYSQL 日志介紹:

1.binlog

binlog常用來進(jìn)行數(shù)據(jù)恢復(fù)翅萤、數(shù)據(jù)庫復(fù)制套么,常見的mysql主從架構(gòu),就是采用slave同步master的binlog實(shí)現(xiàn)的, 另外通過解析binlog能夠?qū)崿F(xiàn)mysql到其他數(shù)據(jù)源(如ElasticSearch)的數(shù)據(jù)復(fù)制省咨。

2.redo log- 記錄新數(shù)據(jù)的備份茸炒,保證事務(wù)持久性

當(dāng)客戶端執(zhí)行每條SQL(更新語句)時壁公,redo log會被首先寫入log buffer;當(dāng)客戶端執(zhí)行COMMIT命令時比肄,log buffer中的內(nèi)容會被視情況刷新到磁盤芳绩。在事務(wù)提交前妥色,只要將Redo Log持久化即可嘹害,不需要將數(shù)據(jù)持久化笔呀。當(dāng)系統(tǒng)崩潰時髓需,雖然數(shù)據(jù)沒有持久化僚匆,但是Redo Log已經(jīng)持久化白热。當(dāng)Mysql失效重啟進(jìn)行恢復(fù)時重新執(zhí)行redo log記錄的SQL進(jìn)行數(shù)據(jù)恢復(fù)。redo log在磁盤上作為一個獨(dú)立的文件存在,即Innodb的log文件攻臀。

3.undo log-保證事務(wù)的原子性? & 實(shí)現(xiàn)數(shù)據(jù)多版本MVCC

為了滿足事務(wù)的原子性刨啸,在操作任何數(shù)據(jù)之前设联,首先將數(shù)據(jù)備份到Undo Log.然后再進(jìn)行數(shù)據(jù)的修改。如果出現(xiàn)了錯誤或者用戶執(zhí)行了ROLLBACK語句换团,系統(tǒng)可以利用Undo Log中的備份將數(shù)據(jù)恢復(fù)到事務(wù)開始之前的狀態(tài)艘包。undo log用于數(shù)據(jù)的回滾操作想虎。

? 具體操作是 copy事務(wù)前的數(shù)據(jù)行到undo buffer舌厨,在適合的時間(事務(wù)提交前)把undo buffer中的內(nèi)容刷新到磁盤裙椭。undo log記錄了數(shù)據(jù)變更歷史如煌恢,刪除前備份 insert插入undo log中原行記錄再在刪除行記錄上打刪除標(biāo)記瑰抵,修改前備份 insert插入undo log中原行記錄再修改更新行數(shù)據(jù)打標(biāo)事務(wù)id&回滾指針(指向undo log中原行記錄)二汛。通過undo log可以實(shí)現(xiàn)事務(wù)回滾肴颊,并且可以根據(jù)undo log回溯到某個特定的版本的數(shù)據(jù)婿着,實(shí)現(xiàn)MVCC竟宋。? 與redo log不同的是丘侠,磁盤上不存在單獨(dú)的undo log文件蜗字,所有的undo log均存放在主ibd數(shù)據(jù)文件中(表空間)。


二争便、mysql鎖-實(shí)現(xiàn)隔離性

Innodb提供了行鎖始花,分兩種:排他鎖酷宵、共享鎖浇垦。

共享鎖針對讀男韧,排他鎖針對寫此虑,完全等同讀寫鎖的概念朦前。

排他鎖: 寫鎖, 如果某個事務(wù)在更新某行韭寸,則其他事物無論是讀還是寫本行都必須等待恩伺;

共享鎖: 讀鎖晶渠,如果某個事物讀某行乱陡,則其他讀的事物無需等待,而寫事物則需等待仪壮。

事務(wù)隔離級別 - 隔離級別依次增強(qiáng),但是導(dǎo)致的問題是并發(fā)能力的減弱

眾所周知地是更新(update胳徽、insert积锅、delete)是一個事務(wù)過程爽彤,在Innodb中,查詢也是一個事務(wù)缚陷,只讀事務(wù)适篙。當(dāng)讀寫事務(wù)并發(fā)訪問同一行數(shù)據(jù)時,能讀到什么樣的內(nèi)容則依賴事務(wù)級別:

- READ_UNCOMMITTED:讀未提交-臟讀- 事務(wù)能夠看到其他事務(wù)沒有提及的修改箫爷,當(dāng)另一個事務(wù)又回滾了修改后的情況又被稱為臟讀dirty read

- READ_COMMITTED:讀提交-幻讀- 事務(wù)能夠看到其他事務(wù)提交后的修改嚷节,會出現(xiàn)一個事務(wù)內(nèi)兩次讀取數(shù)據(jù)可能因?yàn)槠渌聞?wù)提交的修改導(dǎo)致不一致的情況,稱為不可重復(fù)讀。

- REPEATABLE_READ:重復(fù)讀 (默認(rèn)級別)-每次都讀取指定的版本缓屠,這樣保證不會產(chǎn)生幻讀羊初,但可能讀不到最新的數(shù)據(jù)

- SERIALIZABLE:串行化 -鎖表涧卵,讀寫相互阻塞,使用較少



三讼庇、MYSQL事務(wù)原理:

Innodb ACID如何保證

? 原子性 redo + undo

? 一致性 redo

? 隔離性 鎖 + MVCC

? 持久性 redo

下面演示下事務(wù)對某行記錄的更新過程:

todo

1. 初始數(shù)據(jù)行


F1~F6是某行列的名字,1~6是其對應(yīng)的數(shù)據(jù)。后面三個隱含字段分別對應(yīng)該行的事務(wù)號和回滾指針,假如這條數(shù)據(jù)是剛INSERT的硬梁,可以認(rèn)為ID為1罩息,其他兩個字段為空。

2.事務(wù)1更改該行的各字段的值

當(dāng)事務(wù)1更改該行的值時烘绽,會進(jìn)行如下操作:

用排他鎖鎖定該行

記錄redo log

把該行修改前的值Copy到undo log,即上圖中下面的行

修改當(dāng)前行的值,填寫事務(wù)編號,使回滾指針指向undo log中的修改前的行

commit 提交事務(wù) / rollback回滾事務(wù)(需要根據(jù)當(dāng)前回滾指針從undo log中找出事務(wù)修改前的行記錄版本,并恢復(fù)。)

上述過程確切地說是描述了UPDATE的事務(wù)過程剔难,Undo log分為Insert和Update兩種纯趋,delete可以看做是一種特殊的update痹栖,即在記錄上修改刪除標(biāo)記咆畏。

3.事務(wù)2修改該行的值

與事務(wù)1相同,此時undo log,中有有兩行記錄易结,并且通過回滾指針連在一起。todo delete

因此箩溃,如果undo log一直不刪除,則會通過當(dāng)前記錄的回滾指針回溯到該行創(chuàng)建時的初始內(nèi)容涣旨,所幸的時在Innodb中存在purge線程歪架,它會查詢那些比現(xiàn)在最老的活動事務(wù)還早的undo log,并刪除它們剔蹋,從而保證undo log文件不至于無限增長洛口。todo




四、MYSQL到底是怎么實(shí)現(xiàn)MVCC的湘纵?

在Mysql中MVCC是在Innodb存儲引擎中得到支持的汇歹,Innodb為每行記錄都實(shí)現(xiàn)了三個隱藏字段

6字節(jié)的事務(wù)ID(DB_TRX_ID)-標(biāo)識該行所屬的事務(wù)、

7字節(jié)的回滾指針(DB_ROLL_PTR)、

隱藏的ID

innodb存儲的最基本row中包含一些額外的存儲信息 DATA_TRX_ID(標(biāo)識該行所屬的事務(wù))趟佃,DATA_ROLL_PTR(回滾指針)扇谣,DB_ROW_ID(隱藏id),DELETE BIT(刪除標(biāo)志)

6字節(jié)的DATA_TRX_ID 標(biāo)記了最新更新這條行記錄的transaction id闲昭,每處理一個事務(wù)罐寨,其值自動+1

7字節(jié)的DATA_ROLL_PTR 指向當(dāng)前記錄項(xiàng)的rollback segment的undo log記錄,找之前版本的數(shù)據(jù)就是通過這個指針

6字節(jié)的DB_ROW_ID序矩,當(dāng)由innodb自動產(chǎn)生聚集索引時鸯绿,聚集索引包括這個DB_ROW_ID的值,否則聚集索引中不包括這個值.簸淀,這個用于索引當(dāng)中

DELETE BIT位用于標(biāo)識該記錄是否被刪除瓶蝴,這里的不是真正的刪除數(shù)據(jù),而是標(biāo)志出來的刪除租幕。真正意義的刪除是在commit的時候

MYSQL如何實(shí)現(xiàn)事務(wù)舷手?

? MYSQL讀寫鎖:讀鎖和讀鎖之間不互斥,而寫鎖和寫鎖令蛉、讀鎖都互斥聚霜,提升并發(fā)讀能力狡恬。為了進(jìn)一步提升并發(fā)能力,實(shí)現(xiàn)讀寫之間也不沖突蝎宇,讀取數(shù)據(jù)時通過一種類似快照的方式將數(shù)據(jù)保存下來弟劲,這樣讀鎖就和寫鎖不沖突了,不同的事務(wù)session會看到自己特定版本的數(shù)據(jù)姥芥。

MVCC原理:

MVCC原理

? 歷史版本存儲在UNDO Log空間

? 每條記錄帶版本號及回滾指針

? 廢棄記錄異步purge

MVCC實(shí)現(xiàn)

新增一個事務(wù)時事務(wù)id會增加兔乞,trx_id能夠表示事務(wù)開始的先后順序。

update undo log記錄了數(shù)據(jù)之前的數(shù)據(jù)信息凉唐,通過這些信息可以還原到之前版本的狀態(tài)庸追。

當(dāng)進(jìn)行插入操作時,生成的Insert undo log在事務(wù)提交后即可刪除台囱,因?yàn)槠渌聞?wù)不需要這個undo log淡溯。

進(jìn)行刪除修改操作時,會生成對應(yīng)的undo log簿训,并將當(dāng)前數(shù)據(jù)記錄中的db_roll_ptr指向新的undo log

---

MVCC概念: 提升事務(wù)并發(fā)處理能力

1咱娶、MVCC機(jī)制是行級鎖的一種妥協(xié),多線程事務(wù)讀取時强品,避免使用鎖膘侮,而是采用一種更小的開銷,允許非阻塞讀取的榛,寫操作進(jìn)行時只鎖定必要的記錄

2琼了、簡單的實(shí)現(xiàn)方式:MVCC保存某個時間點(diǎn)上的數(shù)據(jù)快照。一個事務(wù)內(nèi)夫晌,看到的是同一個版本的快照雕薪,數(shù)據(jù)一致。不同事務(wù)在同一時間點(diǎn)看到的數(shù)據(jù)會不一致慷丽,因?yàn)樗麄兊玫降臄?shù)據(jù)版本不一樣蹦哼。

MVCC可以任務(wù)它是行級鎖的一個變種,但是它在很多情況下避免了加鎖操作要糊,因此開銷更低纲熏。實(shí)現(xiàn)了非阻塞的讀操作提高db并發(fā)能力,寫操作也只鎖定必要的行锄俄。

MVCC的基本原理: 非理想態(tài)MVCC,提供讀的非阻塞

MVCC的實(shí)現(xiàn)局劲,通過保存數(shù)據(jù)在某個時間點(diǎn)的快照來實(shí)現(xiàn)的。這意味著一個事務(wù)無論執(zhí)行多長時間奶赠,在同一個事務(wù)里看到數(shù)據(jù)都是一致的鱼填。根據(jù)事務(wù)開始的時間不同,每個事務(wù)對同一張表同一個時刻看到的數(shù)據(jù)可能不同毅戈。

MVCC的基本特征:

每行數(shù)據(jù)都存在一個版本苹丸,每次數(shù)據(jù)更新時都更新該版本愤惰。

修改時Copy出當(dāng)前版本隨意修改,各個事務(wù)之間無干擾赘理。

保存時比較版本號宦言,如果成功(commit),則覆蓋原記錄商模;失敗則放棄copy(rollback)

就是每行都有版本號奠旺,保存時根據(jù)版本號決定是否成功,聽起來含有樂觀鎖的味道施流,而Innodb的實(shí)現(xiàn)方式是:

事務(wù)以排他鎖的形式修改原始數(shù)據(jù)

把修改前的數(shù)據(jù)存放于undo log响疚,通過回滾指針與主數(shù)據(jù)關(guān)聯(lián)

修改成功(commit)啥都不做,失敗則恢復(fù)undo log中的數(shù)據(jù)(rollback)

----

InnoDB存儲引擎MVCC的實(shí)現(xiàn)策略:

通過在每一行數(shù)據(jù)后面保存兩個隱藏的列實(shí)現(xiàn)當(dāng)前行創(chuàng)建時的版本號和刪除時的版本號(可能為空)瞪醋。這里的版本號并不是實(shí)際的時間值忿晕,而是系統(tǒng)版本號(可以理解為事務(wù)的ID)。每開始一個新的事務(wù)银受,系統(tǒng)版本號都會自動遞增杏糙。事務(wù)開始時刻的系統(tǒng)版本號會作為事務(wù)的版本號,用來和查詢到的每行記錄的版本號進(jìn)行比較蚓土。

每個事務(wù)又有自己的版本號,這樣事務(wù)內(nèi)執(zhí)行CRUD操作時赖淤,就通過版本號的比較來達(dá)到數(shù)據(jù)版本控制的目的蜀漆。具體做法見下面的示意圖。

MVCC具體的操作如下:

SELECT:InnoDB會根據(jù)以下兩個條件檢查[需同時滿足]每行記錄:

1)InnoDB只查找版本早于當(dāng)前事務(wù)版本的數(shù)據(jù)行(也就是咱旱,行的系統(tǒng)版本號小于或等于事務(wù)的系統(tǒng)版本號)确丢,這樣可以確保事務(wù)讀取的行,要么是在事務(wù)開始前已經(jīng)存在的吐限,要么是事務(wù)自身插入或者修改過的鲜侥。

2)行的刪除版本要么未定義,要么大于當(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)版本號作為行版本號肌蜻,同時保存當(dāng)前系統(tǒng)的版本號為原來的行作為刪除標(biāo)識互墓。

說明

insert操作時 “創(chuàng)建時間”=DB_ROW_ID,這時蒋搜,“刪除時間 ”是未定義的篡撵;

update時判莉,復(fù)制新增行的“創(chuàng)建時間”=DB_ROW_ID,刪除時間未定義育谬,舊數(shù)據(jù)行“創(chuàng)建時間”不變券盅,刪除時間=該事務(wù)的DB_ROW_ID;

delete操作斑司,相應(yīng)數(shù)據(jù)行的“創(chuàng)建時間”不變渗饮,刪除時間=該事務(wù)的DB_ROW_ID;

select操作對兩者都不修改宿刮,只讀相應(yīng)的數(shù)據(jù)

保存這兩個額外系統(tǒng)版本號互站,使大多數(shù)操作都可以不用加鎖。這樣設(shè)計(jì)使得計(jì)數(shù)據(jù)操作很簡單僵缺,性能很好胡桃,并且也能保證只會讀取到符合標(biāo)準(zhǔn)的行。不足之處是每行記錄都需要額外的存儲空間磕潮,需要做更多的行檢查工作翠胰,以及一些額外的維護(hù)工作。

MVCC只在REPEATABLE READ和READ COMMITED兩個隔離級別下工作自脯,其它兩個隔離級別和MVCC不兼容之景。

---

參考:

http://blog.csdn.net/chen77716/article/details/6742128

https://liuzhengyang.github.io/2017/04/18/innodb-mvcc/

http://www.cnblogs.com/chenpingzhao/p/5065316.html

http://zhangxiong0301.iteye.com/blog/2230193

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市膏潮,隨后出現(xiàn)的幾起案子锻狗,更是在濱河造成了極大的恐慌,老刑警劉巖焕参,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件轻纪,死亡現(xiàn)場離奇詭異,居然都是意外死亡叠纷,警方通過查閱死者的電腦和手機(jī)刻帚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涩嚣,“玉大人崇众,你說我怎么就攤上這事』貉蓿” “怎么了校摩?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長阶淘。 經(jīng)常有香客問我衙吩,道長,這世上最難降的妖魔是什么溪窒? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任坤塞,我火速辦了婚禮冯勉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘摹芙。我一直安慰自己灼狰,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布浮禾。 她就那樣靜靜地躺著交胚,像睡著了一般。 火紅的嫁衣襯著肌膚如雪盈电。 梳的紋絲不亂的頭發(fā)上蝴簇,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天,我揣著相機(jī)與錄音匆帚,去河邊找鬼熬词。 笑死,一個胖子當(dāng)著我的面吹牛吸重,可吹牛的內(nèi)容都是我干的互拾。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼嚎幸,長吁一口氣:“原來是場噩夢啊……” “哼颜矿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起嫉晶,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤或衡,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后车遂,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡斯辰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年舶担,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片彬呻。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡衣陶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出闸氮,到底是詐尸還是另有隱情剪况,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布蒲跨,位于F島的核電站译断,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏或悲。R本人自食惡果不足惜孙咪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一堪唐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧翎蹈,春花似錦淮菠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至澄阳,卻和暖如春拥知,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背寇荧。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工举庶, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人揩抡。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓户侥,卻偏偏與公主長得像,于是被迫代替她去往敵國和親峦嗤。 傳聞我的和親對象是個殘疾皇子蕊唐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359

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

  • 很慶幸自己在百無聊賴中打開的是這樣一部影片替梨,看見他你需要尋尋覓覓,愛上他只需要一秒鐘装黑。 1副瀑、“關(guān)于職業(yè)” 寫本篇之...
    A味良明查閱讀 688評論 0 51
  • 今天陳一舫到衡
    llfcxllc閱讀 151評論 0 0
  • 已經(jīng)學(xué)習(xí)了三大模塊,今天進(jìn)入五大數(shù)字力第四模塊:財(cái)務(wù)結(jié)構(gòu)恋谭。 0糠睡、財(cái)務(wù)結(jié)構(gòu) 一個公司的財(cái)務(wù)結(jié)構(gòu)包含兩個指標(biāo):負(fù)債占資...
    吳佩在天涯閱讀 194評論 0 1
  • 這里所說的“情”不是感情,是情緒疚颊,狈孔。 情緒的范圍太廣,憤怒材义,恐懼均抽,難過,求關(guān)注其掂,求存在油挥,求回應(yīng),這些都是大部分人所...
    東岳不是泰山閱讀 153評論 0 5
  • 這個問題一直梗在婆婆和我之間。婆婆說:“你在家的時候喘漏,孩子根本不聽我們的話”护蝶。我聽到這個內(nèi)心是憤怒的,什么意思翩迈?我...
    云中看花閱讀 139評論 0 0