欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

MySQL中的redo及undo簡單分析-創(chuàng)新互聯(lián)

本文主要給大家介紹MySQL中的redo及undo簡單分析,希望可以給大家補(bǔ)充和更新些知識,如有其它問題需要了解的可以持續(xù)在創(chuàng)新互聯(lián)建站行業(yè)資訊里面關(guān)注我的更新文章的。                                                 

成都創(chuàng)新互聯(lián)公司服務(wù)項(xiàng)目包括浪卡子網(wǎng)站建設(shè)、浪卡子網(wǎng)站制作、浪卡子網(wǎng)頁制作以及浪卡子網(wǎng)絡(luò)營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,浪卡子網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到浪卡子省份的部分城市,未來相信會繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

我們都知道事務(wù)有4種特性:原子性、一致性、隔離性和持久性,在事務(wù)中的操作,要么全部執(zhí)行,要么全部不做,這就是事務(wù)的目的。事務(wù)的隔離性由鎖機(jī)制實(shí)現(xiàn),原子性、一致性和持久性由事務(wù)的redo 日志和undo 日志來保證。所以本篇文章將討論關(guān)于事務(wù)中的redo和undo的幾個問題:

  • redo 日志與undo日志分別是什么?

  • redo 如何保證事務(wù)的持久性?

  • undo log 是否是redo log的逆過程?

  • Redo 的類型

重做日志(redo log)用來保證事務(wù)的持久性,即事務(wù)ACID中的D。實(shí)際上它可以分為以下兩種類型:

  • 物理Redo日志

  • 邏輯Redo日志

在InnoDB存儲引擎中,大部分情況下 Redo是物理日志,記錄的是數(shù)據(jù)頁的物理變化。而邏輯Redo日志,不是記錄頁面的實(shí)際修改,而是記錄修改頁面的一類操作,比如新建數(shù)據(jù)頁時,需要記錄邏輯日志。關(guān)于邏輯Redo日志涉及更加底層的內(nèi)容,這里我們只需要記住絕大數(shù)情況下,Redo是物理日志即可,DML對頁的修改操作,均需要記錄Redo.

Redo 的作用

Redo log的主要作用是用于數(shù)據(jù)庫的崩潰恢復(fù)

Redo 的組成

Redo log可以簡單分為以下兩個部分:

  • 一是內(nèi)存中重做日志緩沖 (redo log buffer),是易失的,在內(nèi)存中

  • 二是重做日志文件 (redo log file),是持久的,保存在磁盤中

什么時候?qū)慠edo?

上面那張圖簡單地體現(xiàn)了Redo的寫入流程,這里再細(xì)說下寫入Redo的時機(jī):

  • 在數(shù)據(jù)頁修改完成之后,在臟頁刷出磁盤之前,寫入redo日志。注意的是先修改數(shù)據(jù),后寫日志

  • redo日志比數(shù)據(jù)頁先寫回磁盤

  • 聚集索引、二級索引、undo頁面的修改,均需要記錄Redo日志。

Redo的整體流程

下面以一個更新事務(wù)為例,宏觀上把握redo log 流轉(zhuǎn)過程,如下圖所示:

MySQL中的redo及undo簡單分析

  • 第一步:先將原始數(shù)據(jù)從磁盤中讀入內(nèi)存中來,修改數(shù)據(jù)的內(nèi)存拷貝

  • 第二步:生成一條重做日志并寫入redo log buffer,記錄的是數(shù)據(jù)被修改后的值

  • 第三步:當(dāng)事務(wù)commit時,將redo log buffer中的內(nèi)容刷新到 redo log file,對 redo log file采用追加寫的方式

  • 第四步:定期將內(nèi)存中修改的數(shù)據(jù)刷新到磁盤中

redo如何保證 事務(wù)的持久性?

