欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

mysql事務(wù)和隔離級(jí)別底層原理淺析

 更新時(shí)間:2021年12月06日 16:15:48   作者:三分魔系  
大家好,本篇文章主要講的是mysql事務(wù)和隔離級(jí)別底層原理淺析,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下

前言

首先回顧一下什么是事務(wù),事務(wù)是數(shù)據(jù)庫(kù)操作的最小工作單元,是作為單個(gè)邏輯工作單元執(zhí)行的一系列操作;這些操作作為一個(gè)整體一起向系統(tǒng)提交,要么都執(zhí)行、要么都不執(zhí)行;事務(wù)是一組不可再分割的操作集合(工作邏輯單元)。

事務(wù)的特性:

原子性(Atomicity):原子性是指事務(wù)包含的所有操作要么全部成功,要么全部失敗回滾。一致性(Consistency):事務(wù)執(zhí)行的結(jié)果必須是使數(shù)據(jù)庫(kù)從一個(gè)一致性狀態(tài)變到另一個(gè)一致性狀態(tài)。隔離性(Isolation):一個(gè)事務(wù)的執(zhí)行不能其它事務(wù)干擾。即一個(gè)事務(wù)內(nèi)部的操作及使用的數(shù)據(jù)對(duì)其它并發(fā)事務(wù)是隔離的,并發(fā)執(zhí)行的各個(gè)事務(wù)之間不能互相干擾。持久性(Durability):指一個(gè)事務(wù)一旦提交,它對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)的改變就應(yīng)該是永久性的。接下來的其它操作或故障不應(yīng)該對(duì)其執(zhí)行結(jié)果有任何影響。

一、事務(wù)底層原理淺析

原子性:

實(shí)現(xiàn)原理:undo log

undo log也被成為回滾日志,它是事務(wù)實(shí)現(xiàn)原子性和隔離性的基礎(chǔ)。當(dāng)事務(wù)對(duì)數(shù)據(jù)庫(kù)進(jìn)行修改時(shí),InnoDB會(huì)生成對(duì)應(yīng)的undo log;如果事務(wù)執(zhí)行失敗或調(diào)用了rollback,導(dǎo)致事務(wù)需要回滾,便可以利用undo log中的信息將數(shù)據(jù)回滾到修改之前的樣子。

undo log屬于邏輯日志,它記錄的是sql執(zhí)行相關(guān)的信息。當(dāng)發(fā)生回滾時(shí),InnoDB會(huì)根據(jù)undo log的內(nèi)容做與之前相反的工作:對(duì)于每個(gè)insert,回滾時(shí)會(huì)執(zhí)行delete;對(duì)于每個(gè)delete,回滾時(shí)會(huì)執(zhí)行insert;對(duì)于每個(gè)update,回滾時(shí)會(huì)執(zhí)行一個(gè)相反的update,把數(shù)據(jù)改回去。

undo 存放在數(shù)據(jù)庫(kù)內(nèi)部的一個(gè)特殊段segment中,這個(gè)段稱為undo段。undo段位于共享表空間中。undo是邏輯日志,因此只是將數(shù)據(jù)庫(kù)邏輯的恢復(fù)到原來的樣子。undo log會(huì)產(chǎn)生redo log,也就是undo log的產(chǎn)生會(huì)伴隨著redo log的產(chǎn)生,因?yàn)閡ndo log也需要持久性的保護(hù)。

undo log執(zhí)行記錄是在每次寫入數(shù)據(jù)或者修改數(shù)據(jù)之前。

在這里插入圖片描述

undo log使用原理:數(shù)據(jù)庫(kù)表每行數(shù)據(jù)會(huì)多兩列DATA_TRX_ID和DATA_ROLL_PTR(可能還有一列DB_ROW_ID,當(dāng)沒有默認(rèn)主鍵時(shí)會(huì)自動(dòng)加上這列)。DATA_TRX_ID表示當(dāng)前數(shù)據(jù)的事務(wù)版本, DATA_ROLL_PTR 則指向剛剛拷貝到

undo log 鏈中的舊版本記錄,undo log是個(gè)鏈表,如果多個(gè)事務(wù)多次修改會(huì)繼續(xù)生成undo log并通過DATA_ROLL_PTR建立指向關(guān)系。用圖說明一下:

在這里插入圖片描述

這樣,一旦事務(wù)發(fā)生回滾,mysql便可以借助undo log實(shí)現(xiàn)數(shù)據(jù)還原,從而保證未提交事務(wù)的原子性。

持久性

實(shí)現(xiàn)原理:redo log

