什么是Redolog與Binlog

這篇文章主要介紹“什么是Redo log與Binlog”,在日常操作中,相信很多人在什么是Redo log與Binlog問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”什么是Redo log與Binlog”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!

網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了保定免費建站歡迎大家使用!

MySQL是常用的數(shù)據(jù)庫存儲應(yīng)用,我們利用它存儲信息、查詢信息、處理事務(wù)。特別是為了提高可用性會用到事務(wù)一致性、主從復(fù)制、數(shù)據(jù)恢復(fù)等功能。我們在使用這些功能的時候,是否想過其背后有哪些原理和機(jī)制在支撐?今天我們聚焦redo  log和binlog兩個MySQL的日志機(jī)制,以及它們是如何配合提高M(jìn)ySQL存儲可靠性的。今天會學(xué)到以下內(nèi)容:

  • Redo log

Redo log 解決了什么問題?

Redo log的執(zhí)行流程

Redo log的寫入方式

Redo log記錄形式

  • Binlog

a.Binlog解決了什么問題?

b.Binlog的日志格式

  • Redo log 與Binlog的區(qū)別與合作

Redo log

1.Redo log 解決了什么問題?

MySQL應(yīng)用中處理事務(wù)是一個重要的任務(wù),而在事務(wù)處理的四個特性中(ACID),存在一個持久性(Durability),它表示在事務(wù)執(zhí)行過程中,對數(shù)據(jù)的所有改動都必須在事務(wù)成功結(jié)束前保存至某種物理存儲設(shè)備中。

換句話說,只要事務(wù)提交成功,那么對數(shù)據(jù)庫做的修改就被永久保存下來了,不可能因為任何原因再回到原來的狀態(tài)。那么為什么要在MySQL中考慮事務(wù)持久性的問題呢?假設(shè)這么一種場景,當(dāng)數(shù)據(jù)存儲的事務(wù)正在執(zhí)行但是數(shù)據(jù)還沒有保存的時候,數(shù)據(jù)庫宕機(jī)了,那么這些沒來得及存儲到磁盤的數(shù)據(jù)就丟失了,如果此時有一種機(jī)制能夠記錄這個事務(wù)的操作,當(dāng)數(shù)據(jù)庫服務(wù)恢復(fù)的時候,運行記錄的操作那么這些沒有來得及存儲的數(shù)據(jù)就能夠正確保存了。

Redo log 就是通過這種手段來實現(xiàn)事務(wù)持久性的。上面的場景中是數(shù)據(jù)庫服務(wù)器宕機(jī),如果發(fā)生其他故障導(dǎo)致尚有臟頁未寫入磁盤的場景,也是可以通過Redo  log恢復(fù)的。

1.Redo log的執(zhí)行流程

了解了為什么使用redo log 以后再來看看其執(zhí)行流程,如圖1 所示:

什么是Redo log與Binlog

圖1 redo log執(zhí)行流程

該泳道圖由MySQL客戶端、MySQL Server 層和MySQL 存儲引擎層組成,由于redo  log是在Innodb存儲引擎中使用的,這里假設(shè)存儲引擎就是Innodb。由于MySQL Server  層主要負(fù)責(zé)SQL語句的分析、優(yōu)化和執(zhí)行工作,而MySQL存儲引擎層主要負(fù)責(zé)存儲工作,redo log 也運行在這一層。

