講講一條MySQL更新語句是怎么執(zhí)行的?

這是在網(wǎng)上找到的一張流程圖唬党,寫的比較好鹃共,大家可以先看圖,然后看詳細(xì)閱讀下面的各個(gè)步驟驶拱。

執(zhí)行流程:

1.連接驗(yàn)證及解析

客戶端與MySQL Server建立連接霜浴,發(fā)送語句給MySQL Server,接收到后會(huì)針對(duì)這條語句創(chuàng)建一個(gè)解析樹蓝纲,然后進(jìn)行優(yōu)化阴孟,(解析器知道語句是要執(zhí)行什么,會(huì)評(píng)估使用各種索引的代價(jià)税迷,然后去使用索引永丝,以及調(diào)節(jié)表的連接順序)然后調(diào)用innodb引擎的接口來執(zhí)行語句。

2.寫undo log

innodb 引擎首先開啟事務(wù)箭养,對(duì)舊數(shù)據(jù)生成一個(gè)反向的UPDATE的語句(如果是INSERT會(huì)生成反向的DELETE語句)慕嚷,用于提交失敗后回滾,寫入undo log毕泌,得到回滾指針喝检,并且更新這個(gè)數(shù)據(jù)行的回滾指針和版本號(hào)(會(huì)設(shè)置為更新的事務(wù)id)。

3.從索引中查找數(shù)據(jù)

根據(jù)查詢條件去B+樹中找到這一行數(shù)據(jù)(如果是唯一性索引撼泛,查到第一個(gè)數(shù)據(jù)就可以了(因?yàn)橛形ㄒ恍约s束)挠说,如果是普通索引,會(huì)把所有數(shù)據(jù)查找出來愿题。)

4.更新數(shù)據(jù)

首先判斷數(shù)據(jù)頁是否在內(nèi)存中损俭?

4.1 如果數(shù)據(jù)頁在內(nèi)存中

先判斷更新的索引是普通索引還是唯一性索引蛙奖?

4.1.1 普通索引

如果更新的索引是普通索引,直接更新內(nèi)存中的數(shù)據(jù)頁

4.1.2 唯一性索引

如果更新的索引是唯一性索引撩炊,判斷更新后是否會(huì)破壞數(shù)據(jù)的唯一性外永,不會(huì)的話就更新內(nèi)存中的數(shù)據(jù)頁崎脉。

4.2 如果數(shù)據(jù)頁不在內(nèi)存中

先判斷更新的索引是普通索引還是唯一性索引拧咳?

4.2.1 普通索引

如果是更新的索引是普通索引,將對(duì)數(shù)據(jù)頁的更新操作記錄到change buffer囚灼,change buffer會(huì)在空閑時(shí)異步更新到磁盤骆膝。

4.2.2 唯一性索引

如果是更新的索引是唯一性索引,因?yàn)樾枰WC更新后的唯一性灶体,所以不能延遲更新阅签,必須把數(shù)據(jù)頁從磁盤加載到內(nèi)存,然后判斷更新后是否會(huì)數(shù)據(jù)沖突蝎抽,不會(huì)的話就更新數(shù)據(jù)頁政钟。

5.寫undo log(prepare狀態(tài))

將對(duì)數(shù)據(jù)頁的更改寫入到redo log,將redo log設(shè)置為prepare狀態(tài)樟结。

6.寫bin log(commit狀態(tài))养交,提交事務(wù)

通知MySQL server已經(jīng)更新操作寫入到redo log 了,隨時(shí)可以提交瓢宦,將執(zhí)行的SQL寫入到bin log日志碎连,將redo log改成commit狀態(tài),事務(wù)提交成功驮履。(一個(gè)事務(wù)是否執(zhí)行成功的判斷依據(jù)是是否在bin log中寫入成功鱼辙。寫入成功后,即便MySQL Server崩潰玫镐,之后恢復(fù)時(shí)也會(huì)根據(jù)bin log倒戏, redo log進(jìn)行恢復(fù)。具體可以看看下面的崩潰恢復(fù)原則)

補(bǔ)充資料:

二段提交制是什么恐似?

更新時(shí)杜跷,先改內(nèi)存中的數(shù)據(jù)頁,將更新操作寫入redo log日志蹂喻,此時(shí)redo log進(jìn)入prepare狀態(tài)葱椭,然后通知MySQL Server執(zhí)行完了,隨時(shí)可以提交口四,MySQL Server將更新的SQL寫入bin log孵运,然后調(diào)用innodb接口將redo log設(shè)置為提交狀態(tài),更新完成蔓彩。

如果只是寫了bin log就提交治笨,那么忽然發(fā)生故障驳概,主節(jié)點(diǎn)可以根據(jù)redo log恢復(fù)數(shù)據(jù)到最新,但是主從同步時(shí)會(huì)丟掉這部分更新的數(shù)據(jù)旷赖。

如果只是寫binlog顺又,然后寫redo log,如果忽然發(fā)生故障等孵,主節(jié)點(diǎn)根據(jù)redo log恢復(fù)數(shù)據(jù)時(shí)就會(huì)丟掉這部分?jǐn)?shù)據(jù)稚照。

MySQL崩潰后,事務(wù)恢復(fù)時(shí)的判斷規(guī)則是怎么樣的俯萌?(以redolog是否commit或者binlog是否完整來確定)

如果 redo log 里面的事務(wù)是完整的果录,也就是已經(jīng)有了 commit 標(biāo)識(shí),則直接提交咐熙;