由于InnoDB作為MySQL的存儲(chǔ)引擎,數(shù)據(jù)是存放在磁盤中的,為了減少磁盤IO,提高讀取性能InnoDB提供了緩存池——Buffer Pool。Buffer Pool中包含了磁盤中部分?jǐn)?shù)據(jù)頁(yè)的映射,作為訪問數(shù)據(jù)庫(kù)的緩沖:當(dāng)從數(shù)據(jù)庫(kù)讀取數(shù)據(jù)時(shí),會(huì)首先從Buffer Pool中讀取,如果Buffer Pool中沒有,則從磁盤讀取后放入Buffer Pool;當(dāng)向數(shù)據(jù)庫(kù)寫入數(shù)據(jù)時(shí),會(huì)首先寫入Buffer Pool,Buffer Pool中修改的數(shù)據(jù)會(huì)定期刷新到磁盤中(這一過程稱為刷臟)。

不過這也帶來了一個(gè)新的問題,如果MySQL宕機(jī),而此時(shí)Buffer Pool中修改的數(shù)據(jù)還沒有刷新到磁盤,就會(huì)導(dǎo)致數(shù)據(jù)的丟失,事務(wù)的持久性無法保證。

為了解決這個(gè)問題就引入了redo log,也叫重做日志。當(dāng)數(shù)據(jù)修改時(shí),除了修改Buffer Pool中的數(shù)據(jù),還會(huì)在redo log記錄這次操作;當(dāng)事務(wù)提交時(shí),會(huì)調(diào)用fsync接口對(duì)redo log進(jìn)行刷盤。如果MySQL宕機(jī),重啟時(shí)可以讀取redo log中的數(shù)據(jù),對(duì)數(shù)據(jù)庫(kù)進(jìn)行恢復(fù)。redo log采用的是WAL(Write-ahead logging,預(yù)寫式日志),所有修改在提交前先寫入日志,保證了數(shù)據(jù)不會(huì)因MySQL宕機(jī)而丟失,從而滿足了持久性要求。redo log是針對(duì)物理頁(yè)的,并發(fā)執(zhí)行,最后一次提交會(huì)覆蓋未提交的數(shù)據(jù)。本地redo log:

在這里插入圖片描述

redo log也是有緩沖區(qū)的——redo log buffer,當(dāng)事務(wù)提交之后會(huì)把所有修改信息都刷新到磁盤上。用戶也可以通過控制通過變量 innodb_flush_log_at_trx_commit 的值來修改刷新策略(默認(rèn)1),如設(shè)置值為2,控制成每秒刷新,這樣事務(wù)提

交就會(huì)較快,不過可能面臨日志丟失的風(fēng)險(xiǎn)。

redo log是在SQL語(yǔ)句執(zhí)行之后記錄的。

在這里插入圖片描述

既然redo log也需要存儲(chǔ),也涉及磁盤IO為啥還用它?

(1)redo log 的存儲(chǔ)是順序存儲(chǔ),而緩存同步是隨機(jī)操作。

(2)緩存同步是以數(shù)據(jù)頁(yè)為單位的,每次傳輸?shù)臄?shù)據(jù)大小大于redo log。

redo log是用來恢復(fù)數(shù)據(jù)的 用于保障已提交事務(wù)的持久化特性。

隔離性:

原理:
(1). 寫操作對(duì)寫操作的影響:鎖機(jī)制保證隔離性
(2). 寫操作對(duì)讀操作的影響:MVCC保證隔離性

一致性:

一致性比較特殊,前面的原子性、持久性和隔離性都是為一致性服務(wù)的,除此之外,一致性還依賴于數(shù)據(jù)庫(kù)自我提供的保障,如SQL語(yǔ)法驗(yàn)證,列類型插入數(shù)據(jù)類型驗(yàn)證,同時(shí)也依賴于應(yīng)用層的保障,如轉(zhuǎn)賬操作,需要開發(fā)人員進(jìn)行轉(zhuǎn)賬者的余額扣除和接受者的余額增加,如果應(yīng)用層面出現(xiàn)問題,那么一致性也是無法保障的。

二、隔離級(jí)別底層原理淺析

在事務(wù)底層原理淺析中,關(guān)于隔離性的原理沒有過多深入,在此我們簡(jiǎn)單介紹一下。

首先介紹一下mysql的MVCC(MultiVersion Concurrency Control) 叫做多版本并發(fā)控制。它是依賴undo logread view實(shí)現(xiàn)的。undo log上文已經(jīng)介紹過了,不再贅述,read view(可讀視圖),這與我們平時(shí)理解的數(shù)據(jù)庫(kù)視圖不同,它是用來判斷當(dāng)前數(shù)據(jù)版本的可見性的。

readview主要有四個(gè)屬性:

(1). m_ids 代表生成ReadView時(shí),當(dāng)前所有活躍的事務(wù)ID,活躍的意思就是事務(wù)開啟了還沒提交;

(2). min_trx_id 表示當(dāng)前活躍的mIds中最小的事務(wù)ID;

