簡(jiǎn)述mysql事務(wù)特性背后的技術(shù)實(shí)現(xiàn)

一直在使用mysql, 但是對(duì)于mysql 的一些核心原理一直有些模糊。出問(wèn)題總是想著公司有專職的DBA, 專業(yè)的事情交給專業(yè)的人來(lái)做嘛,所以一直沒(méi)有研究(其實(shí)主要是懶)。趁著假期,閑著也是閑著,就想簡(jiǎn)單了解一下。人嘛,總是嫌麻煩,總想找些現(xiàn)成的文章或者課程。找了極客時(shí)間的兩套mysql相關(guān)課程 (基礎(chǔ))SQL必知必會(huì)(進(jìn)階)MySQL實(shí)戰(zhàn)45講,看了個(gè)大概,只總結(jié)出來(lái)mysql最核心的應(yīng)該是事務(wù)跟索引。

但是看完之后,思維陷入了混亂,每一節(jié)都是一些知識(shí)點(diǎn)的堆積,沒(méi)有形成體系,自己想不明白彼此之間到底是什么關(guān)系。自己又找了拉鉤上的《高性能mysql實(shí)戰(zhàn)》,有個(gè)大概了。我整理了兩個(gè)核心問(wèn)題 :1、“事務(wù)的特性是如何實(shí)現(xiàn)的?”;2、“事務(wù)四種隔離級(jí)別是怎么結(jié)合鎖來(lái)解決并發(fā)產(chǎn)生的三種經(jīng)典問(wèn)題的?” 。

本文是mysql 事務(wù)的第一部分-四個(gè)特性及實(shí)現(xiàn)。自己不是專職的DBA,理解難免有偏差,只是簡(jiǎn)單地總結(jié)一下。希望對(duì)你有所幫助,如果有紕漏,也請(qǐng)留言指出,感謝~
文章主要內(nèi)容如下:

  • 事務(wù)的定義
  • 事務(wù)的四個(gè)特性以及背后的技術(shù)原理

1 事務(wù)是什么

做工程實(shí)現(xiàn),想必大家都接觸過(guò)事務(wù)。事務(wù),一組邏輯執(zhí)行單元,要么全部做完,要不都不做,不會(huì)處于一個(gè)中間狀態(tài)。事務(wù)是為了保證DB操作正確性跟完整性的保障。

2 事務(wù)的四個(gè)特性

按照上一小節(jié)的描述,更多的像是在描述事務(wù)原子性這一特性。其實(shí)事務(wù)并不僅僅是只有原子性這一個(gè)特性。是由四部分組成 ACID。下面我們介紹一下這部分:

2.1 原子性(Atomicity)

原子性:事務(wù)的所有操作,要么全部完成,要么全部不完成,不會(huì)結(jié)束在某個(gè)中間環(huán)節(jié)。
這個(gè)是最基本的要求。

2.2 一致性(Consistency)

一致性:事務(wù)完成之后,事務(wù)所做的修改進(jìn)行持久化保存,不會(huì)丟失。

一致性更像是其他三個(gè)特性綜合之后的結(jié)果。需要依賴于它們。一致性可以從兩個(gè)角度思考:一個(gè)是約束的一致性(比如主鍵、外鍵約束),另一種是業(yè)務(wù)邏輯上的一致性。

2.3 隔離性(Isolation)

隔離性:當(dāng)多個(gè)事務(wù)并發(fā)訪問(wèn)數(shù)據(jù)庫(kù)中的同一數(shù)據(jù)時(shí),所表現(xiàn)出來(lái)的相互關(guān)系。

隔離性關(guān)系到多個(gè)事務(wù)并發(fā)操作時(shí)數(shù)據(jù)的準(zhǔn)確性。innodb有四個(gè)常見(jiàn)的隔離性,這些隔離性會(huì)借助于鎖機(jī)制 解決一些并發(fā)常見(jiàn)的問(wèn)題。當(dāng)然,因?yàn)楦綦x性強(qiáng)弱的不同,有些問(wèn)題在某些場(chǎng)景下是解決不了的。下一節(jié),我們將重點(diǎn)講解這個(gè)問(wèn)題。

