Mysql底層之binlog日誌瞭解

Mysql底層知識要懂哪些?

主要分爲兩個部分

  • binlog的相關概念

  • 怎麼解析binlog

可以分上下兩個部分來敘述。上部分講述binlog的相關概念這部分的知識,我們不需要像運維懂的那麼深,我會列舉一些常見概念和常見配置,大家匆匆掃一眼,有個概念即可。這樣大家以後和運維討論問題的時候,也不會一臉的懵逼。正所謂

懵逼樹上懵逼果,懵逼樹下你和我。   

懵逼樹前排排坐,一人一個懵逼果。

博主一個人默默的把懵逼果收走獨享就好,各位讀者還是懂點基本概念,以後方便和運維溝通。下半部分講怎麼解析binlog

另外,這篇文章是給研發大大看的,可能有些概念我理解的也不對,請運維大大輕噴。

正文

記得我的"一個定義,兩個誤解,三個用途,四個常識"

一個定義

先從定義開始講起

binlog是記錄所有數據庫表結構變更(例如CREATE、ALTER TABLE…)以及表數據修改(INSERT、UPDATE、DELETE…)的二進制日誌

binlog不會記錄SELECT和SHOW這類操作,因爲這類操作對數據本身並沒有修改,但你可以通過查詢通用日誌來查看MySQL執行過的所有語句。

多說一句,如果update操作沒有造成數據變化,也是會記入binlog

兩個誤解

誤解一:binlog只是一類記錄操作內容的日誌文件
因爲binlog稱之爲二進制日誌,很多研發會把這個二進制日誌和我們平時在代碼裏寫的代碼日誌聯繫在一起。因爲我們的代碼日誌,只有一類記錄操作容的文件,並不包含索引文件。然而,這個二進制日誌包括兩類文件

  • 索引文件(文件名後綴爲.index)用於記錄哪些日誌文件正在被使用

  • 日誌文件(文件名後綴爲.00000*)記錄數據庫所有的DDL和DML(除了數據查詢語句)語句事件

這麼說可能還有一點抽象,假設文件my.cnf中有這麼三條配置

log_bin:on 打開binlog日誌

log_bin_basename:bin文件路徑及名前綴(/var/log/mysql/mysql-bin)

log_bin_index:bin文件index(/var/log/mysql/mysql-bin.index)

那麼你會在文件目錄/var/log/mysql/下面發現兩個文件mysql-bin.000001mysql-bin.index
mysql-bin.index就是我們所說的索引文件,打開瞅瞅,內容是下面這樣,記錄哪些文件是日誌文件

./mysql-bin.000001

那麼說到日誌文件。在innodb裏其實又可以分爲兩部分,一部分在緩存中,一部分在磁盤上。這裏業內有一個詞叫做刷盤,就是指將緩存中的日誌刷到磁盤上。跟刷盤有關的參數有兩個個:sync_binlogbinlog_cache_size。這兩個參數作用如下

binlog_cache_size: 二進制日誌緩存部分的大小,默認值32k

sync_binlog=[N]: 表示寫緩衝多少次,刷一次盤,默認值爲0

注意兩點:

  • (1)binlog_cache_size設過大,會造成內存浪費。binlog_cache_size設置過小,會頻繁將緩衝日誌寫入臨時文件。具體怎麼設,有興趣自行查詢,我覺得研發大大根本沒機會去設這個值的,瞭解即可。

  • (2)sync_binlog=0:表示刷新binlog時間點由操作系統自身來決定,操作系統自身會每隔一段時間就會刷新緩存數據到磁盤,這個性能最好。sync_binlog=1,代表每次事務提交時就會刷新binlog到磁盤。sync_binlog=N,代表每N個事務提交會進行一次binlog刷新。