(3). max_trx_id 表示生成ReadView時(shí),最大的事務(wù)ID,它不一定是mIds中最大的事務(wù)ID;

(4).creator_trx_id表示創(chuàng)建該ReadView的事務(wù)ID。

在這里插入圖片描述

注意:每開啟一個(gè)事務(wù),事務(wù)ID就自增一次,事務(wù)ID可以看做一個(gè)全局自增變量。最先開啟的事務(wù)不一定比后開啟的事務(wù)先提交,比如長(zhǎng)連接,所以不要認(rèn)為max_trx_id就是mIds中的最大值。

read view是怎樣借助上面四個(gè)屬性,判斷事務(wù)應(yīng)該讀取那個(gè)版本的數(shù)據(jù)呢?

如果被訪問版本的 data_trx_id 小于 m_ids 中的最小值,說明生成該版本的事務(wù)在 ReadView 生成前就已經(jīng)提交了,那么該版本可以被當(dāng)前事務(wù)訪問。

如果被訪問版本的 data_trx_id 屬性值與ReadView中的creator_trx_id值相同,意味著當(dāng)前事務(wù)在訪問它自己修改過的記錄,所以該版本可以被當(dāng)前事務(wù)訪問。

如果被訪問版本的 data_trx_id 屬性值大于ReadView中的max_trx_id值,表明生成該版本的事務(wù)在當(dāng)前事務(wù)生成ReadView后才開啟,所以該版本不可以被當(dāng)前事務(wù)訪問。

如果被訪問版本的 data_trx_id 屬性值在ReadView的min_trx_id和max_trx_id之間,那就需要判斷一下trx_id屬性值是不是在m_ids列表中,如果在,說明創(chuàng)建ReadView時(shí)生成該版本的事務(wù)還是活躍的,該版本不可以被訪問;如果不在,說明創(chuàng)建ReadView時(shí)生成該版本的事務(wù)已經(jīng)被提交,該版本可以被訪問。

當(dāng)一個(gè)事務(wù)要讀取一行數(shù)據(jù),首先用上面規(guī)則判斷數(shù)據(jù)的最新版本也就是那行記錄,如果發(fā)現(xiàn)可以訪問就直接讀取了,如果發(fā)現(xiàn)不能訪問,就通過DATA_ROLL_PTR指針找到undo log,遞歸往下去找每個(gè)版本,知道讀取到自己可以讀取的版本為止,如果讀取不到就返回空。

所以訪問數(shù)據(jù)時(shí),數(shù)據(jù)庫(kù)里面會(huì)創(chuàng)建一個(gè)視圖,訪問的時(shí)候以視圖的邏輯結(jié)果為準(zhǔn):

READ UNCOMMITED (未提交讀):此隔離級(jí)別下直接返回記錄上的最新值,沒有視圖概念。因?yàn)樽x不會(huì)加任何鎖,所以寫操作在讀的過程中修改數(shù)據(jù),所以會(huì)造成臟讀。好處是可以提升并發(fā)處理性能,能做到讀寫并行。

READ COMMITED (提交讀):此隔離級(jí)別下,這個(gè)視圖是在每個(gè) SQL語(yǔ)句開始執(zhí)行的時(shí)候創(chuàng)建的。InnoDB在 READ COMMITTED,使用排它鎖,讀取數(shù)據(jù)不加鎖而是使用了MVCC機(jī)制?;蛘邠Q句話說他采用了讀寫分離機(jī)制。

REPEATABLE READ (可重復(fù)讀):此隔離級(jí)別下,這個(gè)視圖是在事務(wù)啟動(dòng)時(shí)創(chuàng)建的,整個(gè)事務(wù)存在期間都用這個(gè)視圖。

SERIALIZABLE (串行化):此隔離級(jí)別下直接用加鎖的方式來避免并行訪問。

寫到這里,你也許發(fā)現(xiàn)了,MySQL中借助MVCC在可重復(fù)讀隔離級(jí)別下其實(shí)也杜絕了幻讀的發(fā)生。

三、總結(jié)

原子性:使用 undo log (回滾日志)實(shí)現(xiàn)回滾,從而保障未提交事務(wù)的原子性;

持久性:使用 redo log(重做日志)實(shí)現(xiàn)數(shù)據(jù)恢復(fù),從而保障已提交事務(wù)的持久性;

隔離性:使用鎖以及MVCC思想實(shí)現(xiàn)讀寫分離,讀讀并行,讀寫并行;

一致性:通過回滾、恢復(fù)和在并發(fā)環(huán)境下的隔離做到一致性。

到此這篇關(guān)于mysql事務(wù)和隔離級(jí)別底層原理淺析的文章就介紹到這了,更多相關(guān)mysql事務(wù)和隔離級(jí)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論