MYSQL語(yǔ)句執(zhí)行大體流程

學(xué)習(xí)筆記是學(xué)習(xí)了 極客時(shí)間 - 《MySQL實(shí)戰(zhàn)45講》整理的筆記辙售。

MYSQL簡(jiǎn)單架構(gòu)

MySQL 可以分為 Server 層和存儲(chǔ)引擎層兩部分。

  • Server 層: Server 層包括連接器、查詢緩存、分析器、優(yōu)化器、執(zhí)行器等顿膨,涵蓋 MySQL 的大多數(shù)核
    心服務(wù)功能,以及所有的內(nèi)置函數(shù)(如日期叽赊、時(shí)間恋沃、數(shù)學(xué)和加密函數(shù)等),所有跨存儲(chǔ)引擎的功能都在這一層實(shí)現(xiàn)必指,比如存儲(chǔ)過(guò)程囊咏、觸發(fā)器、視圖等塔橡。梅割,不同的存儲(chǔ)引擎共用一個(gè)Server 層,也就是從連接器到執(zhí)行器的部分葛家。
    • 連接器:連接器負(fù)責(zé)跟客戶端建立連接户辞、獲取權(quán)限、維持和管理連接癞谒。
    • 查詢緩存(MySQL 8.0版本以后直接取消了查詢緩存的整塊功能):MySQL 拿到一個(gè)查詢請(qǐng)求后底燎,會(huì)先到查詢緩存看看,之前是不是執(zhí)行過(guò)這條語(yǔ)句弹砚。之前執(zhí)行過(guò)的語(yǔ)句及其結(jié)果可能會(huì)以 key-value 對(duì)的形式双仍,被直接緩存在內(nèi)存中。key 是查詢的語(yǔ)句迅栅,value 是查詢的結(jié)果殊校。如果你的查詢能夠直接在這個(gè)緩存中找到 key晴玖,那么這個(gè)value 就會(huì)被直接返回給客端读存。
      • 對(duì)于更新頻繁的數(shù)據(jù)庫(kù)表,不建議查詢緩存。查詢緩存的失效非常頻繁呕屎,只要有對(duì)一個(gè)表的更新让簿,這個(gè)表上所有的查詢緩存都會(huì)被清空。因此很可能你費(fèi)勁地把結(jié)果存起來(lái)秀睛,還沒(méi)使用呢尔当,就被一個(gè)更新全清空了。對(duì)于更新壓力大的數(shù)據(jù)庫(kù)來(lái)說(shuō),查詢緩存的命中率會(huì)非常低椭迎。
      • 按需配置:
        • 關(guān)閉緩存:將參數(shù) query_cache_type 設(shè)置成 DEMAND锐帜,這樣對(duì)于默認(rèn)的 SQL 語(yǔ)句都不使用查詢緩存。
        • 設(shè)置緩存:用 SQL_CACHE 顯式指定 select SQL_CACHE * from T where ID=10畜号;
    • 分析器:
      • 詞法分析
      • 語(yǔ)法分析
    • 優(yōu)化器:在表里面有多個(gè)索引的時(shí)候缴阎,決定使用哪個(gè)索引
    • 執(zhí)行器:
      • 判斷權(quán)限
      • 調(diào)用引擎接口
  • 存儲(chǔ)引擎層:存儲(chǔ)引擎層負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)和提取。

MYSQL中 SQL語(yǔ)句的執(zhí)行流程

查詢語(yǔ)句執(zhí)行流程如圖:

msql查詢.png

更新語(yǔ)句執(zhí)行流程(InnoDB引擎)

InnoDB架構(gòu)

InnoDB架構(gòu).png

在更新語(yǔ)句執(zhí)行流程中简软,大部分會(huì)使用到內(nèi)存池蛮拔。

執(zhí)行SQL語(yǔ)句

update T set c=c+1 where ID=2;
update.png

可以看到 更新語(yǔ)句執(zhí)行的時(shí)候,涉及到了兩個(gè)重要的日志模塊痹升。

WAL 技術(shù)

