一、嘮嗑
文章公號 首發!連載中!關注微信公號回覆:“抽獎” 還可參加抽?活動
算上這一篇文章,白日夢的MySQL專題已經寫了18篇了。前面的文章中有跟大家分享過undo log、redo log、以及接下來要有幾篇文章跟大家分享bin log。
前一陣跟一個同學嘮嗑,說到了MySQL的這幾個日誌。那同學就感覺這幾個日誌挺深奧的挺難懂的。其實不用這麼嚇唬自己。
就比如說這幾個日誌,你有沒有想過MySQL為啥要寫日誌呢?寫日誌就得有磁碟IO、不寫不香嗎?速度、效能還會變快。其實不然,MySQL會寫日誌,是因為記錄下的日誌能賦予MySQL一定的能力。
比如undo log讓mysql有回滾事物的能力,redo log讓mysql有崩潰恢復的能力,以及我們現在說的bin log讓MySQL有搭建叢集、資料備份、恢復資料的能力。
那你說,我不想讓MySQL記錄那些日誌不行嗎?肯定行啊!甚至預設情況下,MySQL都不會主動為你記錄bin log ,但是話說回來,你不讓它寫那些日誌,它就沒有相應的能力給你用。是吧!所以綜合來說,寫日誌還是很香的。
知道了這些,再去學相關的知識點是不是目的性很強了呢?關於undo log、redo log白日夢前面已經和大家分享過了,知無不言的那種分享哈,如果你又有感覺了,歡迎關注我然後去翻看。
對於大部分研發同學來說,肯定聽說過bin log。然後卻不一定知道binlog在哪裡?誰寫的?怎麼配置binlog?以及binlog有啥用。所以接下來的幾篇文章,我們一起看看binlog的二三事,讓你更好的理解binlog。
二、什麼是bin log?
bin log是MySQL的二進位制日誌檔案,翻譯成中文名反到是感覺怪怪的。所以說下面直接稱他為binlog。
我們都知道MySQL分為兩大部分。上層是MySQL-Server,下層是可插拔的儲存引擎。
binlog就是由MySQL的Server層產生。
三、它在哪裡?
binlog存放的位置由datadir引數控制。
你可以通過下面的方式檢視到它
知道了binlog具體在哪裡,你就可以看一眼,如下
目錄下有兩種檔案:mysql-bin.0000XX 和 mysql-bin.index
前者儲存著對MySQL更改的邏輯
而後者長下面這樣,估計你一看就懂了~
四、bin log的相關配置
一般關於binlog的配置都寫在MySQL的配置檔案中: my.cnf , 以方便啟動mysql時直接讓這些配置生效
作為了解,你可以大概摟一眼binlog的配置項
[mysqld]
# binlog相關配置
# 指定binlog日誌儲存的位置
datadir = /home/mysql/mysql/var
# 規範binlog的命名為 mysql-bin.0000XX
# 如果加這行配置,binlog檔名為主機名
log-bin = mysql-bin
# 索引當前所有的binlog
log-bin-index = mysql-bin.index
# 最大的大小
max_binlog_size = 1G
# binlog的sync時機
sync-binlog = 1
# binlog的格式
binlog-format = ROW
# 保留七天的binlog
expire_logs_days = 7
五、binlog 有啥用?
如果說redolog中記錄的是偏向物理層面的記錄,如:對哪個資料頁的那個記錄做了什麼修改。
那麼binlog中記錄的是偏向邏輯層面的記錄:如:對xxx表中的id=yyy的行做做了什麼修改,更改後的值是什麼。
binlog不會記錄你的 select 、show這類的操作。
你可以在query log中找到曾經執行過的諸如select、show這種僅查詢的SQL。
常見的binlog有如下的作用。
- delete沒加where條件?不慌!binlog可以幫你恢復資料
- 搭建一套一主兩從的MySQL叢集,binlog幫你完成主從的資料同步。
- 審計,通過分析binlog可以排查是否存在SQL隱碼攻擊。
但是你知道嗎?
預設binlog是不開啟的。因為開啟binlog後會稍微降低一點mysql的效能(1%)。
但是開啟binlog後你就可以搭建MySQL叢集,排查SQL隱碼攻擊,恢復誤刪的資料。所以線上的MySQL叢集都是開啟binlog的,是不是感覺開啟binlog很有保障!很香呢?
六、超有用的引數 sql_log_bin
跟大家分享一種線上實際存在的場景,你就能知道該引數的妙用了。
比如你線上使用的是一個一主兩從的MySQL叢集,然後有一個活動來了,你需要給線上某庫的某資料表新增一列,並且這個表裡面的數量非常之龐大。
新增一列是需要獲取表鎖的,並且龐大的資料量讓你alter table異常緩慢,在獲取表鎖的過程中,正常的DML也會被阻塞。這時你就得考慮無損DDL,比如golang的ghost(怎麼做的無損ddl原理我後門的文章會寫的,本篇不展開)。
ghost工具的特點是,它需要預執行一些SQL目的是先校驗一下你的叢集符不符合它的要求,為了不對線上產生影響,你肯定會想把這些預執行的sql放到從庫上執行。放在從庫上執行固然沒問題,但是你執行的sql會產生bin log。出現新的GTID(後面講MySQL叢集時會跟大家分享,這裡你只需要理解成是一個事物的唯一標識就行)更要命的是,主庫中沒有這些GTID。
當主從都正常執行時,主從bin log不一致沒關係,但是當從庫當機的時候,從庫重啟會將自己的GTID集合傳送給主庫,由於從庫多出來一部分主庫沒有的GTID,會導致該從庫不能再次加入叢集。
其實這個問題也好解決。使用這個引數 sql_log_bin
該sql_log_bin
變數控制是否為當前會話啟用到二進位制日誌的日誌記錄(假設二進位制日誌本身已啟用)。預設值為ON
。要為當前會話禁用或啟用二進位制日誌記錄,請將會話sql_log_bin
變數設定為 OFF
或ON
。
全域性sql_log_bin
變數是隻讀的,無法修改。
七、未來幾篇文章
本文到這裡就行將結束了,概括性的在各個方面講述了一下binlog,讓你對binlog有了一個大概的瞭解。
在後續的幾篇文章中我會嘗試針對binlog的某個點展開問答式的敘述。如下,歡迎關注,敬請期待。
binlog的寫入時機?binlog到底長啥樣?有哪些格式?各種格式的binlog的優缺點?恢復資料?
關於 “搭建一套一主兩從的MySQL叢集,binlog幫你完成主從的資料同步。”會放在MySQL叢集部分穿插串講起來。
參考:
https://dev.mysql.com/doc/refman/5.7/en/binary-log.html
https://dev.mysql.com/doc/refman/5.7/en/replication-options-binary-log.html
https://dev.mysql.com/doc/refman/5.7/en/set-sql-log-bin.html