2.4 持久性(Durability)

持久性:事務(wù)開(kāi)始之前和事務(wù)結(jié)束之后,數(shù)據(jù)庫(kù)的完整性限制未被破壞。

這兒主要是指持久化的問(wèn)題。數(shù)據(jù)寫入之后,要保證不會(huì)丟失,在系統(tǒng)崩潰之后,也能恢復(fù)。

3 四個(gè)特性背后是怎么實(shí)現(xiàn)的?

大多數(shù)的文章,講完事務(wù)的四個(gè)特性就結(jié)束了。如果只是停留在這個(gè)層面,我們就沒(méi)有寫這篇文章的必要了。在這部分,我們會(huì)講解一下四個(gè)特性是如何實(shí)現(xiàn)的?在講解特性實(shí)現(xiàn)原理之前,我們先講一下用到的幾個(gè)知識(shí)點(diǎn)。

3.1 redo、undo與binlog

3.1.1 redo

redo, 重做日志,保證了事務(wù)的原子性與持久性。通常是物理日志,用于恢復(fù)事務(wù)修改的頁(yè)操作。

redo 包括兩部分:

  • 1 內(nèi)存中的重做日志緩沖,易失,一般在事務(wù)開(kāi)始時(shí),就要寫入這部分
  • 2 第二部分是重做日志,這個(gè)是要刷如磁盤的。一般在事務(wù)提交時(shí)會(huì)刷如磁盤。有些場(chǎng)景,也可以設(shè)置沒(méi)用每次事務(wù)提交就刷,而是交給master thread 定期刷盤,但是這樣如果在這期間,宕機(jī)了,則沒(méi)有刷盤的數(shù)據(jù)就要丟失了。

redo 日志里面存儲(chǔ)的是操作指令,每個(gè)指令根據(jù)操作類型的不同,存儲(chǔ)格式也是不同的。

redo 在內(nèi)存中,結(jié)合了checkpoint 以及LSN(log sequence number) 來(lái)保證刷入磁盤的數(shù)據(jù)不丟。checkpoint記錄了刷磁盤刷到哪兒了,LSN記錄了當(dāng)前內(nèi)存中的日志編號(hào)。二者之間的內(nèi)容就是沒(méi)有刷新到磁盤的日志。

3.1.2 undo

undo保證了事務(wù)的一致性。undo 并不是物理日志,而是邏輯上的日志,有一個(gè)專門的內(nèi)存字段存儲(chǔ)undo 日志。
undo 主要有兩個(gè)作用:1是回滾操作,將數(shù)據(jù)庫(kù)邏輯地恢復(fù)到原來(lái)的樣子,但是已經(jīng)分配的頁(yè)、或者數(shù)據(jù)結(jié)果可能回滾不了了; 2 是MVCC(多版本并發(fā)控制),實(shí)現(xiàn)并發(fā)控制的一種很通用的機(jī)制,在下面的一節(jié)中,我們會(huì)講到。

當(dāng)事務(wù)提交的時(shí)候,innodb不會(huì)立即刪除undo log,因?yàn)楹罄m(xù)還可能會(huì)用到undo log,如隔離級(jí)別為repeatable read時(shí),事務(wù)讀取的都是開(kāi)啟事務(wù)時(shí)的最新提交行版本,只要該事務(wù)不結(jié)束,該行版本就不能刪除,即undo log不能刪除。

但是在事務(wù)提交的時(shí)候,會(huì)將該事務(wù)對(duì)應(yīng)的undo log放入到刪除列表中,未來(lái)通過(guò)purge來(lái)刪除。并且提交事務(wù)時(shí),還會(huì)判斷undo log分配的頁(yè)是否可以重用,如果可以重用,則會(huì)分配給后面來(lái)的事務(wù),避免為每個(gè)獨(dú)立的事務(wù)分配獨(dú)立的undo log頁(yè)而浪費(fèi)存儲(chǔ)空間和性能。

