MySQL-事務(wù)&MVCC

前置文章:
一险毁、MySQL-存儲(chǔ)引擎

零疙教、本文綱要

  • 一容贝、事務(wù)
  • 二、MySQL事務(wù)原理
  • 三楼眷、redo log(重做日志)
  • 四铲汪、undo log(回滾日志)
  • 五熊尉、MVCC
    1焚挠、當(dāng)前讀
    2麸俘、快照讀
    3、MVCC實(shí)現(xiàn)
    4轻纪、MVCC原理分析

tips:Ctrl + F快速定位所需內(nèi)容閱讀吧齿梁。

一催植、事務(wù)

1、事務(wù)介紹

事務(wù)是一組操作的集合士飒,它是一個(gè)不可分割的工作單位查邢,事務(wù)會(huì)把所有的操作作為一個(gè)整體一起向系統(tǒng)提交或撤銷操作的請(qǐng)求,即這些操作要么同時(shí)成功酵幕,要么同時(shí)失敗扰藕。

2、事務(wù)特性

  • 原子性(Atomicity):事務(wù)是不可分割的最小操作單元芳撒,要么全部成功邓深,要么全部失敗笔刹;
  • 一致性(Consistency):事務(wù)完成時(shí)芥备,必須使所有的數(shù)據(jù)都保持一致狀態(tài);
  • 隔離性(Isolation):數(shù)據(jù)庫系統(tǒng)提供的隔離機(jī)制舌菜,保證事務(wù)在不受外部并發(fā)操作影響的獨(dú)立環(huán)境下運(yùn)行萌壳;
  • 持久性(Durability):事務(wù)一旦提交或回滾,它對(duì)數(shù)據(jù)庫中的數(shù)據(jù)的改變就是永久的日月。

二袱瓮、MySQL事務(wù)原理

1、redo log & undo log

InnoDB中使用redo logundo log來保證事務(wù)的原子性爱咬、一致性尺借、持久性。

2精拟、鎖 & MVCC

InnoDB中使用MVCC來保證事務(wù)的隔離性燎斩。

三、redo log(重做日志)

InnoDB架構(gòu).png

1蜂绎、redo log介紹

redo log(重做日志)栅表,記錄的是事務(wù)提交時(shí)數(shù)據(jù)頁的物理修改,是用來實(shí)現(xiàn)事務(wù)的持久性师枣。

2谨读、redo log作用

該日志文件由兩部分組成:重做日志緩沖(redo log buffer)以及重做日志文件(redo log file),前者是在內(nèi)存中坛吁,后者在磁盤中劳殖。
當(dāng)事務(wù)提交之后會(huì)把所有修改信息都存到該日志文件中,用于在刷新臟頁到磁盤拨脉,發(fā)生錯(cuò)誤時(shí)哆姻,進(jìn)行數(shù)據(jù)恢復(fù)使用。

3玫膀、對(duì)比redo log有無情形

對(duì)比redo log有無情形.png
  • 有redo log:

① 當(dāng)對(duì)緩沖區(qū)的數(shù)據(jù)進(jìn)行增刪改之后矛缨,會(huì)首先將操作的數(shù)據(jù)頁的變化,記錄在redo log buffer中帖旨;
② 在事務(wù)提交時(shí)箕昭,會(huì)將redo log buffer中的數(shù)據(jù)刷新到redo log磁盤文件中;
③ 過一段時(shí)間之后解阅,如果刷新緩沖區(qū)的臟頁到磁盤時(shí)落竹,發(fā)生錯(cuò)誤,此時(shí)就可以借助于redo log進(jìn)行數(shù)據(jù)恢復(fù)货抄,這樣就保證了事務(wù)的持久性述召;
④ 而如果臟頁成功刷新到磁盤 或 或者涉及到的數(shù)據(jù)已經(jīng)落盤,此時(shí)redolog就沒有作用了蟹地,就可以刪除了积暖,所以存在的兩個(gè)redolog文件是循環(huán)寫的。

#ib_logfile0
#ib_logfile1

4怪与、WAL

在業(yè)務(wù)操作中夺刑,我們操作數(shù)據(jù)一般都是隨機(jī)讀寫磁盤的,而不是順序讀寫磁盤分别。 而redo log在往磁盤文件中寫入數(shù)據(jù)遍愿,由于是日志文件,所以都是順序?qū)?/code>的茎杂。順序?qū)懙男蚀砝溃h(yuǎn)大于隨機(jī)寫。這種先寫日志的方式煌往,稱之為 WAL(Write-Ahead Logging)倾哺。

5、刷盤時(shí)機(jī)

innodb_flush_log_at_trx_commit:

0: 每秒將日志寫入并刷新到磁盤一次刽脖;
1: 日志在每次事務(wù)提交時(shí)寫入并刷新到磁盤羞海,默認(rèn)值;
2: 日志在每次事務(wù)提交后寫入曲管,并每秒刷新到磁盤一次却邓。

四、undo log(回滾日志)

1院水、undo log介紹

