国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

這篇具有很好參考價值的文章主要介紹了MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

MySQL 日志 主要包括錯誤日志、查詢?nèi)罩?、慢查詢?nèi)罩?、事?wù)日志、二進制日志幾大類。其中,比較重要的還要屬二進制日志 binlog(歸檔日志)事務(wù)日志 redo log(重做日志)undo log(回滾日志)。

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)
1、redo log?

redo log(重做日志)是InnoDB存儲引擎獨有的,它讓MySQL擁有了崩潰恢復(fù)能力。

比如 MySQL 實例掛了或宕機了,重啟時,InnoDB存儲引擎會使用redo log恢復(fù)數(shù)據(jù),保證數(shù)據(jù)的持久性與完整性。

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

MySQL 中數(shù)據(jù)是以頁為單位,你查詢一條記錄,會從硬盤把一頁的數(shù)據(jù)加載出來,加載出來的數(shù)據(jù)叫數(shù)據(jù)頁,會放入到 Buffer Pool 中。

后續(xù)的查詢都是先從 Buffer Pool 中找,沒有命中再去硬盤加載,減少硬盤 IO 開銷,提升性能。

更新表數(shù)據(jù)的時候,也是如此,發(fā)現(xiàn) Buffer Pool 里存在要更新的數(shù)據(jù),就直接在 Buffer Pool 里更新。

然后會把“在某個數(shù)據(jù)頁上做了什么修改”記錄到重做日志緩存(redo log buffer)里,接著刷盤到 redo log 文件里。

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

理想情況,事務(wù)一提交就會進行刷盤操作,但實際上,刷盤的時機是根據(jù)策略來進行的。

小貼士: 每條 redo 記錄由“表空間號+數(shù)據(jù)頁號+偏移量+修改數(shù)據(jù)長度+具體修改的數(shù)據(jù)”組成

2、刷盤時機

InnoDB 存儲引擎為 redo log 的刷盤策略提供了 innodb_flush_log_at_trx_commit 參數(shù),它支持三種策略:

  • 0 :設(shè)置為 0 的時候,表示每次事務(wù)提交時不進行刷盤操作
  • 1 :設(shè)置為 1 的時候,表示每次事務(wù)提交時都將進行刷盤操作(默認值)
  • 2 :設(shè)置為 2 的時候,表示每次事務(wù)提交時都只把 redo log buffer 內(nèi)容寫入 page cache

innodb_flush_log_at_trx_commit 參數(shù)默認為 1 ,也就是說當事務(wù)提交時會調(diào)用 fsyncredo log 進行刷盤

另外,InnoDB 存儲引擎有一個后臺線程,每隔1 秒,就會把 redo log buffer 中的內(nèi)容寫到文件系統(tǒng)緩存(page cache),然后調(diào)用 fsync 刷盤。

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

也就是說,一個沒有提交事務(wù)的 redo log 記錄,也可能會刷盤。

為什么呢?

因為在事務(wù)執(zhí)行過程 redo log 記錄是會寫入redo log buffer 中,這些 redo log 記錄會被后臺線程刷盤。

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

除了后臺線程每秒1次的輪詢操作,還有一種情況,當 redo log buffer 占用的空間即將達到 innodb_log_buffer_size 一半的時候,后臺線程會主動刷盤。

下面是不同刷盤策略的流程圖。

innodb_flush_log_at_trx_commit=0

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

0時,如果MySQL掛了或宕機可能會有1秒數(shù)據(jù)的丟失。

innodb_flush_log_at_trx_commit=1

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

1時, 只要事務(wù)提交成功,redo log記錄就一定在硬盤里,不會有任何數(shù)據(jù)丟失。

如果事務(wù)執(zhí)行期間MySQL掛了或宕機,這部分日志丟了,但是事務(wù)并沒有提交,所以日志丟了也不會有損失。

innodb_flush_log_at_trx_commit=2

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

2時, 只要事務(wù)提交成功,redo log buffer中的內(nèi)容只寫入文件系統(tǒng)緩存(page cache)。

如果僅僅只是MySQL掛了不會有任何數(shù)據(jù)丟失,但是宕機可能會有1秒數(shù)據(jù)的丟失。

3、日志文件組?

硬盤上存儲的 redo log 日志文件不只一個,而是以一個日志文件組的形式出現(xiàn)的,每個的redo日志文件大小都是一樣的。