3.1.3 binlog

binlog基本定義:二進(jìn)制日志,也成為二進(jìn)制日志,記錄對(duì)數(shù)據(jù)發(fā)生或潛在發(fā)生更改的SQL語(yǔ)句,并以二進(jìn)制的形式保存在磁盤中;

作用:Mysql的作用類似于ORACLE的歸檔日志,可以用來(lái)查看數(shù)據(jù)庫(kù)的變更歷史(具體的時(shí)間點(diǎn)所有的SQL操作)、數(shù)據(jù)庫(kù)增量備份和恢復(fù)(增量備份和基于時(shí)間點(diǎn)的恢復(fù))、Mysql的復(fù)制(主主數(shù)據(jù)庫(kù)的復(fù)制、主從數(shù)據(jù)庫(kù)的復(fù)制)

3.1.4 更新操作中 redolog 與 binlog的順序
redolog與binlog的順序.png

3.2 WAL (write ahead logging) 又稱 ARIES三原則

ARIES三原則,是指write ahead logging。

1 先寫日之后寫磁盤,日志成功寫入后就不會(huì)丟失,后續(xù)由checkpoint機(jī)制來(lái)保證磁盤物理文件與redo日志達(dá)到一致性。
2 利用Redo 記錄變更后的數(shù)據(jù),即redo記錄事務(wù)數(shù)據(jù)變更后的值
3 利用Undo 記錄變更前的數(shù)據(jù),用于回滾和其他事務(wù)多版本讀。

3.3 特性的實(shí)現(xiàn)

3.3.1 各特性間的關(guān)系

在講解具體實(shí)現(xiàn)之前,我們先來(lái)張圖,參考自 《高性能mysql實(shí)戰(zhàn)》


事務(wù)四特性.png
3.3.2 原子性的實(shí)現(xiàn)

每一個(gè)寫事務(wù),都會(huì)修改 Buffer Pool,從而產(chǎn)生相應(yīng)的 Redo 日志,這些日志信息會(huì)被記錄到 ib_logfiles 文件中。因?yàn)?Redo 日志是遵循 Write Ahead Log 的方式寫的,所以事務(wù)是順序被記錄的。
任何 Buffer Pool 中的頁(yè)被刷到磁盤之前,都會(huì)先寫入到日志文件中。

回滾(undo日志)
要保證原子性,就必須在異常發(fā)生時(shí),對(duì)已經(jīng)執(zhí)行的操作進(jìn)行回滾,此時(shí)就用到了undo 日志。

未刷盤數(shù)據(jù)提交(redo日志)
除了回滾之外,還有一種場(chǎng)景是事務(wù)提交了,日志寫入到buffer pool 了,但是buffer pool的臟頁(yè) 并沒(méi)有刷盤,那此時(shí)怎么恢復(fù)呢?就需要用到redo日志恢復(fù)數(shù)據(jù)。

綜合上述兩種case,其實(shí)原子性的保證就是用到了WAL的原則。

3.3.3 持久性的實(shí)現(xiàn)

持久性是表示一個(gè)事務(wù)一旦提交,它對(duì)數(shù)據(jù)的改變就是永久的。通過(guò)原子性可以保證的一旦事務(wù)提交,即使遇到宕機(jī),也可以從邏輯上將數(shù)據(jù)找回來(lái),再次寫入到物理存儲(chǔ)空間。
因?yàn)閞edo日志是有限的,那么宕機(jī)之后,redo日志之前的數(shù)據(jù)怎么恢復(fù)呢,這就結(jié)合binlog日志。

3.3.4 隔離性的實(shí)現(xiàn)

innodb隔離性有四種,我們簡(jiǎn)單看一下四種隔離級(jí)別都是怎么實(shí)現(xiàn)的。下一篇文章中會(huì)詳細(xì)介紹。

