從Mysql架構(gòu)到Mysql事務(wù)分析

萬事皆由不是空穴來風(fēng)悉稠,任何技術(shù)的底層都有一套嚴(yán)謹(jǐn)?shù)募軜?gòu)。

前景

說到事務(wù),我們都知道“回滾”這個概念赁炎,在一個方法上加上@Transactional 一旦程序遇到異常就會自動回滾是尖,數(shù)據(jù)庫的數(shù)據(jù)原封不動意系,到底是怎么實現(xiàn)回滾機(jī)制?其中 isolation隔離級別又是干什么饺汹?讓我們一起從Mysql底層架構(gòu)開始談起蛔添。

一、Mysql架構(gòu)分析

首先看下邏輯架構(gòu)圖,


image.png

初學(xué)Mysql這個架構(gòu)圖放在眼前有點懵比了吧迎瞧,每個模塊我們分析來看:
1夸溶、Connectors 連接器,指的是不同語言中與SQL的交互
2凶硅、Management Serveices & Utilities:系統(tǒng)管理和控制工具
3缝裁、Connection Pool: 連接池

1)管理緩沖用戶連接,線程處理等需要緩存的需求足绅。
2)負(fù)責(zé)監(jiān)聽對 MySQL Server 的各種請求捷绑,接收連接請求,轉(zhuǎn)發(fā)所有連接請求到線程管理模塊氢妈。每一個連接上 MySQL Server 的客戶端請求都會被分配(或創(chuàng)建)一個連接線程為其單獨服務(wù)粹污。
3)而連接線程的主要工作就是負(fù)責(zé) MySQL Server 與客戶端的通信,接受客戶端的命令請求首量,傳遞 Server 端的結(jié)果信息等壮吩。線程管理模塊則負(fù)責(zé)管理維護(hù)這些連接線程。包括線程的創(chuàng)建蕾总,線程的 cache 等

4粥航、SQL Interface: SQL接口
接受用戶的SQL命令,并且返回用戶需要查詢的結(jié)果生百。比如select from就是調(diào)用SQL Interface

5.Parser: 解析器
SQL命令傳遞到解析器的時候會被解析器驗證和解析递雀。

主要功能
a . 將SQL語句進(jìn)行語義和語法的分析,分解成數(shù)據(jù)結(jié)構(gòu)蚀浆,然后按照不同的操作類型進(jìn)行分類缀程,然后做出針對性的轉(zhuǎn)發(fā)到后續(xù)步驟,以后SQL語句的傳遞和處理就是基于這個結(jié)構(gòu)的市俊。
b. 如果在分解過程中遇到錯誤杨凑,那么就說明這個sql語句是不合理的。

6摆昧、Optimizer: 查詢優(yōu)化器
SQL語句在查詢之前會使用查詢優(yōu)化器對查詢進(jìn)行優(yōu)化撩满。explain語句查看的SQL語句執(zhí)行計劃,就是由查詢優(yōu)化器生成的绅你。

7伺帘、Cache和Buffer:查詢緩存
他的主要功能是將客戶端提交給MySQL的 select請求的返回結(jié)果集 cache 到內(nèi)存中,與該 query 的一個 hash 值 做一個對應(yīng)忌锯。該 Query 所取數(shù)據(jù)的基表發(fā)生任何數(shù)據(jù)的變化之后伪嫁, MySQL 會自動使該 query 的Cache 失效。在讀寫比例非常高的應(yīng)用系統(tǒng)中偶垮, Query Cache 對性能的提高是非常顯著的张咳。當(dāng)然它對內(nèi)存的消耗也是非常大的帝洪。如果查詢緩存有命中的查詢結(jié)果,查詢語句就可以直接去查詢緩存中取數(shù)據(jù)脚猾。這個緩存機(jī)制是由一系列小緩存組成的葱峡。比如表緩存,記錄緩存婚陪,key緩存族沃,權(quán)限緩存等