跟隨圖中的序號來看看redo log 的運行流程。

  • 1. 從MySQL客戶端請求語句“update T set a=1 where id=2”,并發(fā)現(xiàn)MySQL Server 層。

  • 2. 接收到SQL請求以后MySQL Server 層會對其進(jìn)行分析、優(yōu)化、執(zhí)行等處理工作,將生成的SQL執(zhí)行計劃發(fā)到存儲引擎層執(zhí)行。

  • 3. 存儲引擎層將“a修改為1”的這個操作記錄到內(nèi)存中。

  • 4. 記錄到內(nèi)存以后會修改redo log 的記錄,會在添加一行記錄,其內(nèi)容是“需要在哪個數(shù)據(jù)頁上做什么修改”。

  • 5. 此后,將事務(wù)的狀態(tài)設(shè)置為prepare ,說明已經(jīng)準(zhǔn)備好提交事務(wù)了。

  • 6. 等到MySQL Server 層處理完事務(wù)以后,會將事務(wù)的狀態(tài)設(shè)置為commit,也就是提交該事務(wù)。

  • 7. 在收到事務(wù)提交的請求以后,redo log 會把剛才寫入內(nèi)存中的操作記錄寫入到磁盤中,從而完成整個日志的記錄過程。

2Redo log的寫入方式

從上面介紹的Redo log 的執(zhí)行流程中不難看出,redo log在寫入磁盤之前會先將內(nèi)容寫到內(nèi)存中。因此,redo  log的寫入包括兩部分內(nèi)容:一部分是內(nèi)存中的日志緩沖,稱作redo log buffer;另一部分是磁盤日志文件,稱作 redo log  file。MySQL每執(zhí)行一條DML語句,先將更新記錄寫入redo log buffer ,然后再寫入redo log  file。我們將這種先寫日志,再寫磁盤的方式稱為 WAL(Write-Ahead Logging)技術(shù)。

如圖2所示:

什么是Redo log與Binlog

圖2 redo log 寫入方式

順著箭頭的方向從左往右看,日志最開始會寫入位于存儲引擎Innodb的redo log buffer中,這個也就是所謂的用戶空間(user  space),然后再將日志保存到操作系統(tǒng)內(nèi)核空間(kernel space)的緩沖區(qū)(OS buffer)中。

最后,再從OS buffer寫入到磁盤上的redo log file中,完成寫入操作,這個寫入磁盤的操作也稱作“刷盤”。

了解了redo log的寫入方式之后,我們發(fā)現(xiàn)主要完成的操作是redo log buffer 到磁盤的redo log  file的寫入過程,其中需要經(jīng)過OS buffer進(jìn)行中轉(zhuǎn)。關(guān)于redo log buffer寫入redo log file的時機(jī),可以通過  參數(shù)innodb_flush_log_at_trx_commit 進(jìn)行配置,各參數(shù)值含義如下:

參數(shù)為0的時候,稱為“延遲寫”。事務(wù)提交時不會將redo log buffer中日志寫入到OS buffer,而是每秒寫入OS  buffer并調(diào)用寫入到redo log file中。換句話說,這種方式每秒會發(fā)起寫入磁盤的操作,假設(shè)系統(tǒng)崩潰,只會丟失1秒鐘的數(shù)據(jù)。

參數(shù)為1 的時候,稱為“實時寫,實時刷”。事務(wù)每次提交都會將redo log buffer中的日志寫入OS buffer并保存到redo log  file中。其有點是,即使系統(tǒng)崩潰也不會丟失任何數(shù)據(jù),缺點也很明顯就是每次事務(wù)提交都要進(jìn)行磁盤操作,性能較差。

參數(shù)為2的時候,稱為“實時寫,延遲刷”。每次事務(wù)提交寫入到OS buffer,然后是每秒將日志寫入到redo log  file。這樣性能會好點,缺點是在系統(tǒng)崩潰的時候會丟失1秒中的事務(wù)數(shù)據(jù)。

3.Redo log記錄形式

redo log是通過循環(huán)寫入的方式保存的。

如圖3所示:

什么是Redo log與Binlog

圖3 redo log 循環(huán)寫入(素材來源于互聯(lián)網(wǎng))

redo log  buffer(內(nèi)存中)是由首尾相連的四個文件組成的,它們分別是:ib_logfile_1、ib_logfile_2、ib_logfile_3、ib_logfile_4。

寫入的方式也是從文件的頭部開始寫入(假設(shè)),每增加一條日志記錄就往文件的尾部添加,直到把四個文件寫滿,再回到文件開頭的地方(ib_logfile_1)繼續(xù)寫,繼續(xù)寫的時候會覆蓋之前的記錄。

