天天看點

【資料庫】binlog、redo log、undo log掃盲

一、什麼是binlog

​binlog​

​​其實在日常的開發中是聽得很多的,因為很多時候資料的更新就依賴着​

​binlog​

​。

舉個很簡單的例子:我們的資料是儲存在資料庫裡邊的嘛,現在我們對某個商品的某個字段的内容改了(資料庫變更),而使用者檢索的出來資料是走搜尋引擎的。為了讓使用者能搜到最新的資料,我們需要把引擎的資料也改掉。

一句話:資料庫的變更,搜尋引擎的資料也需要變更。

于是,我們就會監聽​

​binlog​

​​的變更,如果​

​binlog​

​有變更了,那我們就需要将變更寫到對應的資料源。

什麼是​

​binlog​

​?

​binlog​

​​記錄了資料庫表結構和表資料變更,比如​

​update/delete/insert/truncate/create​

​​。它不會記錄​

​select​

​(因為這沒有對表沒有進行變更)

​binlog​

​長什麼樣?

​binlog​

​​我們可以簡單了解為:存儲着每條變更的​

​SQL​

​語句(當然從下面的圖看來看,不止SQL,還有XID「事務Id」等等)

【資料庫】binlog、redo log、undo log掃盲

​binlog​

​一般用來做什麼

主要有兩個作用:複制和恢複資料

  • MySQL在公司使用的時候往往都是一主多從結構的,從伺服器需要與主伺服器的資料保持一緻,這就是通過​

    ​binlog​

    ​來實作的
  • 資料庫的資料被幹掉了,我們可以通過​

    ​binlog​

    ​來對資料進行恢複。

因為​

​binlog​

​​記錄了資料庫表的變更,是以我們可以用​

​binlog​

​進行複制(主從複制)和恢複資料。

二、什麼是redo log

假設我們有一條sql語句:

update user_table set name='java3y' where id = '3'      

MySQL執行這條SQL語句,肯定是先把​

​id=3​

​​的這條記錄查出來,然後将​

​name​

​字段給改掉。這沒問題吧?

實際上Mysql的基本存儲結構是頁(記錄都存在頁裡邊),是以MySQL是先把這條記錄所在的頁找到,然後把該頁加載到記憶體中,将對應記錄進行修改。

現在就可能存在一個問題:如果在記憶體中把資料改了,還沒來得及落磁盤,而此時的資料庫挂了怎麼辦?顯然這次更改就丢了。

【資料庫】binlog、redo log、undo log掃盲

如果每個請求都需要将資料立馬落磁盤之後,那速度會很慢,MySQL可能也頂不住。是以MySQL是怎麼做的呢?

MySQL引入了​

​redo log​

​​,記憶體寫完了,然後會寫一份​

​redo log​

​​,這份​

​redo log​

​記載着這次在某個頁上做了什麼修改。

【資料庫】binlog、redo log、undo log掃盲

其實寫​

​redo log​

​​的時候,也會有​

​buffer​

​​,是先寫​

​buffer​

​​,再真正落到磁盤中的。至于從​

​buffer​

​什麼時候落磁盤,會有配置供我們配置。

【資料庫】binlog、redo log、undo log掃盲

寫​

​redo log​

​​也是需要寫磁盤的,但它的好處就是​

​順序IO​

​(我們都知道順序IO比随機IO快非常多)。

是以,​

​redo log​

​​的存在為了:當我們修改的時候,寫完記憶體了,但資料還沒真正寫到磁盤的時候。此時我們的資料庫挂了,我們可以根據​

​redo log​

​​來對資料進行恢複。因為​

​redo log​

​是順序IO,是以寫入的速度很快,并且​

​redo log​

​記載的是實體變化(xxxx頁做了xxx修改),檔案的體積很小,恢複速度很快。

三、binlog和redo log

看到這裡,你可能會想:​

​binlog​

​​和​

​redo log​

​ 這倆也太像了吧,都是用作”恢複“的。

其實他倆除了"恢複"這塊是相似的,很多都不一樣,下面看我列一下。

存儲的内容

​binlog​

​​記載的是​

​update/delete/insert​

​​這樣的SQL語句,而​

​redo log​

​記載的是實體修改的内容(xxxx頁修改了xxx)。

是以在搜尋資料的時候會有這樣的說法:​

​redo log​

​ 記錄的是資料的實體變化,​

​binlog​

​ 記錄的是資料的邏輯變化

功能

​redo log​

​的作用是為持久化而生的。寫完記憶體,如果資料庫挂了,那我們可以通過​

​redo log​