為什么會(huì)涉及這兩個(gè)模塊建炫,首先我們需要了解一下 MYSQL WAL 技術(shù),WAL 的全稱是 Write-Ahead Logging疼蛾,它的關(guān)鍵點(diǎn)就是先寫(xiě)日志肛跌,再寫(xiě)磁盤(pán)。具體來(lái)說(shuō)据过,當(dāng)有一條記錄需要更新的時(shí)候惋砂,InnoDB 引擎就會(huì)先把記錄寫(xiě)到redo log里面,并更新內(nèi)存绳锅,這個(gè)時(shí)候更新就算完成了西饵。同時(shí),InnoDB 引擎會(huì)在適當(dāng)?shù)臅r(shí)候鳞芙,將這個(gè)操作記錄更新到磁盤(pán)里面眷柔,而這個(gè)更新往往是在系統(tǒng)比較空閑的時(shí)候做。

  • redo log(重做日志): InnoDB 引擎特有的日志并且是固定大小,循環(huán)寫(xiě)入機(jī)制原朝。比如4個(gè)日志文件如下圖所示驯嘱。
relog1.png

write pos 是當(dāng)前記錄的位置,一邊寫(xiě)一邊后移喳坠,寫(xiě)到第 3 號(hào)文件末尾后就回到 0 號(hào)文件開(kāi)頭鞠评。checkpoint 是當(dāng)前要擦除的位置,也是往后推移并且循環(huán)的壕鹉,擦除記錄前要把記錄更新到數(shù)據(jù)文件剃幌。write pos checkpoint 之間的是用來(lái)記錄新的操作。如果 write pos 追上 checkpoint晾浴,如要將數(shù)據(jù)寫(xiě)入磁盤(pán)后在進(jìn)行下一步操作负乡。

  • 優(yōu)點(diǎn):保證即使數(shù)據(jù)庫(kù)發(fā)生異常重啟,之前提交的記錄都不會(huì)丟失脊凰,這個(gè)能力稱為crash-safe抖棘。

  • redo log 是物理日志,記錄的是“在某個(gè)數(shù)據(jù)頁(yè)上做了什么修改”;如下圖所示:

  • 參數(shù)配置:innodb_flush_log_at_trx_commit 這個(gè)參數(shù)設(shè)置成1 的時(shí)候切省,表示每次事務(wù)的 redo log 都直接持久化到磁盤(pán)最岗。

  • binlog(歸檔日志):是 MySQL 的 Server 層實(shí)現(xiàn)的,所有引擎都可以使用朝捆。只能用于歸檔(備份)仑性。其主要記錄的是SQL語(yǔ)句原始的邏輯。如下圖所示:

    • 參數(shù)配置:sync_binlog 這個(gè)參數(shù)設(shè)置成 1 的時(shí)候右蹦,表示每次事務(wù)的 binlog 都持久化到磁盤(pán)诊杆。
    • Binlog有兩種模式,statement 格式的話是記sql語(yǔ)句何陆, row格式會(huì)記錄行的內(nèi)容晨汹,記兩條,更
      新前和更新后都有贷盲。

對(duì)比

redo log binlog
實(shí)現(xiàn) InnoDB 引擎特有 Server 層所有引擎都可以使用淘这。
類別 物理日志,記錄的是“在某個(gè)數(shù)據(jù)頁(yè)上做了什么修改” binlog 是邏輯日志巩剖,記錄的是這個(gè)語(yǔ)句的原始邏輯铝穷。比如“給 ID=2 這一行的 c 字段加 1 ”。
寫(xiě)入方式 循環(huán) 追加佳魔,文件寫(xiě)到一定大小后會(huì)切換到下一個(gè)曙聂,并不會(huì)覆蓋以前的日志。