8、 Pluggable Storage Engines:存儲引擎
與其他數(shù)據(jù)庫例如Oracle 和SQL Server等數(shù)據(jù)庫中只有一種存儲引擎不同的是泌参,MySQL有一個被稱為“Pluggable Storage Engine Architecture”(可插拔的存儲引擎架構(gòu))的特性脆淹,也就意味著MySQL數(shù)據(jù)庫提供了多種存儲引擎。
而且存儲引擎是針對表的沽一,用戶可以根據(jù)不同的需求為數(shù)據(jù)表選擇不同的存儲引擎盖溺,用戶也可以根據(jù)自己的需要編寫自己的存儲引擎。也就是說铣缠,同一數(shù)據(jù)庫不同的表可以選擇不同的存儲引擎烘嘱。

簡單架構(gòu)流程圖

圖片1.png

二、為什么需要事務(wù)

  • 分析update driver_info set driver_status = 2 where driver_id = 10001;這條語句執(zhí)行會有什么問題嗎?
    先理解幾個概念:

1、數(shù)據(jù)庫數(shù)據(jù)存放的文件稱為data file
2梨与、日志文件稱為log file
數(shù)據(jù)庫數(shù)據(jù)是有緩存的,如果沒有緩存哮内,每次都寫或者讀物理disk,那性能就太低下了:
3壮韭、數(shù)據(jù)庫數(shù)據(jù)的緩存稱為data buffer
4北发、日志(redo)緩存稱為log buffer

既然數(shù)據(jù)庫數(shù)據(jù)有緩存,就很難保證緩存數(shù)據(jù)(臟數(shù)據(jù))與磁盤數(shù)據(jù)的一致性喷屋。如下圖


image.png

1到2的過程中一旦發(fā)生服務(wù)宕機(jī)或斷電琳拨,緩存數(shù)據(jù)會丟失,緩存與磁盤數(shù)據(jù)造成不一致問題屯曹。

在并發(fā)環(huán)境下狱庇,如果不做有效控制,會出現(xiàn)什么情況:


image.png

兩個客戶端在操作同一個塊數(shù)據(jù)的時候恶耽,從上圖中可以看出如果沒有處理好磁盤與緩存數(shù)據(jù)一致性的問題,那么讀到緩存的數(shù)據(jù)就會變成臟數(shù)據(jù)密任!緩存存在的意義是為了提供更好的查詢性能,如果連數(shù)據(jù)一致性都無法保證那么毫無意義驳棱!

事務(wù),最終的目的是為了保證數(shù)據(jù)的一致性

三农曲、事務(wù)特性ACID

  • 原子性(Atomicity):事務(wù)中的所有操作作為一個整體像原子一樣不可分割社搅,要么全部成功,要么全部失敗驻债。
  • 一致性(Consistency):事務(wù)的執(zhí)行結(jié)果必須使數(shù)據(jù)庫從一個一致性狀態(tài)到另一個一致性狀態(tài)。一致性狀態(tài)是指:
    1.系統(tǒng)的狀態(tài)滿足數(shù)據(jù)的完整性約束(主碼,參照完整性,check約束等)
    2.系統(tǒng)的狀態(tài)反應(yīng)數(shù)據(jù)庫本應(yīng)描述的現(xiàn)實世界的真實狀態(tài),比如轉(zhuǎn)賬前后兩個賬戶的金額總和應(yīng)該保持不變形葬。
  • 隔離性(Isolation):并發(fā)執(zhí)行的事務(wù)不會相互影響,其對數(shù)據(jù)庫的影響和它們串行執(zhí)行時一樣合呐。比如多個用戶同時往一個賬戶轉(zhuǎn)賬,最后賬戶的結(jié)果應(yīng)該和他們按先后次序轉(zhuǎn)賬的結(jié)果一樣。
  • 持久性(Durability):事務(wù)一旦提交,其對數(shù)據(jù)庫的更新就是持久的笙以。任何事務(wù)或系統(tǒng)故障都不會導(dǎo)致數(shù)據(jù)丟失淌实。

這里我們需要單獨把隔離性拿出來說下:
1、事務(wù)的隔離級別分為四種:


image.png

簡單敘述

  • 臟讀:事務(wù)1讀到事務(wù)2未提交的數(shù)據(jù)猖腕。
  • 不可重復(fù)讀:事務(wù)1第一次讀的數(shù)據(jù)和第二次讀的數(shù)據(jù)不一致拆祈,因為事務(wù)2改變數(shù)據(jù)并提交了。
  • 幻讀:事務(wù)1第一次讀的數(shù)據(jù)行數(shù)和第二次讀的數(shù)據(jù)行數(shù)不一致倘感,因為事務(wù)2新增數(shù)據(jù)并提交了放坏。

事務(wù)的隔離級別是用利用鎖來控制的,Mysql默認(rèn)事務(wù)隔離級別是可重復(fù)讀(RR),但是利用MVCC控制版本來解決幻讀問題老玛。
2淤年、鎖
MySQL的行級鎖,是由存儲引擎來實現(xiàn)的蜡豹,這里我們主要講解InnoDB的行級鎖麸粮。
InnoDB的行級鎖,按照鎖定范圍來說镜廉,分為三種:

  • 記錄鎖(Record Locks):鎖定索引中一條記錄弄诲。

  • 間隙鎖(Gap Locks):要么鎖住索引記錄中間的值,要么鎖住第一個索引記錄前面的值或者最后一個索引記錄后面的值桨吊。

  • Next-Key Locks:是索引記錄上的記錄鎖和在索引記錄之前的間隙鎖的組合威根。

InnoDB的行級鎖,按照功能來說视乐,分為兩種:

  • 共享鎖(S):允許一個事務(wù)去讀一行洛搀,阻止其他事務(wù)獲得相同數(shù)據(jù)集的排他鎖。
  • 排他鎖(X):允許獲得排他鎖的事務(wù)更新數(shù)據(jù)佑淀,阻止其他事務(wù)取得相同數(shù)據(jù)集的共享讀鎖和排他寫鎖留美。

對于UPDATE、DELETE和INSERT語句伸刃,InnoDB會自動給涉及數(shù)據(jù)集加排他鎖(X)谎砾;對于普通SELECT語句,InnoDB不會加任何鎖捧颅,事務(wù)可以通過以下語句顯示給記錄集加共享鎖或排他鎖景图。
手動添加共享鎖(S):
SELECT * FROM table_name WHERE ... LOCK IN SHARE MODE
手動添加排他鎖(x):
SELECT * FROM table_name WHERE ... FOR UPDATE

InnoDB也實現(xiàn)了表級鎖,也就是意向鎖碉哑,意向鎖是mysql內(nèi)部使用的挚币,不需要用戶干預(yù)亮蒋。

  • 意向共享鎖(IS):事務(wù)打算給數(shù)據(jù)行加行共享鎖,事務(wù)在給一個數(shù)據(jù)行加共享鎖前必須先取得該表的IS鎖妆毕。
  • 意向排他鎖(IX):事務(wù)打算給數(shù)據(jù)行加行排他鎖慎玖,事務(wù)在給一個數(shù)據(jù)行加排他鎖前必須先取得該表的IX鎖。
    意向鎖和行鎖可以共存笛粘,意向鎖的主要作用是為了【全表更新數(shù)據(jù)】時的性能提升趁怔。否則在全表更新數(shù)據(jù)時,需要先檢索該范是否某些記錄上面有行鎖薪前。


    image.png

InnoDB行鎖是通過給索引上的索引項加鎖來實現(xiàn)的润努,因此InnoDB這種行鎖實現(xiàn)特點意味著:只有通過索引條件檢索的數(shù)據(jù),InnoDB才使用行級鎖序六,否則任连,InnoDB將使用表鎖!

3例诀、MVCC和一致性非鎖定讀
數(shù)據(jù)庫的并發(fā)控制機(jī)制有很多随抠,最為常見的就是鎖機(jī)制(事務(wù)開始時DQL加讀鎖結(jié)束時釋放讀鎖、同理給DML加寫鎖)繁涂。鎖機(jī)制一般會給競爭資源加鎖拱她,阻塞讀或者寫操作來解決事務(wù)之間的競爭條件,最終保證事務(wù)的可串行化扔罪。
而MVCC則引入了另外一種并發(fā)控制秉沼,它讓讀寫操作互不阻塞,每一個寫操作都會創(chuàng)建一個新版本的數(shù)據(jù)矿酵,讀操作會從有限多個版本的數(shù)據(jù)中挑選一個最合適的結(jié)果直接返回唬复,由此解決了事務(wù)的競爭條件。