比如可以配置為一組4個文件,每個文件的大小是 1GB,整個 redo log 日志文件組可以記錄4G的內(nèi)容。

它采用的是環(huán)形數(shù)組形式,從頭開始寫,寫到末尾又回到頭循環(huán)寫,如下圖所示。

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

在個日志文件組中還有兩個重要的屬性,分別是 write pos、checkpoint

  • write pos 是當前記錄的位置,一邊寫一邊后移
  • checkpoint 是當前要擦除的位置,也是往后推移

每次刷盤 redo log 記錄到日志文件組中,write pos 位置就會后移更新。

每次 MySQL 加載日志文件組恢復(fù)數(shù)據(jù)時,會清空加載過的 redo log 記錄,并把 checkpoint 后移更新。

write poscheckpoint 之間的還空著的部分可以用來寫入新的 redo log 記錄。

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

如果 write pos 追上 checkpoint ,表示日志文件組滿了,這時候不能再寫入新的 redo log 記錄,MySQL 得停下來,清空一些記錄,把 checkpoint 推進一下。

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

4、redo log 小結(jié)?

現(xiàn)在我們來思考一個問題: 只要每次把修改后的數(shù)據(jù)頁直接刷盤不就好了,還有 redo log 什么事?

它們不都是刷盤么?差別在哪里?

1 Byte = 8bit
1 KB = 1024 Byte
1 MB = 1024 KB
1 GB = 1024 MB
1 TB = 1024 GB

實際上,數(shù)據(jù)頁大小是16KB,刷盤比較耗時,可能就修改了數(shù)據(jù)頁里的幾 Byte 數(shù)據(jù),有必要把完整的數(shù)據(jù)頁刷盤嗎?

而且數(shù)據(jù)頁刷盤是隨機寫,因為一個數(shù)據(jù)頁對應(yīng)的位置可能在硬盤文件的隨機位置,所以性能是很差。

如果是寫 redo log,一行記錄可能就占幾十 Byte,只包含表空間號、數(shù)據(jù)頁號、磁盤文件偏移 量、更新值,再加上是順序?qū)懀?code>所以刷盤速度很快。

所以用 redo log 形式記錄修改內(nèi)容,性能會遠遠超過刷數(shù)據(jù)頁的方式,這也讓數(shù)據(jù)庫的并發(fā)能力更強。

其實內(nèi)存的數(shù)據(jù)頁在一定時機也會刷盤,我們把這稱為頁合并,講 Buffer Pool的時候會對這塊細說

5、binlog?

redo log 它是物理日志,記錄內(nèi)容是“在某個數(shù)據(jù)頁上做了什么修改”,屬于 InnoDB 存儲引擎。

binlog邏輯日志,記錄內(nèi)容是語句的原始邏輯,類似于“給 ID=2 這一行的 c 字段加 1”,屬于MySQL Server 層。

不管用什么存儲引擎,只要發(fā)生了表數(shù)據(jù)更新,都會產(chǎn)生 binlog 日志

那 binlog 到底是用來干嘛的?

可以說MySQL數(shù)據(jù)庫的數(shù)據(jù)備份、主備、主主、主從都離不開binlog,需要依靠binlog來同步數(shù)據(jù),保證數(shù)據(jù)一致性。

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

binlog會記錄所有涉及更新數(shù)據(jù)的邏輯操作,并且是順序?qū)憽?/p>

6、記錄格式

binlog 日志有三種格式,可以通過binlog_format參數(shù)指定。

  • statement
  • row
  • mixed

指定statement,記錄的內(nèi)容是SQL語句原文,比如執(zhí)行一條update T set update_time=now() where id=1,記錄的內(nèi)容如下。

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

同步數(shù)據(jù)時,會執(zhí)行記錄的SQL語句,但是有個問題,update_time=now()這里會獲取當前系統(tǒng)時間,直接執(zhí)行會導(dǎo)致與原庫的數(shù)據(jù)不一致。

為了解決這種問題,我們需要指定為row,記錄的內(nèi)容不再是簡單的SQL語句了,還包含操作的具體數(shù)據(jù),記錄內(nèi)容如下。

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

row格式記錄的內(nèi)容看不到詳細信息,要通過mysqlbinlog工具解析出來。

update_time=now()變成了具體的時間update_time=1627112756247,條件后面的@1、@2、@3 都是該行數(shù)據(jù)第 1 個~3 個字段的原始值(假設(shè)這張表只有 3 個字段)。

