簡介 MySQL日誌之redo log和binlog

coldplay.xixi
發布: 2021-02-18 09:04:08
轉載
1842 人瀏覽過

簡介 MySQL日誌之redo log和binlog

#免費學習推薦:mysql影片教學

#前言

只要是接觸過MySQL的程式設計師,那麼或多或少都有聽過redo log(重做日誌)和binlog(歸檔日誌)。今天就來分享這兩個日誌的用處和差異。

簡單來說,redo log是InnoDB特有的日誌,如果使用的是其他儲存引擎,就沒有redo log,只有binlog。

binlog是MySQL的Server層的日誌,不管使用什麼儲存引擎,都會有binlog的存在。那麼,為什麼要有redo log和binlog呢?一個binlog不就可以全部解決了嗎?接下來我們就來詳細看redo log和binlog的差別吧。

redo log

在MySQL中,如果你要更新一個語句,需要帶更新條件,例如update T set name = 'god-jiang' where id=6,一般都是先查詢到id=6的語句,然後再進行更新操作。

如果更新的數量是100條,1000條甚至10000條的時候,每次更新都需要寫到磁碟上。然後磁碟也要找到對應的記錄,然後再更新,整個過程IO成本、查找成本太大,為了解決這個問題,MySQL的設計者採用了WAL技術來解決。 WAL全名為Write Ahead Logging,意思是先寫日誌,再寫磁碟。

具體操作:當有一筆記錄需要更新的時候,InnoDB引擎會先把記錄寫到redo log中,並更新內存,這個時候更新就算完成了。同時,InnoDB引擎會在適當的時候(系統空閒時),將這個操作記錄更新到磁碟中,而這個更新往往是在系統比較空閒的時候。

但是redo log的大小是固定的,不可能一直無限寫,讓我們看MySQL怎麼做到的吧。
簡介 MySQL日誌之redo log和binlog

write pos是目前記錄的位置,一邊寫一邊往後移動。 check point是目前要擦除的位置,也是往後移動且循環的,擦除記錄之前要把記錄更新到資料檔案中。

write pos與check point之間綠色的部分錶示可以記錄新的操作。如果write pos追上了check point,表示redo log滿了,這個時候就不能繼續執行新的操作,需要停下擦除一些記錄,並且把check point往後推進。

有了redo log,InnoDB可以保證即使資料庫發現異常重啟了,也不會遺失先前提交的事務,這個能力也被稱為crash-safe

以上就是redo log的介紹,看完了之後,你可以試著去問一下你公司的DBA同事,MySQL是否可以恢復到半個月內任意一秒的狀態,得到的答案肯定是可以的,這都要歸功於redo log的功勞。

binlog

從MySQL整體來看,其實分成兩層,一層是Server層,一層是儲存引擎層。上面聊到的redo log就是屬於InnoDB引擎特有的日誌,而binlog是屬於Server層的日誌,也稱為歸檔日誌。

redo log和binlog的區別

  • redo log是InnoDB引擎特有的;binlog是MySQL的Server層實現的,所有引擎都可以使用
  • redo log是實體日誌,記錄的是「在XXX資料頁上做了XXX修改」;binlog是邏輯日誌,記錄的是原始邏輯,其記錄是對應的SQL語句
  • redo log是循環寫的,空間一定會用完,需要write pos和check point搭配;binlog是追加寫,寫到一定大小會切換到下一個,並不會覆蓋以前的日誌

透過簡單的更新語句示範執行器和InnoDB引擎的內部流程

update T set name = 'god-jiang' where id = 6
登入後複製
  1. 透過執行器從InnoDB引擎取出id=6的記錄,然後載入到記憶體中
  2. 執行器拿到引擎回傳的結果,把name修改為'god-jiang',再重新呼叫儲存引擎的介面寫入新資料
  3. 引擎將新資料更新到記憶體中,同時將這個更新操作寫到redo log中,此時redo log處於prepare狀態
  4. 執行器產生這個操作的binlog,並把binlog寫到磁碟中
  5. 執行器呼叫引擎提交交易的接口,並且把剛剛寫入的redo log改為commit狀態,更新完成

#對應的流程圖
簡介 MySQL日誌之redo log和binlog

# #最後為什麼寫入redo log會處於prepare狀態,然後寫入binlog還要變成commit狀態?其實這個過程就叫做「兩階段提交」。

兩階段提交

其實redo log和binlog都可以用來表示交易的提交的狀態,而兩階段提交就是讓這兩個狀態保持邏輯上的一致。

舉例:update T set name = ‘god-jiang’ where id = 6沒有兩階段提交會發生什麼事?

先寫redo log後再寫binlog。假設寫完了redo log,binlog還沒寫完,這個時候MySQL異常重開機。因為redo log寫完了,恢復系統的時候name=‘god-jiang’。但是binlog沒有寫完,所以binlog沒有記錄這條語句,這個時候用binlog恢復資料的時候,恢復出來的name就是原來值,與redo log不同。

同理可得,先寫binlog後寫redo log也會發現兩個日誌復原的資料不同。這個不一致會導致線上出現主從不一致的情況。

總結

  • redo log可以保存crash-safe能力,可以保證MySQL異常重啟資料不遺失
  • binlog可以記錄對應的SQL語句,也可以保證MySQL異常重啟資料不會遺失
  • 提交交易的兩階段提交,可以維持資料邏輯一致性

##相關免費學習推薦:mysql資料庫(影片)

#

以上是簡介 MySQL日誌之redo log和binlog的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:csdn.net
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!