1、讀未提交:沒(méi)做任何控制。能夠讀到一個(gè)事務(wù)中的中間狀態(tài),是違背ACID的,所以在MySQL中基本不用。
2、讀已提交(RC):通過(guò)對(duì)數(shù)據(jù)加了寫鎖,在寫的過(guò)程中數(shù)據(jù)是不能被其他事務(wù)看到的。但是會(huì)存在不可重復(fù)讀的問(wèn)題。
3、可重復(fù)讀(RR):通過(guò)增加間隙鎖,解決了不可重讀的問(wèn)題,但是并不能對(duì)未存在的數(shù)據(jù)進(jìn)行加鎖操作,所以會(huì)存在幻讀的問(wèn)題。
4、可串行化:通過(guò)加鎖,所有的操作都是單版本,串行化的。

3.3.5 一致性的實(shí)現(xiàn)

一致性可以歸納為完整性。而數(shù)據(jù)的完整性是通過(guò)上面三個(gè)特性來(lái)保證的,包括原子性、隔離性、持久性,而這三個(gè)特性又是通過(guò)Redo/Undo/binlog 來(lái)保證的。

4 總結(jié)

本文根據(jù)我自己的學(xué)習(xí)過(guò)程,簡(jiǎn)單整理了事務(wù),事務(wù)特性,以及事務(wù)特性背后的技術(shù)原理。

5 參考文獻(xiàn)

淺入淺出mysql https://draveness.me/mysql-innodb
淺入深出MySQL中事務(wù)的實(shí)現(xiàn) https://draveness.me/mysql-transaction

詳細(xì)分析MySQL事務(wù)日志(redo log和undo log) https://www.cnblogs.com/f-ck-need-u/archive/2018/05/08/9010872.html#auto_id_16
拉勾網(wǎng)的《高性能mysql實(shí)戰(zhàn)》課程 https://kaiwu.lagou.com/course/courseInfo.htm?courseId=5#/content?courseId=5

6 其他

本文是mysql學(xué)習(xí)的第一篇-事務(wù)及其特性,希望對(duì)你有所幫助~
如果有疑問(wèn),可以直接留言,也可以關(guān)注公眾號(hào) “鏈人成長(zhǎng)chainerup” 提問(wèn)留言,或者加入知識(shí)星球“鏈人成長(zhǎng)” 與我深度鏈接~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 我們都知道事務(wù)有4種特性:原子性、一致性、隔離性和持久性,在事務(wù)中的操作,要么全部執(zhí)行,要么全部不做,這就是事務(wù)的...
    pjmike閱讀 32,340評(píng)論 5 36
  • 一、事務(wù)概述 我們可以將事務(wù)理解為一組sql語(yǔ)句的集合。事務(wù)可以只包含一條sql,也可以包含多條sql,事務(wù)中所有...
    國(guó)球乒乓閱讀 510評(píng)論 0 0
  • 7.1 認(rèn)識(shí)事務(wù)7.1.1 概述事務(wù)可由一條非常簡(jiǎn)單的SQL語(yǔ)句組成,也可以由一組復(fù)雜的SQL語(yǔ)句組成。事務(wù)是訪問(wèn)...
    正在加載更多閱讀 555評(píng)論 0 0
  • 還剩17000詞要翻譯。 看《人生不設(shè)限》的時(shí)候,突然看到作者說(shuō)上帝讓我們自愛(ài),而我之前覺(jué)得自己可能潛意識(shí)有點(diǎn)自卑...
    09f70d5e7741閱讀 217評(píng)論 0 1
  • 越來(lái)越能坐,就仿佛體驗(yàn)到了那種久坐辦公室的感覺(jué),我這些天經(jīng)常一坐一下午,我厭倦寢室這個(gè)毀人的地方,想起了七堇年一本...
    賈的假不了閱讀 60評(píng)論 0 0

友情鏈接更多精彩內(nèi)容