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

MySQL三大日志(binlog、redo?log和undo?log)圖文詳解

 更新時(shí)間:2023年01月18日 14:11:40   作者:世界盡頭與你  
日志是MySQL數(shù)據(jù)庫的重要組成部分,記錄著數(shù)據(jù)庫運(yùn)行期間各種狀態(tài)信息,下面這篇文章主要給大家介紹了關(guān)于MySQL三大日志(binlog、redo?log和undo?log)的相關(guān)資料,需要的朋友可以參考下

1.redo log

redo log概述

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

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

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

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

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

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

刷盤時(shí)機(jī)

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

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

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

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

除了后臺(tái)線程每秒1次的輪詢操作,還有一種情況,當(dāng) redo log buffer 占用的空間即將達(dá)到 innodb_log_buffer_size 一半的時(shí)候,后臺(tái)線程會(huì)主動(dòng)刷盤。

innodb_flush_log_at_trx_commit=0

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

innodb_flush_log_at_trx_commit=1

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

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

innodb_flush_log_at_trx_commit=2

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

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

日志文件組

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

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

2.binlog binlog

概述

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

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

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

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

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

記錄格式

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

  • statement
  • row
  • mixed

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

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

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

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

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

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

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

寫入機(jī)制

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

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

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

binlog日志刷盤流程如下:

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

刷盤時(shí)機(jī)

writefsync的時(shí)機(jī),可以由參數(shù)sync_binlog控制,默認(rèn)是0。

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

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

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

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

在出現(xiàn)IO瓶頸的場(chǎng)景里,將sync_binlog設(shè)置成一個(gè)比較大的值,可以提升性能。同樣的,如果機(jī)器宕機(jī),會(huì)丟失最近N個(gè)事務(wù)的binlog日志。??

3.兩階段提交

redo log(重做日志)讓InnoDB存儲(chǔ)引擎擁有了崩潰恢復(fù)能力。

binlog(歸檔日志)保證了MySQL集群架構(gòu)的數(shù)據(jù)一致性。

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

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

回到正題,redo logbinlog兩份日志之間的邏輯不一致,會(huì)出現(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ā)生了異常,會(huì)出現(xiàn)什么情況呢?

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

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

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

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

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

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

4.undo log

我們知道如果想要保證事務(wù)的原子性,就需要在異常發(fā)生時(shí),對(duì)已經(jīng)執(zhí)行的操作進(jìn)行回滾,在 MySQL 中,恢復(fù)機(jī)制是通過 回滾日志(undo log) 實(shí)現(xiàn)的,所有事務(wù)進(jìn)行的修改都會(huì)先記錄到這個(gè)回滾日志中,然后再執(zhí)行相關(guān)的操作。如果執(zhí)行過程中遇到異常的話,我們直接利用 回滾日志 中的信息將數(shù)據(jù)回滾到修改之前的樣子即可!并且,回滾日志會(huì)先于數(shù)據(jù)持久化到磁盤上。這樣就保證了即使遇到數(shù)據(jù)庫突然宕機(jī)等情況,當(dāng)用戶再次啟動(dòng)數(shù)據(jù)庫的時(shí)候,數(shù)據(jù)庫還能夠通過查詢回滾日志來回滾將之前未完成的事務(wù)。

另外,MVCC 的實(shí)現(xiàn)依賴于:隱藏字段、Read View、undo log。在內(nèi)部實(shí)現(xiàn)中,InnoDB 通過數(shù)據(jù)行的 DB_TRX_IDRead View 來判斷數(shù)據(jù)的可見性,如不可見,則通過數(shù)據(jù)行的 DB_ROLL_PTR 找到 undo log 中的歷史版本。每個(gè)事務(wù)讀到的數(shù)據(jù)版本可能是不一樣的,在同一個(gè)事務(wù)中,用戶只能看到該事務(wù)創(chuàng)建 Read View 之前已經(jīng)提交的修改和該事務(wù)本身做的修改

5.總結(jié)

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

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

本教程基于JavaGuide - 數(shù)據(jù)庫篇 - 三大日志詳解