兩階段提交( prepare 和commit

在之前的邏輯圖中我們可以看到鞠鲜,進(jìn)行了兩階段提交操作宁脊,為了讓兩份日志之間的邏輯一致。通過(guò)一種特殊的xid贤姆,可以在兩階段提交的不同時(shí)刻發(fā)生異常重啟時(shí)榆苞,將redo和binlog聯(lián)系起來(lái)。如下:

 [Note] Found 1 prepared transaction(s) in InnoDB
 [Note] commit xid 'MySQLXid\1\0\0\0\0\0\0\0\6\0\0\0\0\0\0\0'
非兩階段提交出現(xiàn)宕機(jī)問(wèn)題 以update T set c=c+1 where ID=2;為例
  1. 先寫(xiě) redo log 后寫(xiě) binlog霞捡。假設(shè)在 redo log 寫(xiě)完坐漏,binlog 還沒(méi)有寫(xiě)完的時(shí)候,MySQL 進(jìn)程異常重啟碧信。由于我們前面說(shuō)過(guò)的赊琳,redo log 寫(xiě)完之后,系統(tǒng)即使崩潰音婶,仍然能夠把數(shù)據(jù)恢復(fù)回來(lái)慨畸,所以恢復(fù)后這一行 c 的值是 1莱坎。但是由于 binlog 沒(méi)寫(xiě)完就 crash 了衣式,這時(shí)候 binlog 里面就沒(méi)有記錄這個(gè)語(yǔ)句。因此,之后備份日志的時(shí)候碴卧,存起來(lái)的 binlog 里面就沒(méi)有這條語(yǔ)句弱卡。然后你會(huì)發(fā)現(xiàn),如果需要用這個(gè) binlog 來(lái)恢復(fù)臨時(shí)庫(kù)的話住册,由于這個(gè)語(yǔ)句的 binlog 丟失婶博,這個(gè)臨時(shí)庫(kù)就會(huì)少了這一次更新,恢復(fù)出來(lái)的這一行 c 的值就是 0荧飞,與原庫(kù)的值不同凡人。
  2. 先寫(xiě) binlog 后寫(xiě) redo log。如果在 binlog 寫(xiě)完之后 crash叹阔,由于 redo log 還沒(méi)寫(xiě)挠轴,崩潰恢復(fù)以后這個(gè)事務(wù)無(wú)效,所以這一行 c 的值是 0耳幢。但是 binlog 里面已經(jīng)記錄了“把 c 從 0 改成 1”這個(gè)日志岸晦。所以,在之后用 binlog 來(lái)恢復(fù)的時(shí)候就多了一個(gè)事務(wù)出來(lái)睛藻,恢復(fù)出來(lái)的這一行 c 的值就是 1启上,與原庫(kù)的值不同。

關(guān)于 binlog 和 redo log更為深入的了解 推薦閱讀:一文帶你看懂binlog和redo log

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末店印,一起剝皮案震驚了整個(gè)濱河市冈在,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌按摘,老刑警劉巖讥邻,帶你破解...
    沈念sama閱讀 218,858評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異院峡,居然都是意外死亡兴使,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,372評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)照激,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)发魄,“玉大人,你說(shuō)我怎么就攤上這事俩垃±祝” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,282評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵口柳,是天一觀的道長(zhǎng)苹粟。 經(jīng)常有香客問(wèn)我,道長(zhǎng)跃闹,這世上最難降的妖魔是什么嵌削? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,842評(píng)論 1 295
  • 正文 為了忘掉前任毛好,我火速辦了婚禮,結(jié)果婚禮上苛秕,老公的妹妹穿的比我還像新娘肌访。我一直安慰自己,他們只是感情好艇劫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,857評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布吼驶。 她就那樣靜靜地躺著,像睡著了一般店煞。 火紅的嫁衣襯著肌膚如雪蟹演。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 51,679評(píng)論 1 305
  • 那天顷蟀,我揣著相機(jī)與錄音轨帜,去河邊找鬼。 笑死衩椒,一個(gè)胖子當(dāng)著我的面吹牛蚌父,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播毛萌,決...
    沈念sama閱讀 40,406評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼苟弛,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了阁将?” 一聲冷哼從身側(cè)響起膏秫,我...
    開(kāi)封第一講書(shū)人閱讀 39,311評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎做盅,沒(méi)想到半個(gè)月后缤削,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,767評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡吹榴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年亭敢,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片图筹。...
    茶點(diǎn)故事閱讀 40,090評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡帅刀,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出远剩,到底是詐尸還是另有隱情扣溺,我是刑警寧澤,帶...
    沈念sama閱讀 35,785評(píng)論 5 346
  • 正文 年R本政府宣布瓜晤,位于F島的核電站锥余,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏痢掠。R本人自食惡果不足惜驱犹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,420評(píng)論 3 331
  • 文/蒙蒙 一嘲恍、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧着绷,春花似錦、人聲如沸锌云。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,988評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)桑涎。三九已至彬向,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間攻冷,已是汗流浹背娃胆。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,101評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留等曼,地道東北人里烦。 一個(gè)月前我還...
    沈念sama閱讀 48,298評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像禁谦,于是被迫代替她去往敵國(guó)和親胁黑。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,033評(píng)論 2 355

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