回滾日志(也稱撤銷日志)腊徙,用于記錄數(shù)據(jù)被修改前的信息 , 作用包含兩個(gè) : 提供回滾(保證事務(wù)的原子性)MVCC(多版本并發(fā)控制)简十。
undo log記錄的是邏輯日志,可以認(rèn)為記錄的是與我們執(zhí)行的update撬腾、insert螟蝙、delete相反的邏輯語句。

2民傻、undo log銷毀

undo log在事務(wù)執(zhí)行時(shí)產(chǎn)生胰默,事務(wù)提交時(shí),并不會(huì)立即刪除undo log漓踢,因?yàn)檫@些日志可能還用于MVCC牵署。

3、undo log存儲(chǔ)

undo log采用段的方式進(jìn)行管理和記錄喧半,存放在rollback segment回滾段中奴迅,內(nèi)部包含1024個(gè)undo log segment。

五薯酝、MVCC

1半沽、當(dāng)前讀

讀取的是記錄的最新版本,讀取時(shí)還要保證其他并發(fā)事務(wù)不能修改當(dāng)前記錄吴菠,會(huì)對(duì)讀取的記錄進(jìn)行加鎖者填。

  • ① 對(duì)應(yīng)SQL
  • select ... lock in share mode(共享鎖);
  • select ...for update(排它鎖)做葵;
  • update占哟、insert、delete(排它鎖)酿矢。
  • ② 演示示例

Ⅰ 事務(wù)B提交后榨乎,事務(wù)A當(dāng)前讀,可以讀到最新數(shù)據(jù)瘫筐,如下:

當(dāng)前讀.png

Ⅱ 事務(wù)B提交后蜜暑,事務(wù)A快照讀,不能讀到最新數(shù)據(jù)策肝,如下:

快照讀.png

2肛捍、快照讀

簡(jiǎn)單的select(不加鎖)就是快照讀,快照讀之众,讀取的是記錄數(shù)據(jù)的可見版本拙毫,有可能是歷史數(shù)據(jù),不加鎖棺禾,是非阻塞讀缀蹄。

  • ① 快照讀的不同情形
  • Read Committed:每次select,都生成一個(gè)快照讀;
  • Repeatable Read:開啟事務(wù)后第一個(gè)select語句才是快照讀的地方缺前;
  • Serializable:快照讀會(huì)退化為當(dāng)前讀蛀醉。
  • ② 演示示例

具體示例見上。

3诡延、MVCC實(shí)現(xiàn)

MVCC全稱 Multi-Version Concurrency Control滞欠,多版本并發(fā)控制。指維護(hù)一個(gè)數(shù)據(jù)的多個(gè)版本肆良,使得讀寫操作沒有沖突,快照讀為MySQL實(shí)現(xiàn)MVCC提供了一個(gè)非阻塞讀功能逸绎。MVCC的具體實(shí)現(xiàn)惹恃,還需要依賴于數(shù)據(jù)庫記錄中的三個(gè)隱式字段undo log日志棺牧、readView巫糙。

  • ① 三個(gè)隱式字段

DB_TRX_ID:最近修改事務(wù)ID,記錄插入這條記錄或最后一次修改該記錄的事務(wù)ID颊乘;
DB_ROLL_PTR回滾指針参淹,指向這條記錄的上一個(gè)版本,用于配合undo log乏悄,指向上一個(gè)版本浙值;
DB_ROW_ID隱藏主鍵,如果表結(jié)構(gòu)沒有指定主鍵檩小,將會(huì)生成該隱藏字段开呐。

查看.ibd文件存儲(chǔ)位置的命令:show global variables like '%datadir%';,位置為/var/lib/mysql/规求,如下:

 show global variables like '%datadir%';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| datadir       | /var/lib/mysql/ |
+---------------+-----------------+

查看表結(jié)構(gòu)信息的指令筐付,如下:

ibd2sdi ***.ibd

演示示例:

-- 創(chuàng)建未設(shè)置主鍵的tb_test02表格
create table tb_test02 (id int , name varchar(10));

-- 查看tb_test02表格的各列信息
[root@localhost test]# ibd2sdi tb_test02.ibd

-- 截取指令輸出的關(guān)鍵內(nèi)容
        "columns": [
            {
                "name": "id",
            },
            {
                "name": "name",
            },
            {
                "name": "DB_ROW_ID",
            },
            {
                "name": "DB_TRX_ID",
            },
            {
                "name": "DB_ROLL_PTR",
            }
        ],
  • ② undo log(回滾日志)

回滾日志(又稱撤銷日志),在insert阻肿、update瓦戚、delete的時(shí)候產(chǎn)生的便于數(shù)據(jù)回滾的日志。

Ⅰ 當(dāng)insert的時(shí)候丛塌,產(chǎn)生的undo log日志只在回滾時(shí)需要较解,在事務(wù)提交后,可被立即刪除姨伤;
Ⅱ 而update哨坪、delete的時(shí)候,產(chǎn)生的undo log日志不僅在回滾時(shí)需要乍楚,在快照讀時(shí)也需要当编,不會(huì)立即被刪除