image.png

上圖直觀地展現(xiàn)了InnoDB一致性非鎖定讀的機(jī)制全肮。之所以稱其為非鎖定讀敞咧,是因為不需要等待行上排他鎖的釋放」枷伲快照數(shù)據(jù)是指該行的之前版本的數(shù)據(jù)休建,每行記錄可能有多個版本,一般稱這種技術(shù)為行多版本技術(shù)评疗。由此帶來的并發(fā)控制测砂,稱之為多版本并發(fā)控制(Multi Version Concurrency Control, MVCC)。InnoDB是通過undo log來實現(xiàn)MVCC百匆。
在事務(wù)隔離級別READ COMMITTED和REPEATABLE READ下砌些,InnoDB默認(rèn)使用一致性非鎖定讀。然而加匈,對于快照數(shù)據(jù)的定義卻不同存璃。在READ COMMITTED事務(wù)隔離級別下宙彪,一致性非鎖定讀總是讀取被鎖定行的最新一份快照數(shù)據(jù)。而在REPEATABLE READ事務(wù)隔離級別下有巧,則讀取事務(wù)開始時的行數(shù)據(jù)版本。
MVCC使得數(shù)據(jù)庫讀不會對數(shù)據(jù)加鎖悲没,普通的SELECT請求不會加鎖篮迎,提高了數(shù)據(jù)庫的并發(fā)處理能力。借助MVCC示姿,數(shù)據(jù)庫可以實現(xiàn)READ COMMITTED甜橱,REPEATABLE READ等隔離級別,用戶可以查看當(dāng)前數(shù)據(jù)的前一個或者前幾個歷史版本栈戳,保證了ACID中的I特性(隔離性)

四岂傲、理解幾個問題

  • 怎么實現(xiàn)回滾?
    簡單理解子檀,如果有個迷宮你想要通過它镊掖,但是你也不知道能不能通過,當(dāng)你走到半途中發(fā)現(xiàn)自己無法再走下去的時候你要返回去褂痰,那你該怎么返回呢亩进,是不是應(yīng)該在進(jìn)入的途中走一步就在墻上標(biāo)記“回去的方向”
    (undo log)
  • 在事務(wù)提交入庫的過程中尚有臟頁未寫入磁盤,這時服務(wù)發(fā)生故障時該怎么辦缩歪?(redo log)
  • 多個事務(wù)存在的情況归薛,怎么管理好事務(wù)間的隔離關(guān)系?
    (通過鎖和MVCC多版本控制來實現(xiàn)匪蝙,其中MVCC可以解決RR隔離級別下 幻讀的問題)

五主籍、引入事務(wù)日志

事務(wù)日志是在存儲引擎層面的,像bin log是mysql server層面的日志,不能混淆逛球。

1千元、回滾日志undo log

作用: 保存了事務(wù)發(fā)生之前的數(shù)據(jù)的一個版本,可以用于回滾需忿,同時可以提供多版本并發(fā)控制下的讀(MVCC)诅炉,也即非鎖定讀

內(nèi)容: 邏輯格式的日志,在執(zhí)行undo的時候屋厘,僅僅是將數(shù)據(jù)從邏輯上恢復(fù)至事務(wù)之前的狀態(tài)涕烧,而不是從物理頁面上操作實現(xiàn)的,這一點是不同于redo log的汗洒。

什么時候產(chǎn)生: 事務(wù)開始之前议纯,將當(dāng)前是的版本生成undo log,undo 也會產(chǎn)生 redo 來保證undo log的可靠性