圖3中write pos表示當(dāng)前寫入記錄位置(寫入磁盤的數(shù)據(jù)頁的邏輯序列位置),check point表示刷盤(寫入磁盤)后對應(yīng)的位置。write  pos到check point之間的部分用來記錄新日志,也就是留給新記錄的空間。check point到write  pos之間是待刷盤的記錄,如果不刷盤會被新記錄覆蓋。

當(dāng)write pos指針追上check point的時候(也就是新記錄即將覆蓋老記錄的時刻),會推動check  point向前移動,也就是催促其將記錄刷到磁盤中,這樣好空出位置給新記錄。

當(dāng)redo log buffer根據(jù)check  pint刷盤以后,針對Innodb引擎而言是以頁為單位進(jìn)行磁盤存儲,一個事務(wù)可能一個或者多個數(shù)據(jù)頁,每個頁面修改多個字節(jié)。當(dāng)重新啟動Innodb存儲引擎的時候,是會進(jìn)行恢復(fù)操作。因為redo  log記錄的是數(shù)據(jù)頁的物理變化,恢復(fù)的速度比邏輯日志(binlog)要快。

在重啟Innodb時,首先會檢查磁盤中數(shù)據(jù)頁的邏輯序列位置,如果數(shù)據(jù)頁的邏輯序列位置小于日志中的位置,則會從check  point開始恢復(fù)。如果宕機(jī)的時候,正處于check  point的刷盤過程中,且數(shù)據(jù)頁的刷盤進(jìn)度超過了日志頁的刷盤進(jìn)度,此時會出現(xiàn)數(shù)據(jù)頁中記錄的邏輯序列位置大于日志中的邏輯序列位置,這時超出日志進(jìn)度的部分將不會重做,因為這本身就表示已經(jīng)做過的事情,無需再重做。

Binlog

4.Binlog 解決了什么問題?

對于MySQL數(shù)據(jù)庫而言增加數(shù)據(jù)的可靠性是一個永恒的話題,其中主從復(fù)制和數(shù)據(jù)恢復(fù)就是增強數(shù)據(jù)可靠性的兩個重要功能。Binlog就是為實現(xiàn)這兩個功能而設(shè)置的。

主從復(fù)制的場景中在Master 端會開啟binlog ,然后將 binlog 發(fā)送到各個Slave 端,Slave 端重放binlog 從而達(dá)到Slave  端的數(shù)據(jù)和Master端的數(shù)據(jù)保持一致。在數(shù)據(jù)恢復(fù)場景,通過使用mysqlbinlog 工具以及對應(yīng)的binlog  將數(shù)據(jù)恢復(fù)到指定的時間點。那么可以把binlog 解決的問題總結(jié)為兩點,就是主從復(fù)制和數(shù)據(jù)恢復(fù)。

5.Binlog的日志格式

從記錄方式上來看binlog通過追加的方式記錄,當(dāng)日志文件尺寸大于給定值后,后續(xù)的日志會記錄到新的文件上。這個與 redo log  的循環(huán)記錄產(chǎn)生鮮明的對比,同時binlog 可通過配置參數(shù) max_binlog_size 設(shè)置每個binlog 文件的大小。

從日志格式來看,Binlog 日志有三種格式,分別為 STATMENT 、 ROW 和 MIXED 。

在 MySQL 5.7.7 之前,默認(rèn)的格式是 STATEMENT , MySQL 5.7.7 之后,默認(rèn)值是 ROW 。日志格式通過  binlog-format 指定。三種格式的定義和優(yōu)缺點如下:

lSTATEMENT:基于SQL語句的復(fù)制(statement-based replication, SBR),記錄的是修改的SQL語句。

n 優(yōu)點:由于不用記錄每行日志的更改,因此日志文件小,減少了日志量,節(jié)約了IO,提高了性能;