InnoDB是事務(wù)的存儲引擎,其通過Force Log at Commit 機(jī)制實(shí)現(xiàn)事務(wù)的持久性,即當(dāng)事務(wù)提交時,先將 redo log buffer 寫入到 redo log file 進(jìn)行持久化,待事務(wù)的commit操作完成時才算完成。這種做法也被稱為Write-Ahead Log(預(yù)先日志持久化),在持久化一個數(shù)據(jù)頁之前,先將內(nèi)存中相應(yīng)的日志頁持久化。

為了保證每次日志都寫入redo log file,在每次將redo buffer寫入redo log file之后,默認(rèn)情況下,InnoDB存儲引擎都需要調(diào)用一次fsync操作,因?yàn)橹刈鋈罩敬蜷_并沒有 O_DIRECT選項(xiàng),所以重做日志先寫入到文件系統(tǒng)緩存。為了確保重做日志寫入到磁盤,必須進(jìn)行一次 fsync操作。fsync是一種系統(tǒng)調(diào)用操作,其fsync的效率取決于磁盤的性能,因此磁盤的性能也影響了事務(wù)提交的性能,也就是數(shù)據(jù)庫的性能。
(O_DIRECT選項(xiàng)是在Linux系統(tǒng)中的選項(xiàng),使用該選項(xiàng)后,對文件進(jìn)行直接IO操作,不經(jīng)過文件系統(tǒng)緩存,直接寫入磁盤)

上面提到的Force Log at Commit機(jī)制就是靠InnoDB存儲引擎提供的參數(shù)innodb_flush_log_at_trx_commit來控制的,該參數(shù)可以控制 redo log刷新到磁盤的策略,設(shè)置該參數(shù)值也可以允許用戶設(shè)置非持久性的情況發(fā)生,具體如下:

  • 當(dāng)設(shè)置參數(shù)為1時,(默認(rèn)為1),表示事務(wù)提交時必須調(diào)用一次fsync操作,最安全的配置,保障持久性

  • 當(dāng)設(shè)置參數(shù)為2時,則在事務(wù)提交時只做write操作,只保證將redo log buffer寫到系統(tǒng)的頁面緩存中,不進(jìn)行fsync操作,因此如果MySQL數(shù)據(jù)庫宕機(jī)時 不會丟失事務(wù),但操作系統(tǒng)宕機(jī)則可能丟失事務(wù)

  • 當(dāng)設(shè)置參數(shù)為0時,表示事務(wù)提交時不進(jìn)行寫入redo log操作,這個操作僅在master thread 中完成,而在master thread中每1秒進(jìn)行一次重做日志的fsync操作,因此實(shí)例 crash 最多丟失1秒鐘內(nèi)的事務(wù)。(master thread是負(fù)責(zé)將緩沖池中的數(shù)據(jù)異步刷新到磁盤,保證數(shù)據(jù)的一致性)

fsyncwrite操作實(shí)際上是系統(tǒng)調(diào)用函數(shù),在很多持久化場景都有使用到,比如 Redis 的AOF持久化中也使用到兩個函數(shù)。fsync操作 將數(shù)據(jù)提交到硬盤中,強(qiáng)制硬盤同步,將一直阻塞到寫入硬盤完成后返回,大量進(jìn)行fsync操作就有性能瓶頸,而write操作將數(shù)據(jù)寫到系統(tǒng)的頁面緩存后立即返回,后面依靠系統(tǒng)的調(diào)度機(jī)制將緩存數(shù)據(jù)刷到磁盤中去,其順序是user buffer——> page cache——>disk。

MySQL中的redo及undo簡單分析

除了上面談到的Force Log at Commit機(jī)制保證事務(wù)的持久性,實(shí)際上重做日志的實(shí)現(xiàn)還要依賴于mini-transaction。

Redo在InnoDB中是如何實(shí)現(xiàn)的?與mini-transaction的聯(lián)系?