注意:insert對(duì)快照讀已存在的數(shù)據(jù)不產(chǎn)生影響徒溪,而update和delete可能產(chǎn)生影響忿偷,所以此處會(huì)有區(qū)別金顿。

版本鏈:不同事務(wù)或相同事務(wù)對(duì)同一條記錄進(jìn)行修改,會(huì)導(dǎo)致該記錄的undolog生成一條記錄版本鏈表鲤桥,鏈表的頭部最新的舊記錄揍拆,鏈表尾部最早的舊記錄。

image.png
  • ③ readview(讀視圖)

ReadView(讀視圖)是 快照讀 SQL執(zhí)行時(shí)MVCC提取數(shù)據(jù)的依據(jù)茶凳,記錄并維護(hù)系統(tǒng)當(dāng)前活躍的事務(wù)(未提交的)id嫂拴。

四個(gè)核心字段:
m_ids:當(dāng)前活躍的事務(wù)ID集合;
min_trx_id:最小活躍事務(wù)ID贮喧;
max_trx_id預(yù)分配事務(wù)ID筒狠,當(dāng)前最大事務(wù)ID+1(因?yàn)槭聞?wù)ID是自增的);
creator_trx_id:ReadView創(chuàng)建者的事務(wù)ID箱沦。

版本鏈數(shù)據(jù)的訪問規(guī)則(trx_id是當(dāng)前undolog版本鏈對(duì)應(yīng)事務(wù)ID):

訪問規(guī)則.png

生成ReadView的時(shí)機(jī):
Ⅰ READ COMMITTED :在事務(wù)中每一次執(zhí)行快照讀時(shí)生成ReadView辩恼;
Ⅱ REPEATABLE READ:僅在事務(wù)中第一次執(zhí)行快照讀時(shí)生成ReadView,后續(xù)復(fù)用該ReadView谓形。

4灶伊、MVCC原理分析

  • ① RC(READ COMMITTED)隔離級(jí)別

RC隔離級(jí)別下,在事務(wù)中每一次執(zhí)行快照讀時(shí)生成ReadView寒跳。

每一次執(zhí)行快照讀時(shí)生成ReadView.png

示例解讀:

演示示例RC.png

此情形中聘萨,當(dāng)我們對(duì)比到版本鏈中trx_id = 2的時(shí)候,滿足條件②冯袍,此時(shí)該版本就是版本鏈中事務(wù)5可以讀取到的數(shù)據(jù)匈挖。

  • ② RR(REPEATABLE READ)隔離級(jí)別

RR隔離級(jí)別下,僅在事務(wù)中第一次執(zhí)行快照讀時(shí)生成ReadView康愤,后續(xù)復(fù)用該ReadView儡循。RR 是可重復(fù)讀,在一個(gè)事務(wù)中征冷,執(zhí)行兩次相同的select語句择膝,查詢到的結(jié)果是一樣的。

第一次執(zhí)行快照讀時(shí)生成ReadView.png

六检激、結(jié)尾

以上即為事務(wù)和MVCC部分的內(nèi)容了肴捉,感謝閱讀。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末叔收,一起剝皮案震驚了整個(gè)濱河市齿穗,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌饺律,老刑警劉巖窃页,帶你破解...
    沈念sama閱讀 211,348評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡脖卖,警方通過查閱死者的電腦和手機(jī)乒省,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來畦木,“玉大人袖扛,你說我怎么就攤上這事∈” “怎么了蛆封?”我有些...
    開封第一講書人閱讀 156,936評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)妓雾。 經(jīng)常有香客問我娶吞,道長(zhǎng),這世上最難降的妖魔是什么械姻? 我笑而不...
    開封第一講書人閱讀 56,427評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮机断,結(jié)果婚禮上楷拳,老公的妹妹穿的比我還像新娘。我一直安慰自己吏奸,他們只是感情好欢揖,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評(píng)論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著奋蔚,像睡著了一般她混。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上泊碑,一...
    開封第一講書人閱讀 49,785評(píng)論 1 290
  • 那天坤按,我揣著相機(jī)與錄音,去河邊找鬼馒过。 笑死臭脓,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的腹忽。 我是一名探鬼主播来累,決...
    沈念sama閱讀 38,931評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼窘奏!你這毒婦竟也來了嘹锁?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,696評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤着裹,失蹤者是張志新(化名)和其女友劉穎领猾,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,141評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瘤运,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評(píng)論 2 327
  • 正文 我和宋清朗相戀三年窍霞,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片拯坟。...
    茶點(diǎn)故事閱讀 38,625評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡但金,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出郁季,到底是詐尸還是另有隱情冷溃,我是刑警寧澤,帶...
    沈念sama閱讀 34,291評(píng)論 4 329
  • 正文 年R本政府宣布梦裂,位于F島的核電站似枕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏年柠。R本人自食惡果不足惜凿歼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望冗恨。 院中可真熱鬧答憔,春花似錦、人聲如沸掀抹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽傲武。三九已至蓉驹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間揪利,已是汗流浹背态兴。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留土童,地道東北人诗茎。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像献汗,于是被迫代替她去往敵國(guó)和親敢订。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評(píng)論 2 348

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