這樣就能保證同步數(shù)據(jù)的一致性,通常情況下都是指定為row, 這樣可以為數(shù)據(jù)庫的恢復(fù)與同步帶來更好的可靠性。

但是這種格式,需要更大的容量來記錄,比較占用空間 ,恢復(fù)與同步時會更消耗IO資源,影響執(zhí)行速度。

所以就有了一種折中的方案,指定為mixed,記錄的內(nèi)容是前兩者的混合。

MySQL會判斷這條SQL語句是否可能引起數(shù)據(jù)不一致,如果是,就用row格式,否則就用statement格式

7、寫入機制

binlog的寫入時機也非常簡單,事務(wù)執(zhí)行過程中,先把日志寫到binlog cache,事務(wù)提交的時候,再把binlog cache寫到binlog文件中。

因為一個事務(wù)的binlog不能被拆開,無論這個事務(wù)多大,也要確保一次性寫入,所以系統(tǒng)會給每個線程分配一個塊內(nèi)存作為binlog cache。

我們可以通過binlog_cache_size參數(shù)控制單個線程 binlog cache 大小,如果存儲內(nèi)容超過了這個參數(shù),就要暫存到磁盤(Swap)。

binlog日志刷盤流程如下

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

  • 上圖的 write,是指把日志寫入到文件系統(tǒng)的 page cache,并沒有把數(shù)據(jù)持久化到磁盤,所以速度比較快
  • 上圖的 fsync,才是將數(shù)據(jù)持久化到磁盤的操作

writefsync的時機,可以由參數(shù)sync_binlog控制,默認是0。

為0的時候,表示每次提交事務(wù)都只write,由系統(tǒng)自行判斷什么時候執(zhí)行fsync。

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

雖然性能得到提升,但是機器宕機,page cache里面的 binlog 會丟失。

為了安全起見,可以設(shè)置為1,表示每次提交事務(wù)都會執(zhí)行fsync,就如同 redo log 日志刷盤流程 一樣。

最后還有一種折中方式,可以設(shè)置為N(N>1),表示每次提交事務(wù)都write,但累積N個事務(wù)后才fsync。

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

在出現(xiàn)IO瓶頸的場景里,將sync_binlog設(shè)置成一個比較大的值,可以提升性能。

同樣的,如果機器宕機,會丟失最近N個事務(wù)的binlog日志。

8、兩階段提交

  • redo log(重做日志)讓InnoDB存儲引擎擁有了崩潰恢復(fù)能力。
  • binlog(歸檔日志)保證了MySQL集群架構(gòu)的數(shù)據(jù)一致性。

雖然它們都屬于持久化的保證,但是側(cè)重點不同。

在執(zhí)行更新語句過程,會記錄redo logbinlog兩塊日志,以基本的事務(wù)為單位,redo log在事務(wù)執(zhí)行過程中可以不斷寫入,而binlog只有在提交事務(wù)時才寫入,所以redo log與binlog的寫入時機不一樣。

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

回到正題,redo logbinlog兩份日志之間的邏輯不一致,會出現(xiàn)什么問題?

我們以update語句為例,假設(shè)id=2的記錄,字段c值是0,把字段c值更新成1,SQL語句為update T set c=1 where id=2。

假設(shè)執(zhí)行過程中寫完redo log日志后,binlog日志寫期間發(fā)生了異常,會出現(xiàn)什么情況呢?

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

由于binlog沒寫完就異常,這時候binlog里面沒有對應(yīng)的修改記錄。因此,之后用binlog日志恢復(fù)數(shù)據(jù)時,就會少這一次更新,恢復(fù)出來的這一行c值是0,而原庫因為redo log日志恢復(fù),這一行c值是1,最終數(shù)據(jù)不一致。

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

為了解決兩份日志之間的邏輯一致問題,InnoDB存儲引擎使用兩階段提交方案。

原理很簡單,將redo log寫入拆成了兩個步驟preparecommit,這就是兩階段提交。

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

使用兩階段提交后,寫入binlog時發(fā)生異常也不會有影響,因為MySQL根據(jù)redo log日志恢復(fù)數(shù)據(jù)時,發(fā)現(xiàn)redo log還處于prepare階段,并且沒有對應(yīng)binlog日志,就會回滾該事務(wù)

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

再看一個場景,redo log設(shè)置commit階段發(fā)生異常,那會不會回滾事務(wù)呢?

MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)

并不會回滾事務(wù),它會執(zhí)行上圖框住的邏輯,雖然redo log是處于prepare階段,但是能通過事務(wù)id找到對應(yīng)的binlog日志,所以MySQL認為是完整的,就會提交事務(wù)恢復(fù)數(shù)據(jù)。

9、undo log

我們知道如果想要保證事務(wù)的原子性,就需要在異常發(fā)生時,對已經(jīng)執(zhí)行的操作進行回滾。

在 MySQL 中,恢復(fù)機制是通過 回滾日志(undo log) 實現(xiàn)的,所有事務(wù)進行的修改都會先記錄到這個回滾日志中,然后再執(zhí)行相關(guān)的操作。如果執(zhí)行過程中遇到異常的話,我們直接利用 回滾日志 中的信息將數(shù)據(jù)回滾到修改之前的樣子即可!

并且,回滾日志會先于數(shù)據(jù)持久化到磁盤上。這樣就保證了即使遇到數(shù)據(jù)庫突然宕機等情況,當用戶再次啟動數(shù)據(jù)庫的時候,數(shù)據(jù)庫還能夠通過查詢回滾日志來回滾將之前未完成的事務(wù)。

另外,MVCC 的實現(xiàn)依賴于:隱藏字段、Read View、undo log。在內(nèi)部實現(xiàn)中,InnoDB 通過數(shù)據(jù)行的 DB_TRX_IDRead View 來判斷數(shù)據(jù)的可見性,如不可見,則通過數(shù)據(jù)行的 DB_ROLL_PTR 找到 undo log 中的歷史版本。

每個事務(wù)讀到的數(shù)據(jù)版本可能是不一樣的,在同一個事務(wù)中,用戶只能看到該事務(wù)創(chuàng)建 Read View 之前已經(jīng)提交的修改和該事務(wù)本身做的修改

10、總結(jié)

MySQL InnoDB 引擎使用 redo log(重做日志) 保證事務(wù)的持久性,使用 undo log(回滾日志) 來保證事務(wù)的原子性

MySQL數(shù)據(jù)庫的數(shù)據(jù)備份、主備、主主、主從都離不開binlog,需要依靠binlog來同步數(shù)據(jù),保證數(shù)據(jù)一致性。文章來源地址http://www.zghlxwxcb.cn/news/detail-434028.html