Redo的實(shí)現(xiàn)實(shí)則跟mini-transaction緊密相關(guān),mini-transaction是一種InnoDB內(nèi)部使用的機(jī)制,通過mini-transaction來保證并發(fā)事務(wù)操作下以及數(shù)據(jù)庫異常時數(shù)據(jù)頁中數(shù)據(jù)的一致性,但它不屬于事務(wù)。

為了使得mini-transaction保證數(shù)據(jù)頁數(shù)據(jù)的一致性,mini-transaction必須遵循以下三種協(xié)議

  • The FIX Rules

  • Write-Ahead Log

  • Force-log-at-commit

The FIX Rules

修改一個數(shù)據(jù)頁時需要獲得該頁的x-latch(排他鎖),獲取一個數(shù)據(jù)頁時需要該頁的s-latch(讀鎖或者稱為共享鎖) 或者是 x-latch,持有該頁的鎖直到修改或訪問該頁的操作完成。

Write-Ahead Log

在前面闡述中就提到了Write-Ahead Log(預(yù)先寫日志)。在持久化一個數(shù)據(jù)頁之前,必須先將內(nèi)存中相應(yīng)的日志頁持久化。每個頁都有一個LSN(log sequence number),代表日志序列號,(LSN占用8字節(jié),單調(diào)遞增), 當(dāng)一個數(shù)據(jù)頁需要寫入到持久化設(shè)備之前,要求內(nèi)存中小于該頁LSN的日志先寫入持久化設(shè)備

那為什么必須要先寫日志呢?可不可以不寫日志,直接將數(shù)據(jù)寫入磁盤?原則上是可以的,只不過會產(chǎn)生一些問題,數(shù)據(jù)修改會產(chǎn)生隨機(jī)IO,但日志是順序IO,append方式順序?qū)懀且环N串行的方式,這樣才能充分利用磁盤的性能。

Force-log-at-commit

這一點(diǎn)也就是前文提到的如何保證事務(wù)的持久性的內(nèi)容,這里再次總結(jié)一下,與上面的內(nèi)容相呼應(yīng)。在一個事務(wù)中可以修改多個頁,Write-Ahead Log 可以保證單個數(shù)據(jù)頁的一致性,但是無法保證事務(wù)的持久性,F(xiàn)orce-log-at-commit 要求當(dāng)一個事務(wù)提交時,其產(chǎn)生所有的mini-transaction 日志必須刷新到磁盤中,若日志刷新完成后,在緩沖池中的頁刷新到持久化存儲設(shè)備前數(shù)據(jù)庫發(fā)生了宕機(jī),那么數(shù)據(jù)庫重啟時,可以通過日志來保證數(shù)據(jù)的完整性。

重做日志的寫入流程

MySQL中的redo及undo簡單分析

上圖表示了重做日志的寫入流程,每個mini-transaction對應(yīng)每一條DML操作,比如一條update語句,其由一個mini-transaction來保證,對數(shù)據(jù)修改后,產(chǎn)生redo1,首先將其寫入mini-transaction私有的Buffer中,update語句結(jié)束后,將redo1從私有Buffer拷貝到公有的Log Buffer中。當(dāng)整個外部事務(wù)提交時,將redo log buffer再刷入到redo log file中。

undo log

undo log的定義

undo log主要記錄的是數(shù)據(jù)的邏輯變化,為了在發(fā)生錯誤時回滾之前的操作,需要將之前的操作都記錄下來,然后在發(fā)生錯誤時才可以回滾。

undo log的作用

undo是一種邏輯日志,有兩個作用:

  • 用于事務(wù)的回滾

  • MVCC

關(guān)于MVCC(多版本并發(fā)控制)的內(nèi)容這里就不多說了,本文重點(diǎn)關(guān)注undo log用于事務(wù)的回滾。

undo日志,只將數(shù)據(jù)庫邏輯地恢復(fù)到原來的樣子,在回滾的時候,它實(shí)際上是做的相反的工作,比如一條INSERT ,對應(yīng)一條 DELETE,對于每個UPDATE,對應(yīng)一條相反的 UPDATE,將修改前的行放回去。undo日志用于事務(wù)的回滾操作進(jìn)而保障了事務(wù)的原子性。