如果 redo log 里面的事務(wù)只有完整的 prepare弱恒,則判斷對(duì)應(yīng)的事務(wù) binlog 是否存在并完整:a. 如果是,則提交事務(wù)棋恼;b. 否則返弹,回滾事務(wù)。

undo log是什么爪飘?

undo log主要是保證事務(wù)的原子性义起,事務(wù)執(zhí)行失敗就回滾,用于在事務(wù)執(zhí)行失敗后悦施,對(duì)數(shù)據(jù)回滾并扇。undo log是邏輯日志,記錄的是SQL抡诞。(可以認(rèn)為當(dāng)delete一條記錄時(shí)穷蛹,undo log中會(huì)記錄一條對(duì)應(yīng)的insert記錄,反之亦然昼汗,當(dāng)update一條記錄時(shí)肴熏,它記錄一條對(duì)應(yīng)相反的update記錄。)

在事務(wù)提交后顷窒,undo log日志不會(huì)立即刪除蛙吏,會(huì)放到一個(gè)待刪除的鏈表中,有purge線程判斷是否有其他事務(wù)在使用上一個(gè)事務(wù)之前的版本信息鞋吉,然后決定是否可以清理鸦做,簡單的來說就是前面的事務(wù)都提交成功了,這些undo才能刪除谓着。

change buffer是什么(就是將更新數(shù)據(jù)頁的操作緩存下來)

在更新數(shù)據(jù)時(shí)泼诱,如果數(shù)據(jù)行所在的數(shù)據(jù)頁在內(nèi)存中,直接更新內(nèi)存中的數(shù)據(jù)頁赊锚。

如果不在內(nèi)存中治筒,為了減少磁盤IO的次數(shù)屉栓,innodb會(huì)將這些更新操作緩存在change buffer中,在下一次查詢時(shí)需要訪問這個(gè)數(shù)據(jù)頁時(shí)耸袜,在執(zhí)行change buffer中的操作對(duì)數(shù)據(jù)頁進(jìn)行更新友多。

適合寫多讀少的場景,因?yàn)檫@樣即便立即寫了堤框,也不太可能會(huì)被訪問到域滥,延遲更新可以減少磁盤I/O,只有普通索引會(huì)用到胰锌,因?yàn)槲ㄒ恍运饕疲诟聲r(shí)就需要判斷唯一性藐窄,所以沒有必要资昧。

redo log 是什么?

redo log就是為了保證事務(wù)的持久性荆忍。因?yàn)閏hange buffer是存在內(nèi)存中的格带,萬一機(jī)器重啟,change buffer中的更改沒有來得及更新到磁盤刹枉,就需要根據(jù)redo log來找回這些更新叽唱。

優(yōu)點(diǎn)是減少磁盤I/O次數(shù),即便發(fā)生故障也可以根據(jù)redo log來將數(shù)據(jù)恢復(fù)到最新狀態(tài)微宝。

缺點(diǎn)是會(huì)造成內(nèi)存臟頁棺亭,后臺(tái)線程會(huì)自動(dòng)對(duì)臟頁刷盤,或者是淘汰數(shù)據(jù)頁時(shí)刷盤蟋软,此時(shí)收到的查詢請(qǐng)求需要等待镶摘,影響查詢。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末岳守,一起剝皮案震驚了整個(gè)濱河市凄敢,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌湿痢,老刑警劉巖涝缝,帶你破解...
    沈念sama閱讀 221,406評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異譬重,居然都是意外死亡拒逮,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,395評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門臀规,熙熙樓的掌柜王于貴愁眉苦臉地迎上來滩援,“玉大人,你說我怎么就攤上這事以现『菰梗” “怎么了约啊?”我有些...
    開封第一講書人閱讀 167,815評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長佣赖。 經(jīng)常有香客問我恰矩,道長,這世上最難降的妖魔是什么憎蛤? 我笑而不...
    開封第一講書人閱讀 59,537評(píng)論 1 296
  • 正文 為了忘掉前任外傅,我火速辦了婚禮,結(jié)果婚禮上俩檬,老公的妹妹穿的比我還像新娘萎胰。我一直安慰自己,他們只是感情好棚辽,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,536評(píng)論 6 397
  • 文/花漫 我一把揭開白布技竟。 她就那樣靜靜地躺著,像睡著了一般屈藐。 火紅的嫁衣襯著肌膚如雪榔组。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,184評(píng)論 1 308
  • 那天联逻,我揣著相機(jī)與錄音搓扯,去河邊找鬼。 笑死包归,一個(gè)胖子當(dāng)著我的面吹牛锨推,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播公壤,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼换可,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼!你這毒婦竟也來了境钟?” 一聲冷哼從身側(cè)響起锦担,我...
    開封第一講書人閱讀 39,668評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎慨削,沒想到半個(gè)月后洞渔,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,212評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡缚态,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,299評(píng)論 3 340
  • 正文 我和宋清朗相戀三年磁椒,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片玫芦。...
    茶點(diǎn)故事閱讀 40,438評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡浆熔,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出桥帆,到底是詐尸還是另有隱情医增,我是刑警寧澤慎皱,帶...
    沈念sama閱讀 36,128評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站叶骨,受9級(jí)特大地震影響茫多,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜忽刽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,807評(píng)論 3 333
  • 文/蒙蒙 一天揖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧跪帝,春花似錦今膊、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,279評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至纸泄,卻和暖如春赖钞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背聘裁。 一陣腳步聲響...
    開封第一講書人閱讀 33,395評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留弓千,地道東北人衡便。 一個(gè)月前我還...
    沈念sama閱讀 48,827評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像洋访,于是被迫代替她去往敵國和親镣陕。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,446評(píng)論 2 359