​​來恢複記憶體還沒來得及刷到磁盤的資料,将​

​redo log​

​加載到記憶體裡邊,那記憶體就能恢複到挂掉之前的資料了。

​binlog​

​的作用是複制和恢複而生的。

  • 主從伺服器需要保持資料的一緻性,通過​

    ​binlog​

    ​來同步資料。
  • 如果整個資料庫的資料都被删除了,​

    ​binlog​

    ​存儲着所有的資料變更情況,那麼可以通過​

    ​binlog​

    ​來對資料進行恢複。

又看到這裡,你會想:”如果整個資料庫的資料都被删除了,那我可以用​

​redo log​

​的記錄來恢複嗎?“不能

因為功能的不同,​

​redo log​

​​ 存儲的是實體資料的變更,如果我們記憶體的資料已經刷到了磁盤了,那​

​redo log​

​​的資料就無效了。是以​

​redo log​

​不會存儲着曆史所有資料的變更,檔案的内容會被覆寫的。

binlog和redo log 寫入的細節

​redo log​

​是MySQL的InnoDB引擎所産生的。

​binlog​

​無論MySQL用什麼引擎,都會有的。

InnoDB是有事務的,事務的四大特性之一:持久性就是靠​

​redo log​

​​來實作的(如果寫入記憶體成功,但資料還沒真正刷到磁盤,如果此時的資料庫挂了,我們可以靠​

​redo log​

​來恢複記憶體的資料,這就實作了持久性)。

上面也提到,在修改的資料的時候,​

​binlog​

​​會記載着變更的類容,​

​redo log​

​也會記載着變更的内容。(隻不過一個存儲的是實體變化,一個存儲的是邏輯變化)。那他們的寫入順序是什麼樣的呢?

​redo log​

​事務開始的時候,就開始記錄每次的變更資訊,而​

​binlog​

​是在事務送出的時候才記錄。

于是新有的問題又出現了:我寫其中的某一個​

​log​

​​,失敗了,那會怎麼辦?現在我們的前提是先寫​

​redo log​

​​,再寫​

​binlog​

​,我們來看看:

  • 如果寫​

    ​redo log​

    ​失敗了,那我們就認為這次事務有問題,復原,不再寫​

    ​binlog​

    ​。
  • 如果寫​

    ​redo log​

    ​成功了,寫​

    ​binlog​

    ​,寫​

    ​binlog​

    ​寫一半了,但失敗了怎麼辦?我們還是會對這次的事務復原,将無效的​

    ​binlog​

    ​給删除(因為​

    ​binlog​

    ​會影響從庫的資料,是以需要做删除操作)
  • 如果寫​

    ​redo log​

    ​和​

    ​binlog​

    ​都成功了,那這次算是事務才會真正成功。

簡單來說:MySQL需要保證​

​redo log​

​​和​

​binlog​

​的資料是一緻的,如果不一緻,那就亂套了。

  • 如果​

    ​redo log​

    ​寫失敗了,而​

    ​binlog​

    ​寫成功了。那假設記憶體的資料還沒來得及落磁盤,機器就挂掉了。那主從伺服器的資料就不一緻了。(從伺服器通過​

    ​binlog​

    ​得到最新的資料,而主伺服器由于​

    ​redo log​

    ​沒有記載,沒法恢複資料)
  • 如果​

    ​redo log​

    ​寫成功了,而​

    ​binlog​

    ​寫失敗了。那從伺服器就拿不到最新的資料了。

MySQL通過兩階段送出來保證​

​redo log​

​​和​

​binlog​

​的資料是一緻的。

【資料庫】binlog、redo log、undo log掃盲

過程:

  • 階段1:InnoDB​

    ​redo log​

    ​ 寫盤,InnoDB 事務進入 ​

    ​prepare​

    ​ 狀态
  • 階段2:​

    ​binlog​

    ​ 寫盤,InooDB 事務進入 ​

    ​commit​

    ​ 狀态
  • 每個事務​

    ​binlog​

    ​的末尾,會記錄一個 ​

    ​XID event​

    ​,标志着事務是否送出成功,也就是說,恢複過程中,​

    ​binlog​

    ​ 最後一個 XID event 之後的内容都應該被 purge。
【資料庫】binlog、redo log、undo log掃盲

四、什麼是undo log

​undo log​

​有什麼用?

​undo log​

​主要有兩個作用:復原和多版本控制(MVCC)

在資料修改的時候,不僅記錄了​

​redo log​

​​,還記錄​

​undo log​

​​,如果因為某些原因導緻事務失敗或復原了,可以用​

​undo log​

​進行復原