另外,這裏存在一個一致性問題,sync_binlog=N,數據庫在操作系統宕機的時候,可能數據並沒有同步到磁盤,於是再次重啓數據庫,會帶來數據丟失問題。 
sync_binlog=1,事務在Commit的時候,數據寫入binlog,但是還沒寫入事務日誌(redo logundo log)。此時宕機,重啓數據庫,數據被回滾。但是binlog裏已經記錄,這裏存在不一致問題。這個事務日誌和binlog一致性的問題,大家可以查詢mysql的內部XA協議,該協議就是解決這個一致性問題的。

誤解二:binlog是InnoDb獨有的
binlog是以事件形式記錄的,這句話通俗點說,就是binlog的內容都是一個個的事件。這塊具體的我會在下一篇講,這篇記住binlog的內容就是一個個事件就行。
注意了,這裏的用詞,是一個個事件,而不是事務。大家應該知道Innodbmysiam最顯著的區別就是一個支持事務,一個不支持事務
因此你可以說,binlog是基於事務來記錄二進制日誌,比如sync_binlog=1,每提交一次事務,就寫入binlog。你卻不能說binlog是事務日誌,binlog不僅記錄innodb日誌,在myisam中,也一樣存在binlog

三個用途

這三個用途,出自《MySQL技術內幕 InnoDB存儲引擎》一書,分別爲恢復複製審計。這三個用途,研發大大們瞭解一下即可,比如數據恢復,你碰到同事刪庫的機會實在太少。假如真的有同事捨己爲人,冒着離職的風險給你提供做數據恢復的機會,大把運維工程師待命在那,輪不到你的。所以,這三個功能瞭解即可。

恢復:這裏網上有大把的文章指導你,如何利用binlog日誌恢復數據庫數據。如果你真的覺得自己很有時間,就自己去創建個庫,然後刪了,再去恢復一下數據,練練手吧。

複製: 如圖所示(圖片不是自己畫的,偷懶了)

主庫有一個log dump線程,將binlog傳給從庫
從庫有兩個線程,一個I/O線程,一個SQL線程,I/O線程讀取主庫傳過來的binlog內容並寫入到relay log,SQL線程從relay log裏面讀取內容,寫入從庫的數據庫。

審計:用戶可以通過二進制日誌中的信息來進行審計,判斷是否有對數據庫進行注入攻擊。

四個常識

常識一:binlog常見格式
這塊知識我用一個表格來表示,沒必要囉嗦一大堆。

業內目前推薦使用的是row模式,準確性高,雖然說文件大,但是現在有SSD和萬兆光纖網絡,這些磁盤IO和網絡IO都是可以接受的。
那麼,大家一定想問,爲什麼不推薦使用mixed模式,理由如下
假設master有兩條記錄,而slave只有一條記錄。

當在master上更新一條從庫不存在的記錄時,也就是id=2的記錄,你會發現master是可以執行成功的。而slave拿到這個SQL後,也會照常執行,不報任何異常,只是更新操作不影響行數而已。並且你執行命令show slave status,查看輸出,你會發現沒有異常。但是,如果你是row模式,由於這行根本不存在,是會報1062錯誤的。

常識二:怎查看binlog
binlog本身是一類二進制文件。二進制文件更省空間,寫入速度更快,是無法直接打開來查看的。

因此mysql提供了命令mysqlbinlog進行查看
一般的statement格式的二進制文件,用下面命令就可以

mysqlbinlog mysql-bin.000001 

如果是row格式,加上-v或者-vv參數就行,如

mysqlbinlog -vv mysql-bin.000001 

常識三:怎麼刪binlog
binlog的方法很多,有三種是常見的
(1) 使用reset master,該命令將會刪除所有日誌,並讓日誌文件重新從000001開始
(2) 使用命令

PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr }

例如

purge master logs to "binlog_name.00000X" 

將會清空00000X之前的所有日誌文件.
(3) 使用expire_logs_days=N選項指定過了多少天日誌自動過期清空

常識四:binlog常見參數
常見參數,列舉如下,有個印象就好。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章