什么時候釋放: 當(dāng)事務(wù)提交之后溢谤,undo log并不能立馬被刪除瞻凤,而是放入待清理的鏈表憨攒,由purge線程判斷是否由其他事務(wù)在使用undo段中表的上一個事務(wù)之前的版本信息,決定是否可以清理undo log的日志空間

2阀参、重做日志(redo log)

作用: 確保事務(wù)的持久性肝集。 防止在發(fā)生故障的時間點,尚有臟頁未寫入磁盤蛛壳,在重啟mysql服務(wù)的時候杏瞻,根據(jù)redo log進(jìn)行重做,從而達(dá)到事務(wù)的持久性這一特性衙荐。

內(nèi)容: 物理格式的日志捞挥,記錄的是事務(wù)開始執(zhí)行修改后的數(shù)據(jù),其redo log是順序?qū)懭雛edo log file的物理文件中去的忧吟。

什么時候產(chǎn)生: 事務(wù)開始之后就產(chǎn)生redo log砌函,redo log的落盤并不是隨著事務(wù)的提交才寫入的,而是在事務(wù)的執(zhí)行過程中溜族,便開始寫入redo log文件中讹俊。

什么時候釋放: 當(dāng)對應(yīng)事務(wù)的臟頁寫入到磁盤之后,redo log的使命也就完成了煌抒,重做日志占用的空間就可以重用(被覆蓋)劣像。

參考資料:https://blog.csdn.net/u010002184/article/details/88526708

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市摧玫,隨后出現(xiàn)的幾起案子耳奕,更是在濱河造成了極大的恐慌,老刑警劉巖诬像,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屋群,死亡現(xiàn)場離奇詭異,居然都是意外死亡坏挠,警方通過查閱死者的電腦和手機(jī)芍躏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來降狠,“玉大人对竣,你說我怎么就攤上這事“衽洌” “怎么了否纬?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蛋褥。 經(jīng)常有香客問我临燃,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任膜廊,我火速辦了婚禮乏沸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘爪瓜。我一直安慰自己蹬跃,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布铆铆。 她就那樣靜靜地躺著炬转,像睡著了一般。 火紅的嫁衣襯著肌膚如雪算灸。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天驻啤,我揣著相機(jī)與錄音菲驴,去河邊找鬼。 笑死骑冗,一個胖子當(dāng)著我的面吹牛赊瞬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播贼涩,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼巧涧,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了遥倦?” 一聲冷哼從身側(cè)響起谤绳,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎袒哥,沒想到半個月后缩筛,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡堡称,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年瞎抛,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片却紧。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡桐臊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出晓殊,到底是詐尸還是另有隱情断凶,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布巫俺,位于F島的核電站懒浮,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜砚著,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一次伶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧稽穆,春花似錦冠王、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至餐胀,卻和暖如春哟楷,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背否灾。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工卖擅, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人墨技。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓惩阶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親扣汪。 傳聞我的和親對象是個殘疾皇子断楷,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,507評論 2 359

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

  • 我們都知道事務(wù)有4種特性:原子性、一致性崭别、隔離性和持久性冬筒,在事務(wù)中的操作,要么全部執(zhí)行茅主,要么全部不做账千,這就是事務(wù)的...
    pjmike閱讀 31,855評論 5 36
  • 事務(wù)可以用來維護(hù)數(shù)據(jù)庫的完整性匀奏,保證成批的 SQL 語句要么全部執(zhí)行,要么全部不執(zhí)行学搜。MySQL 中只有使用了 I...
    伊凡的一天閱讀 2,373評論 3 22
  • 寫在前面 本文是對于網(wǎng)上各個對redo和undo log日志解析的總結(jié)娃善,參考文章列表在最后。 事務(wù)的4大特性:原子...
    呂信閱讀 8,398評論 0 11
  • https://www.runoob.com/mysql/mysql-transaction.html[https...
    王王王王王景閱讀 21,158評論 4 23
  • 昨天我的游戲手柄到了瑞佩。為啥買它聚磺,原因是我想更好地“吃雞”。為啥“吃雞”炬丸,因為怕OUT瘫寝。 短短一行字蜒蕾,我圈出幾個重點...
    楠得書寫閱讀 944評論 0 50