MySQL中有兩個重要的日誌模塊,分別是redo log(重作日誌)和binlog(歸檔日誌)。當咱們學習MySQL的時候,這兩部份內容是繞不開的,本文我未來詳細的介紹一下這兩個日誌模塊,它們在設計上有不少好玩的地方,一些思想也能夠在咱們工做中使用。數據庫
這裏咱們舉個例子,好比飯店掌櫃有個小黑板,專門用來記錄客人的賒帳記錄,若是賒帳的人很少,那麼他就能夠把顧客名字和帳目寫在小黑板上,若是賒帳的人不少,小黑板總會記不下的時候,這個時候掌櫃的就須要一個專門記錄賒帳的帳本。ide
若是有人又要賒帳的時候,掌櫃就有兩種作法:學習
一種是直接翻開帳本找到這個顧客的記錄,把此次賒的賬加上去或者劃掉。spa
另外一種就是先在黑板上記錄,等打烊或者不忙的時候再把帳本翻出來記錄在帳本上。插件
在生意紅火,櫃檯很忙的時候,掌櫃確定選擇第二種作法,由於第一種作法太麻煩了,每次都要翻閱帳本找到這我的的記錄,帳本有不少頁,找起來很是浪費時間,找到以後又要覈算,整個過程想一想都麻煩,相比之下,先在黑板上記錄就方便不少。設計
舉上邊這個例子是由於MySQL也有這個問題,若是每次更新操做都須要寫進磁盤,而後磁盤也要先找到對應的那條數據,而後更新,整個過程IO成本、查找成本很高,爲了解決這個問題,MySQL在設計的時候就用了相似飯店記帳的思路來提升更新效率。日誌
其實就是MySQL裏常說的WAL技術,WAL的全稱是Write-Ahead Logging,它的關鍵點就是先寫日誌,再寫磁盤,也就是先寫小黑板,等不忙的時候再寫帳本。orm
須要注意的是,先寫日誌的寫日誌,其實也是寫磁盤,只是寫日誌是順序磁盤,速度很是快。blog
具體的狀況就是,當有一條記錄須要更新的時候,InnoDB引擎就會先把記錄寫到redo log裏面,並更新內存,這個時候更新就算完成了,InnoDB引擎會在適當的時候,將這個操做記錄更新到磁盤裏面,而這個更新每每在系統比較空閒的時候作,就像打烊了之後寫帳本同樣。圖片
同時,將賒帳記錄在小黑板上,若是賒帳的很少,能夠等打烊了之後再記錄帳本,若是賒帳的特別多,小黑板寫滿了,這個時候掌櫃就要放下手上的活,先把黑板上的部分賒帳記錄更新到帳本上,而後將記錄好的信息從小黑板上擦掉,爲記錄新的賒帳騰出地方。
MySQL於這個也是相似的,InnoDB的redo log是固定大小的,好比咱們能夠分配一組4個文件,每一個文件的大小都是1GB,那麼總共就能夠記錄4GB的操做,從頭開始寫,寫到末尾就又從開頭循環寫,write pos是當前記錄的位置,一邊寫一邊後移,寫到3號文件末尾後就回到0號文件開頭,checkpoint是當前要擦除的位置,也是日後推移而且循環的,擦除記錄前要把記錄更新到數據庫中。
write pos和checkpoint之間的是「小黑板」上還空着的部分,能夠用來記錄更新的操做,若是write pos追上了checkpoint,表示「黑板「寫滿了,這個時候不能再執行新的更新,得停下先擦掉一些記錄,把check point推動一下。
redo log是InnoDB引擎所特有的,因此咱們在使用InnoDB引擎建立表時,若是數據庫發生異常重啓,以前提交的記錄都不會丟失,InnoDB就是由於有了redo log纔有了crash-safe的能力。
crash-safe簡單來說,就比如飯店掌櫃的把賒帳記錄在小黑板上或者帳本上,以後飯店忽然停業了幾天,從新開業後,依然能夠經過小黑板和帳本上的數據覈算賒帳帳目,
上一篇文中,咱們在說MySQL總體來看,分爲兩部分,一部是Server層,主要作的是MySQL功能層面的事情,還有一部分是引擎層,負責存儲相關的具體事情。上邊說的redo log是InnoDB引擎特有的日誌,而Server層的日誌稱爲binlog。
這個地方爲何要有兩份日誌,還要從最開始的時候MySQL中沒有InnoDB引擎提及,當時MySQL自帶的引擎是MyISAM,可是M有ISAM沒有crash-safe的能力,binlog日誌只能用來歸檔,而InnoDB是第三方公司以插件的形式引入MySQL的,由於只依靠binlog是沒有crash-safe的能力,因此要使用InnoDB的日誌系統redo log。
兩種日誌主要的不一樣:
redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 層實現的,全部引擎均可以使用
redo log 是物理日誌,記錄的是「在某個數據頁上作了什麼修改」;binlog 是邏輯日誌,記錄的是這個語句的原始邏輯,好比「給 ID=2 這一行的 c 字段加 1 」
redo log 是循環寫的,空間固定會用完;binlog 是能夠追加寫入的。「追加寫」是指 binlog 文件寫到必定大小後會切換到下一個,並不會覆蓋之前的日誌。