聊聊 binlog 是什麼?
前言
上篇阿星詳細聊了 redo log
(重做日誌),但是在MySQL
資料庫中還有一種二進位制日誌叫binlog
(歸檔日誌)。
redo log
它是物理日誌,記錄內容是“在某個資料頁上做了什麼修改”,屬於InnoDB
儲存引擎。
而binlog
是邏輯日誌,記錄內容是語句的原始邏輯,類似於“給ID=2這一行的c欄位加1”,屬於MySQL Server
層。
binlog
不管用什麼儲存引擎,只要發生了表資料更新,都會產生binlog
日誌。
那binlog
到底是用來幹嘛的?
可以說MySQL
資料庫的資料備份、主備、主主、主從都離不開binlog
,需要依靠binlog
來同步資料,保證資料一致性。
binlog
會記錄所有涉及更新資料的邏輯操作,並且是順序寫。
記錄格式
binlog
日誌有三種格式,可以通過binlog_format
引數指定。
- statement
- row
- mixed
指定statement
,記錄的內容是SQL
語句原文,比如執行一條update T set update_time=now() where id=1
,記錄的內容如下。
同步資料時,會執行記錄的SQL
語句,但是有個問題,update_time=now()
這裡會獲取當前系統時間,直接執行會導致與原庫的資料不一致。
為了解決這種問題,我們需要指定為row
,記錄的內容不再是簡單的SQL
語句了,還包含操作的具體資料,記錄內容如下。
row
格式記錄的內容看不到詳細資訊,要通過mysqlbinlog
工具解析出來。
update_time=now()
變成了具體的時間update_time=1627112756247
,條件後面的@1、@2、@3都是該行資料第1個~3個欄位的原始值(假設這張表只有3個欄位)。
這樣就能保證同步資料的一致性,通常情況下都是指定為row
,這樣可以為資料庫的恢復與同步帶來更好的可靠性。
但是這種格式,需要更大的容量來記錄,比較佔用空間,恢復與同步時會更消耗IO
資源,影響執行速度。
所以就有了一種折中的方案,指定為mixed
,記錄的內容是前兩者的混合。
MySQL
會判斷這條SQL
語句是否可能引起資料不一致,如果是,就用row
格式,否則就用statement
格式。
寫入機制
binlog
的寫入時機也非常簡單,事務執行過程中,先把日誌寫到binlog cache
,事務提交的時候,再把binlog cache
寫到binlog
檔案中。
因為一個事務的binlog
不能被拆開,無論這個事務多大,也要確保一次性寫入,所以系統會給每個執行緒分配一個塊記憶體作為binlog cache
。
我們可以通過binlog_cache_size
引數控制單個執行緒binlog cache大小,如果儲存內容超過了這個引數,就要暫存到磁碟(Swap
)。
binlog
日誌刷盤流程如下
- 上圖的write,是指把日誌寫入到檔案系統的page cache,並沒有把資料持久化到磁碟,所以速度比較快
- 上圖的fsync,才是將資料持久化到磁碟的操作
write
和fsync
的時機,可以由引數sync_binlog
控制,預設是0
。
為0
的時候,表示每次提交事務都只write
,由系統自行判斷什麼時候執行fsync
。
雖然效能得到提升,但是機器宕機,page cache
裡面的binglog會丟失。
為了安全起見,可以設定為1
,表示每次提交事務都會執行fsync
,就如同binlog日誌刷盤流程一樣。
最後還有一種折中方式,可以設定為N(N>1)
,表示每次提交事務都write
,但累積N
個事務後才fsync
。
在出現IO
瓶頸的場景裡,將sync_binlog
設定成一個比較大的值,可以提升效能。
同樣的,如果機器宕機,會丟失最近N
個事務的binlog
日誌。
福利
MySQL好文推薦
關於我
阿星是一個熱愛技術的 Java
程式猿,公眾號 「程式猿阿星」 定期分享有趣有料的精品原創文章!
咱們都是自家人,點不點贊,在不在看什麼的,沒關係的,看開心了就好。
在看,點贊什麼的,我不是特別在意,真的,真的,別不信啊。
不三連也真的沒關係。
大夥們不要在意啊。
我是阿星,我們下期見
- 位元組面試:面試官竟然問了Java 強引用,弱引用,軟引用。
- 阿里面試官:談談對Redis雜湊表的理解
- 如果這題都不會面試官還會繼續問我 JVM 嘛:如何判斷物件是否可回收
- 一款功能強大的Docker容器實時指標監控
- kafka三高架構設計剖析
- 乾貨 | 一文搞懂Linux系統下程序
- InnoDB原理篇:Change Buffer是如何提升索引效能的?
- 充電即是真理,利用雙休學起來
- InnoDB原理篇:如何用好索引
- 一文帶你瞭解輕量性日誌採集器Beats的使用
- InnoDB原理篇:為什麼使用索引會變快?
- InnoDB原理篇:聊聊資料頁變成索引這件事
- InnoDB原理篇:Buffer Pool 為了讓 MySQL 變快都做了什麼?
- 面試官太難伺候?一個try-catch問出這麼多花樣
- Java集合經典26問!
- SpringBoot專案啟動時增加自定義Banner
- 位元組二面:棧和佇列互相實現
- 牛人筆記推薦
- 一個案例搞懂原碼、反碼、補碼,不懂得請看過來
- 騰訊二面:多數元素