總結(jié) 

到此這篇關(guān)于MySQL三大日志(binlog、redo log和undo log)的文章就介紹到這了,更多相關(guān)MySQL日志binlog、redo log和undo log內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 連接mysql連接超時(shí)報(bào)錯(cuò)問題以及解決

    連接mysql連接超時(shí)報(bào)錯(cuò)問題以及解決

    這篇文章主要介紹了連接mysql連接超時(shí)報(bào)錯(cuò)問題以及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • MYSQL初始化數(shù)據(jù)目錄的實(shí)現(xiàn)步驟

    MYSQL初始化數(shù)據(jù)目錄的實(shí)現(xiàn)步驟

    本文主要介紹了MYSQL初始化數(shù)據(jù)目錄的實(shí)現(xiàn)步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-02-02
  • MySQL中如何給一個(gè)字段遞增賦值

    MySQL中如何給一個(gè)字段遞增賦值

    這篇文章主要介紹了MySQL中如何給一個(gè)字段遞增賦值問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Linux下安裝配置MySQL

    Linux下安裝配置MySQL

    mysql最流行的關(guān)系型數(shù)據(jù)庫之一,目前隸屬于oracle公司,因體積小、速度快、總體擁有成本低,開放源代碼這一特點(diǎn),所以是我們?nèi)粘i_發(fā)的首選。下面我們來看看如何在Linux下安裝配置MySQL
    2017-05-05
  • mysql-8.0.30壓縮包版安裝和配置MySQL環(huán)境過程

    mysql-8.0.30壓縮包版安裝和配置MySQL環(huán)境過程

    該文章介紹了如何在Windows系統(tǒng)中下載、安裝和配置MySQL數(shù)據(jù)庫,包括下載地址、解壓文件、創(chuàng)建和配置my.ini文件、設(shè)置環(huán)境變量、初始化MySQL服務(wù)、啟動(dòng)服務(wù)以及修改root用戶密碼等步驟
    2025-01-01
  • mysql 5.7.19 winx64免安裝版配置教程

    mysql 5.7.19 winx64免安裝版配置教程

    這篇文章主要為大家詳細(xì)介紹了mysql 5.7.19 winx64免安裝版配置教程,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-06-06
  • mysql關(guān)聯(lián)兩張表時(shí)的編碼問題及解決辦法

    mysql關(guān)聯(lián)兩張表時(shí)的編碼問題及解決辦法

    在本篇文章里小編給大家整理的是關(guān)于mysql關(guān)聯(lián)兩張表時(shí)的編碼問題及解決辦法,有需要的朋友們可以參考下。
    2019-09-09
  • Mysql閃退問題圖文解決辦法

    Mysql閃退問題圖文解決辦法

    之前在使用MySQL 5.5 Command Line Client時(shí),無論輸入什么密碼,都出現(xiàn)閃退的情況,糾結(jié)了半天才找到原因,下面小編給大家分享我的解決方法,感興趣的朋友一起看看吧
    2016-11-11
  • 阿里云ECS centos6.8下安裝配置MySql5.7的教程

    阿里云ECS centos6.8下安裝配置MySql5.7的教程

    阿里云默認(rèn)yum命令下的MySQL是5.17****,安裝mysql5.7之前先卸載以前的版本。下面通過本文給大家介紹阿里云ECS centos6.8下安裝配置MySql5.7的教程,需要的的朋友參考下吧
    2017-07-07
  • MySQL復(fù)合查詢和表的內(nèi)外連接示例詳解

    MySQL復(fù)合查詢和表的內(nèi)外連接示例詳解

    在數(shù)據(jù)庫管理和數(shù)據(jù)分析中,單表查詢往往無法滿足復(fù)雜的數(shù)據(jù)查詢需求,因此多表查詢和子查詢成為了解決問題的關(guān)鍵技術(shù),MySQL支持多種多表查詢方式,如內(nèi)連接、外連接(左外連接和右外連接)以及自連接,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-10-10

最新評(píng)論