n 缺點:準(zhǔn)確性差,對一些系統(tǒng)行數(shù)不能準(zhǔn)確復(fù)制,例如:now()、uuid()。

lROW:基于行的復(fù)制(row-based replication, RBR),不記錄每條SQL語句的上下文信息,只記錄每行實際數(shù)據(jù)的變更 。

n 優(yōu)點: 準(zhǔn)確性強,能夠準(zhǔn)確復(fù)制數(shù)據(jù)的變更。

n 缺點: 產(chǎn)生的日志文件較大,從造成較大的網(wǎng)絡(luò)IO和磁盤IO。尤其是alter table的時候會讓日志暴漲。

lMIXED:基于STATMENT和ROW兩種模式的混合復(fù)制( mixed-based replication, MBR  ),默認(rèn)使用STATEMENT模式保存,STATEMENT模式無法復(fù)制的操作使用ROW模式。

n 優(yōu)點:準(zhǔn)確性強、文件大小適中。

n 缺點:有可能發(fā)生主從不一致的現(xiàn)象。

在MySQL中可以通過“show binlog events” 命令查看binlog日志的事件。如代碼段1  所示,這里通過上述命令查看“mysql-bin.000002”文件中的binlog 日志情況。

mysql> show binlog events in 'mysql-bin.000002';

代碼段1

如圖4所示:

什么是Redo log與Binlog

圖4 顯示binlog 日志內(nèi)容

通過上述命令展示對應(yīng)binlog 日志事件,從左到右展示如下:

  • Log_name:描述存放binlog日志的文件名字。

  • Pos:描述記日志的開始位置。

  • Event_type:描述時間類型,例如:查詢、插入等。

  • Server_id:對應(yīng)數(shù)據(jù)庫服務(wù)器的ID。

  • End_log_pos:日志結(jié)束的位置。

  • Info:執(zhí)行的SQL語句。

上面是查看日志的事件,這里也可以通過mysqlbinlog命令可以查看binlog的內(nèi)容。如代碼段2 所示,通過mysqlbinlog  命令查看mysql-bin.000002的內(nèi)容。

mysql> mysqlbinlog 'mysql-bin.000002';

代碼段2

如圖5所示:

什么是Redo log與Binlog

圖5 binlog 日志的內(nèi)容

我們將上述查看命令返回的結(jié)果截取其中一部分給大家講解,我們從上往下看:

  • “at 294”說明“事件”的起點,也就是從文件的第294字節(jié)開始。

  • “120330 17:54:46”表示事件發(fā)生的時間戳信息。

  • “end_log_pos 388 ”表示日志記錄結(jié)束的字節(jié)位置,也就是在文件的第388 字節(jié)截止。

  •  "exec_time=28",表示事件執(zhí)行花費的時間。

  •  “error_code=0”,表示錯誤代碼為0,也就是沒有錯誤。

  •  “server id 1”,表示服務(wù)器的標(biāo)識id。

需要注意的是binlog的事務(wù)提交,是一次性將事務(wù)進(jìn)行提交(一個事物包含一個或者多個SQL語句)。而redo  log可以在事務(wù)開始之后就開始逐步寫入磁盤。因此對于事務(wù)的提交,即便是較大的事務(wù),提交(commit)都是很快的,但是在開啟了binlog的情況下,對于較大事務(wù)的提交,可能會變得比較慢。因為binlog事務(wù)提交是一次性寫入。

6.Redo log與Binlog區(qū)別與合作

前面介紹了redo log 和 binlog,那么這里總結(jié)一下它們之間的區(qū)別如下表格。

 
Redo log
Binlog
適用場景
適用于崩潰恢復(fù)(crash-safe)。
適用于主從復(fù)制和數(shù)據(jù)恢復(fù)。
實現(xiàn)方式
 InnoDB 引擎層實現(xiàn)的,并不是所有引擎都有。
 Server 層實現(xiàn)的,所有引擎都可以使用 binlog 日志。
