這篇文章主要介紹“什么是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)還提供了保定免費(fèi)建站歡迎大家使用!
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ù)的時候,運(yùn)行記錄的操作那么這些沒有來得及存儲的數(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 所示:
圖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 也運(yùn)行在這一層。
跟隨圖中的序號來看看redo log 的運(yùn)行流程。
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所示:
圖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所示:
圖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ù)就是增強(qiáng)數(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)確性強(qiáng),能夠準(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)確性強(qiáng)、文件大小適中。
n 缺點:有可能發(fā)生主從不一致的現(xiàn)象。
在MySQL中可以通過“show binlog events” 命令查看binlog日志的事件。如代碼段1 所示,這里通過上述命令查看“mysql-bin.000002”文件中的binlog 日志情況。
mysql> show binlog events in 'mysql-bin.000002';
代碼段1
如圖4所示:
圖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所示:
圖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í)行花費(fèi)的時間。
“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ū)別如下表格。
由 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所示:
圖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 所示:
圖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://jinyejixie.com/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)