到了這里,關(guān)于MySQL知識學(xué)習(xí)03(三大日志詳解 binlog、redo log、undo log)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • Java基礎(chǔ)-知識點03(面試|學(xué)習(xí))

    Java基礎(chǔ)-知識點03(面試|學(xué)習(xí))

    String 類是Java中用于表示字符串的類。在Java中,字符串是一系列字符的序列,用于表示文本數(shù)據(jù)。 String類的作用及特性 1、 創(chuàng)建字符串 : 可以通過字符串字面量或使用new來創(chuàng)建字符串對象。 2、 字符串長度 : 可以使用length()方法獲取字符串的長度。 3、 字符串連接

    2024年04月15日
    瀏覽(48)
  • [TS手冊學(xué)習(xí)] 03_函數(shù)相關(guān)知識點

    TS官方手冊:TypeScript: Handbook - The TypeScript Handbook (typescriptlang.org) 函數(shù)類型表達式 使用類似于箭頭表達式的形式來描述一個函數(shù)的類型。 上述代碼中, fn: (a:string) = void 表示變量 fn 是一個函數(shù),這個函數(shù)有一個參數(shù) a ,是 string 類型,且這個函數(shù)的返回值類型為 void ,即沒有

    2024年02月05日
    瀏覽(21)
  • mysql binlog 日志詳解及恢復(fù)

    一、binlog概述 binlog是Mysql sever層維護的一種二進制日志,與innodb引擎中的redo/undolog是完全不同的日志; 其主要是用來記錄對mysql數(shù)據(jù)更新或潛在發(fā)生更新的SQL語句,并以\\\"事務(wù)\\\"的形式保存在磁盤中; 作用主要有: 復(fù)制:MySQL Replication在Master端開啟binlog,Master把它的二進制日志傳

    2024年02月12日
    瀏覽(87)
  • 【前端知識】Three 學(xué)習(xí)日志(十)—— 常見幾何體(長方體、球體、圓柱、矩形平面、圓形平面)

    【前端知識】Three 學(xué)習(xí)日志(十)—— 常見幾何體(長方體、球體、圓柱、矩形平面、圓形平面)

    Three 學(xué)習(xí)日志(十)—— 常見幾何體(長方體、球體、圓柱、矩形平面、圓形平面) 一、構(gòu)建常用幾何體 二、 遍歷加入場景中 三、效果展示 四、完整代碼

    2024年02月07日
    瀏覽(26)
  • Java知識學(xué)習(xí)13(AQS詳解)

    Java知識學(xué)習(xí)13(AQS詳解)

    1、AQS介紹? AQS 的全稱為 AbstractQueuedSynchronizer ,翻譯過來的意思就是 抽象隊列同步器 。這個類在 java.util.concurrent.locks 包下面。 AQS 就是一個抽象類,主要 用來構(gòu)建鎖和同步器 。 AQS 為構(gòu)建鎖和同步器提供了一些通用功能的實現(xiàn),因此,使用 AQS 能簡單且高效地構(gòu)造出應(yīng)用廣

    2024年02月13日
    瀏覽(17)
  • 【一文詳解】知識分享:(C#開發(fā)學(xué)習(xí)快速入門)

    【一文詳解】知識分享:(C#開發(fā)學(xué)習(xí)快速入門)

    c語言 是面向過程。 c++ 是面向過程+面向?qū)ο蟆?c# 是純粹的面向?qū)ο? 核心思想是以人的思維習(xí)慣來分析和解決問題。萬物皆對象 。 面向?qū)ο箝_發(fā)步驟: 分析對象 特征 行為 關(guān)系(對象關(guān)系/類關(guān)系) 寫代碼: 特征–成員變量 方法–成員方法 實例化–具體對象 Note(補充知識)

    2024年01月19日
    瀏覽(130)
  • python算法中的機器學(xué)習(xí)算法之無監(jiān)督學(xué)習(xí)知識點(詳解)

    目錄 學(xué)習(xí)目標: 學(xué)習(xí)內(nèi)容: Ⅰ. K均值聚類(K-Means Clustering) Ⅱ. 層次聚類(Hierarchical Clusteri

    2024年02月01日
    瀏覽(23)
  • 【C++入門】學(xué)習(xí)使用二維數(shù)組基本知識及用法詳解

    【C++入門】學(xué)習(xí)使用二維數(shù)組基本知識及用法詳解

    ???♂?iecne個人主頁: : iecne的學(xué)習(xí)日志 ??每天 關(guān)注 iecne的作品,一起進步 ??一起學(xué)習(xí),必看iecne ??希望大家多多支持??一起進步呀! 二維數(shù)組就是在一維數(shù)組上多加一個維度。 建議:以下三種定義方式,利用第二種更加直觀,提高代碼可讀性 第二種就是在定義一

    2024年01月25日
    瀏覽(26)
  • 【數(shù)據(jù)庫通關(guān)之路】 MySQL 全路線學(xué)習(xí)知識點梳理(中)

    【數(shù)據(jù)庫通關(guān)之路】 MySQL 全路線學(xué)習(xí)知識點梳理(中)

    本文是 MYSQL零基礎(chǔ)小白學(xué)習(xí) 系列的第二篇文章,點此閱讀 上一篇文章 文末包郵送《分布式中間件核心原理與RocketMQ最佳實踐 》 (點擊下方目錄直達)一本,本文每+1000瀏覽額外加抽一人 需求 :設(shè)計包含如下信息的學(xué)生表,請注重數(shù)據(jù)類型、長度的合理性。 編號 姓名,姓名最

    2023年04月20日
    瀏覽(20)
  • 【數(shù)據(jù)庫通關(guān)之路】 MySQL 全路線學(xué)習(xí)知識點梳理(下)

    【數(shù)據(jù)庫通關(guān)之路】 MySQL 全路線學(xué)習(xí)知識點梳理(下)

    本文是MYSQL零基礎(chǔ)小白學(xué)習(xí)系列的第三篇文章,點此閱讀 上一篇文章 文末 包郵隨機送《MySQL數(shù)據(jù)庫進階實戰(zhàn) 》 五本 (點擊下方目錄直達) 目的:主鍵是一行數(shù)據(jù)的唯一標識,要求非空且唯一 添加約束: 建完表后添加主鍵約束: 刪除約束: 目的:保存數(shù)據(jù)時,未指定值則采

    2024年02月04日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包