記錄方式
redo log 采用循環(huán)寫的方式記錄,當(dāng)寫到結(jié)尾時,會回到開頭循環(huán)寫日志。
Binlog通過追加的方式記錄,當(dāng)文件尺寸大于給配置值后,后續(xù)的日志會記錄到新的文件上。
文件大小
redo log 的大小是固定的。
 
Binl og 可通過配置參數(shù) max_binlog_size 設(shè)置每個binlog 文件的大小。

由 binlog 和 redo log 的區(qū)別可知:binlog 日志只用于歸檔,但僅僅依靠 binlog 是沒有 crash-safe 能力的。但只有  redo log 也不行,因為 redo log 是 InnoDB 特有的,且日志記錄落盤后會被覆蓋掉。因此需要 binlog 和 redo log  二者同時記錄,才能保證當(dāng)數(shù)據(jù)庫發(fā)生宕機(jī)重啟時,數(shù)據(jù)不會丟失。

那么如何讓兩個日志保持一致呢?

如圖5所示:

什么是Redo log與Binlog

圖5 redo log 和 binlog 事務(wù)保持一致

該圖沿用了圖1  的例子,稍微不同的是加入了一個步驟??吹骄G色虛線框的部分加入了寫入binlog的步驟。當(dāng)事務(wù)為prepare狀態(tài)的時候,在commit事務(wù)之間,會先將日志保存到binlog當(dāng)中,然后再提交給  Innodb中的redo log,最后完成commit的操作。

再聚焦于redo log 和 binlog 在提交成功和失敗兩種情況中的狀態(tài)變化。

如圖6 所示:

什么是Redo log與Binlog

圖6 redo log 和 binlog 狀態(tài)變遷圖(素材來源于互聯(lián)網(wǎng))

從上往下看,先看紅色線條的部分,當(dāng)寫入redo log并且事務(wù)狀態(tài)為prepare的時候,如果寫入成功直接寫入binlog,如果binlog  寫入也成功,redo log  狀態(tài)設(shè)置為commit。如果寫入binlog的時候失敗了,沿著紅色箭頭向上回滾此次事務(wù)。再回到最上面,看綠色箭頭的部分,如果寫入redo log  狀態(tài)為prepare 此時寫入失敗,不再寫入binlog,事務(wù)直接回滾。

可以看出這里為了保持兩個日志的一致性,使用了兩段提交。redo log和binlog是兩個獨立的邏輯,如果不用兩階段提交,要么就是先寫完redo  log再寫 binlog,或者先寫binlog再寫 redo log??纯催@兩種方式會有什么問題:

  • 先寫redo log后寫binlog。假設(shè)在redo log寫完,binlog還沒有寫完的時候,也就是說binlog  沒有事務(wù)中更新的語句。此時MySQL重啟并使用binlog來恢復(fù)數(shù)據(jù),由于之前更新的語句沒有保存數(shù)據(jù)庫就會少了一次更新,導(dǎo)致數(shù)據(jù)的不一致。

  • 先寫binlog后寫redo log。如果在binlog寫完之后服務(wù)器宕機(jī)了,由于redo  log還沒寫,也就是數(shù)據(jù)還沒有寫到數(shù)據(jù)庫中。但是binlog里面已經(jīng)記錄了,意思是把本來不應(yīng)該更新的數(shù)據(jù)記錄到更新里面了。此時MySQL數(shù)據(jù)庫重啟,就會把這條不該更新的數(shù)據(jù)更新到數(shù)據(jù)庫中,導(dǎo)致數(shù)據(jù)的不一致。

到此,關(guān)于“什么是Redo log與Binlog”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

本文題目:什么是Redolog與Binlog
網(wǎng)址分享:http://muchs.cn/article38/ipgopp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站面包屑導(dǎo)航、域名注冊品牌網(wǎng)站建設(shè)、網(wǎng)站排名、云服務(wù)器

廣告

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

h5響應(yīng)式網(wǎng)站建設(shè)