undo log的寫入時機(jī)

  • DML操作修改聚簇索引前,記錄undo日志

  • 二級索引記錄的修改,不記錄undo日志

需要注意的是,undo頁面的修改,同樣需要記錄redo日志。

undo的存儲位置

在InnoDB存儲引擎中,undo存儲在回滾段(Rollback Segment)中,每個回滾段記錄了1024個undo log segment,而在每個undo log segment段中進(jìn)行undo 頁的申請,在5.6以前,Rollback Segment是在共享表空間里的,5.6.3之后,可通過 innodb_undo_tablespace設(shè)置undo存儲的位置。

undo的類型

在InnoDB存儲引擎中,undo log分為:

  • insert undo log

  • update undo log

insert undo log是指在insert 操作中產(chǎn)生的undo log,因?yàn)閕nsert操作的記錄,只對事務(wù)本身可見,對其他事務(wù)不可見。故該undo log可以在事務(wù)提交后直接刪除,不需要進(jìn)行purge操作。

而update undo log記錄的是對delete 和update操作產(chǎn)生的undo log,該undo log可能需要提供MVCC機(jī)制,因此不能再事務(wù)提交時就進(jìn)行刪除。提交時放入undo log鏈表,等待purge線程進(jìn)行最后的刪除。

補(bǔ)充:purge線程兩個主要作用是:清理undo頁和清除page里面帶有Delete_Bit標(biāo)識的數(shù)據(jù)行。在InnoDB中,事務(wù)中的Delete操作實(shí)際上并不是真正的刪除掉數(shù)據(jù)行,而是一種Delete Mark操作,在記錄上標(biāo)識Delete_Bit,而不刪除記錄。是一種"假刪除",只是做了個標(biāo)記,真正的刪除工作需要后臺purge線程去完成。

undo log 是否是redo log的逆過程?

undo log 是否是redo log的逆過程?其實(shí)從前文就可以得出答案了,undo log是邏輯日志,對事務(wù)回滾時,只是將數(shù)據(jù)庫邏輯地恢復(fù)到原來的樣子,而redo log是物理日志,記錄的是數(shù)據(jù)頁的物理變化,顯然undo log不是redo log的逆過程。

redo & undo總結(jié)

下面是redo log + undo log的簡化過程,便于理解兩種日志的過程:

假設(shè)有A、B兩個數(shù)據(jù),值分別為1,2.
1. 事務(wù)開始
2. 記錄A=1到undo log
3. 修改A=3
4. 記錄A=3到 redo log
5. 記錄B=2到 undo log
6. 修改B=4
7. 記錄B=4到redo log
8. 將redo log寫入磁盤
9. 事務(wù)提交

實(shí)際上,在insert/update/delete操作中,redo和undo分別記錄的內(nèi)容都不一樣,量也不一樣。在InnoDB內(nèi)存中,一般的順序如下:

  • 寫undo的redo

  • 寫undo

  • 修改數(shù)據(jù)頁

  • 寫Redo

小結(jié)

本文分析了事務(wù)中的redo和undo日志,參考了一些資料書籍整理得出,可能有些地方表述的不清楚。如有不對之處,歡迎指出。

以上就是MySQL事務(wù)中的redo與undo的分析(圖文)的詳細(xì)內(nèi)容,更多請關(guān)注創(chuàng)新互聯(lián)網(wǎng)站制作公司其它相關(guān)文章!

本文名稱:MySQL中的redo及undo簡單分析-創(chuàng)新互聯(lián)
本文路徑:http://chinadenli.net/article0/cesoio.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作品牌網(wǎng)站設(shè)計(jì)軟件開發(fā)網(wǎng)站策劃做網(wǎng)站品牌網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司