溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

什么是Redo log和Binlog

發(fā)布時間:2021-10-22 14:52:18 來源:億速云 閱讀:138 作者:iii 欄目:數(shù)據(jù)庫

本篇內(nèi)容介紹了“什么是Redo log和Binlog”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

redo log

為什么要有 redo log ?

我們可以這樣想,如果沒有 redo log 的話, MySQL 是如何進行工作的 查詢還好說,畢竟只是查詢一下記錄而已,并沒有對數(shù)據(jù)進行更改

那如果是增加和更新操作呢?現(xiàn)在一條 update 語句過來,后面是不是一定會有限定條件,就比如現(xiàn)在要更新一條記錄,把 A 的銀行卡余額更新到 1k  ,那這條語句是不是應(yīng)該來個限定條件,類似 where userName = 'A',也就是說,一般 update  操作都伴隨著查詢的操作,得先找到這個人,然后再進行更新操作對吧

如果數(shù)據(jù)量比較小還好,很快就能找到并且更新完畢

但是如果數(shù)據(jù)量比較大,里面有一億條數(shù)據(jù),怎么辦?而且更新操作肯定是要寫到磁盤上去的,那這中間的 IO 成本呢?如果我有好幾十條 update  語句先后更新呢?這樣想的話,你就能想到,就這些操作,成本就高的不行,那能不能降低一下這些成本呢?

這就是 redo log 的作用

就是當(dāng)有一條記錄更新的時候, InnoDB 引擎就會先把記錄寫到 redo log 里面去,同時更新內(nèi)存,這樣就算是更新這條數(shù)據(jù)成功了

但是此時,它并沒有更新到磁盤上去對吧?別擔(dān)心, InnoDB 會在恰當(dāng)?shù)臅r候,把這條及記錄更新到磁盤上去

這樣的思想或者技術(shù),有個專有名詞: WAL 技術(shù),也就是 WriteAheadLogging ,核心就是先寫日志,再寫磁盤

同樣,這里面有個問題

redo log 不能一直寫吧?如果更新操作一直寫入到 redo log 中的話,不限制大小的話,可能服務(wù)器上的存儲空間都被 redo log  給占滿了

所以 InnoDB 的 redo log 是固定大小的,比如我們配置了一組 4 個文件,每個文件大小是 1GB ,那么它的操作可能就會這樣:

什么是Redo log和Binlog

能夠看到,主要就是 write pos 和 checkpoint , write pos  比較好理解,它就是當(dāng)前記錄的位置,有需要記錄的操作就從當(dāng)前位置向后移,等把 ib_logfile_3 寫完之后,就回到 ib_logfile_0  文件開頭繼續(xù)寫

checkpoint 是當(dāng)前要擦除的位置,就是 InnoDB  引擎不是會在恰當(dāng)?shù)臅r候,將這些操作進行持久化,更新到磁盤上去,那持久化之后的數(shù)據(jù)是不是就可以擦除了

write pos 和 checkpoint 之間的部分就是可以用來記錄操作的部分,那么如果 write pos 和 checkpoint  相遇了怎么辦?相遇了是不是說明這個時候分配的 redo log 大小用完了,那這時候就不能再進行更新操作了,必須停下來處理一下,將 checkpoint  往前推推才行

就是因為有了 redo log ,所以 InnoDB 才可以保證即使數(shù)據(jù)庫發(fā)生了異常重啟,也沒關(guān)系,之前提交的記錄都還在,只需要根據(jù) redo log  里面的記錄進行相應(yīng)恢復(fù)就可以了

所以如果你和 DBA 比較熟的話,可以問問,咱們的 MySQL 是不是可以恢復(fù)到半個月內(nèi)任意一秒的狀態(tài),如果對方回答是,別懷疑,他真的不是在吹牛逼

binlog

binlog 是 MySQL Server 層的記錄日志,這塊舉個例子來說吧

在說之前,我們要明白 redo log 和 binlog 的區(qū)別:

  • redo log 是 InnoDB 引擎特有的, binlog 是 MySQL 的 Server 層實現(xiàn)的,所有的引擎都是可以的

  • redo log 是物理日志,記錄的是"在 XXX 頁上做了 XXX 修改"; binlog 是邏輯日志,比如" 給 id = 2 這一行的 c 字段加  1"

  • redo log 是有固定大小的,所以它的空間會用完,如果用完的話,一定要進行一些寫入磁盤的操作才可以繼續(xù); binlog 是可以追加寫入的,也就是  binlog 沒有空間的概念,一直寫就行了

理解了它們之間區(qū)別之后,我們拿一個更新操作來舉例

我現(xiàn)在要給 id = 2 這一行的 c 字段加 1,到 MySQL 層面,它是如何去做的呢?

首先,會先找到這條 id = 2 的數(shù)據(jù),然后找到 c 字段進行加 1 操作,這個時候,引擎會將這行數(shù)據(jù)更新到內(nèi)存中,同時把這個更新操作記錄到 redo  log 里面,這個時候 redo log 處于 prepare 狀態(tài),隨后執(zhí)行器生成這個操作的 binlog ,并且把 binlog  寫入到磁盤完成之后,執(zhí)行器調(diào)用引擎的提交事務(wù)接口,引擎把剛剛寫入的 redo log 從 prepare 狀態(tài)改成 commit  狀態(tài),這樣更新操作才算完成

兩階段提交

在上面的描述中,你能發(fā)現(xiàn) redo log 竟然是先 prepare 狀態(tài),等 binlog 寫完之后,才是 commit  狀態(tài),這種方式就叫"兩階段提交"

為什么會有這種方式呢?

redo log 和 binlog 都可以用于表示事務(wù)的提交狀態(tài),而兩階段提交就是讓這兩個狀態(tài)保持邏輯上的一致

可以假設(shè)一下,如果不采用這種方式,而是就先寫 redo log ,再寫 binlog ,會怎樣?如果在寫 binlog 時,發(fā)生了異常,更新操作已經(jīng)到  redo log 中了,但是此時 binlog 并沒有進行更新,是不是出現(xiàn)了數(shù)據(jù)不一致?

先寫 binlog 再寫 redo log 也是一樣的道理

所以,在寫時,先讓 redo log 處于 prepare 狀態(tài),等 binlog 寫完之后,再讓 redo log 處于 commit  狀態(tài),這樣就保持了邏輯上的一致

“什么是Redo log和Binlog”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

向AI問一下細節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI