天天看點

【MySQL系列】- binlog預防删庫跑路

前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。​​點選跳轉到網站。​​

如果哪天不小心把表給删了,資料都沒了或者一不留神被删庫跑路了,那怎麼把資料恢複呢?這就需要今天的主角binlog登場了。

binlog 是什麼

binlog又稱二進制日志,是binary log的結合體。

還是看官方定義:

The binary log contains “events” that describe database changes such as table creation operations or changes to table data.

翻譯:二進制日志包含描述資料庫更改的“事件”,如表建立操作或表資料更改。

說白了就是二進制日志記錄了對 MySQL 資料庫執行更改的所有操作,若操作本身沒有導緻資料庫發生變化,該操作可能也會寫入二進制檔案。 當然不包括 select和show這類不會對資料本身進行修改的操作。

binlog在語句或事務完成後立即執行,但在釋放鎖或執行送出之前執行,這可以確定按照送出順序記錄日志。對非事務性表的增删改操作在執行後立即存儲在binlog中。

binlog 的作用

binlog主要有兩個重要作用,恢複和主從複制,還有其他作用,審計。

  • 恢複(recovery):某些資料恢複操作需要使用二進制日志。恢複備份後,将重新執行在備份後記錄的二進制日志中的事件。這些事件使資料庫從備份點更新,資料将變化恢複到指定的時間點(Point-in-time)。
  • 主從複制(replication):主資料庫向從資料庫發送binlog到從資料庫,從資料庫執行和複制binlog進而将資料恢複到從資料庫中。
  • 審計(audit):使用者可以通過二進制日志中的資訊來進行審計,判斷是否有對資料庫進行注入的攻 `擊。

binlog的格式

MySQL有好3種格式記錄binlog,但具體的格式取決于MySQL資料庫的版本。3種格式如下:

  1. STATEMENT:MySQL中的主從複制功能最初是基于SQL語句從源到副本的傳播,這稱為基于語句的日志記錄(statement-based logging)。可以使用參數​

    ​--binlog-format=STATEMENT​

    ​進行配置。
  • 優點:隻需要記錄執行語句的細節和上下文環境,不需要記錄每一行的變化,減少了binlog日志量,節省了I/O。
  • 缺點:為了保證SQL語句能在slave上正确執行,必須記錄上下文資訊,以保證所有語句能在slave得到和在master端執行時候相同的結果;另外,主從複制時,存在部分函數(如sleep)及存儲過程在slave上會出現與master結果不一緻的情況
  1. ROW:預設值。基于行(row-based logging)修改的記錄,僅儲存修改的行記錄。
  • 優點:能清楚地記錄每一行資料修改的細節,而且不會出現某些特定情況下的存儲過程,或function,以及trigger的調用和觸發無法被正确複制的問題。
  • 缺點:記錄的細節比較多,導緻binlog檔案會特别大,特别是當執行alter table之類的語句的時候,由于表結構修改,每條記錄都發生改變,那麼該表每一條記錄都會記錄到日志中。
  1. MIXED:混合格式,上面兩種格式的混用。預設情況下使用的是STATEMENT格式,在某些情況下會轉換為ROW格式。一般的語句修改使用STATEMENT格式儲存binlog,如一些函數,STATEMENT無法完成主從複制的操作,則采用ROW格式儲存binlog,MySQL會根據執行的每一條具體的sql語句來區分對待記錄的日志形式,也就是在STATEMENT和ROW之間選擇一種.新版本的MySQL中對ROW格式也被做了優化,并不是所有的修改都會以ROW格式來記錄,像遇到表結構變更的時候就會以STATEMENT模式來記錄。至于update或者delete等修改資料的語句,還是會記錄所有行的變更。

binlog的參數

  • log_bin:是否開啟binlog,MySQL8.0之前預設是關閉的,之後預設是開啟的。需要打開的話隻要将配置檔案中注釋掉的log-bin參數打開,可通過語句​

    ​SHOW VARIABLES LIKE '%log_bin%'​

    ​檢視binlog是否開啟,ON是開啟,OFF是關閉。log-bin可配置成log-bin=[name]的形式,其中name字段表示binlog檔案的名字,可填可不填,如果不填的話name會自動變為主機名-bin,比如:host-bin.000001。其中000001代表序号,表示第一個binlog檔案。
  • log_bin_index:binlog的索引檔案的絕對路徑,用來存儲過往産生的binlog檔案,通常情況下,不建議手動修改這個檔案。

    binlog的索引檔案是一個文本檔案,可通過記事本打開,裡面存儲的

    預設情況下,log_bin_index的路徑和名字跟log-bin的一樣。比如:host-bin.index

  • log_bin_basename:binlog的路徑和名字,可以通過log-bin配置。binlog預設在MySQL資料路徑下。
  • max_binlog_size:單個binlog檔案的最大值,預設值也是最大值是1GB,最小值為4096 byte。如果目前binlog檔案超過最大值,MySQL會關閉目前binlog檔案并重新打開一個并寫入。

可以通過指令​

​show binary logs​

​檢視都有哪些binlog檔案

【MySQL系列】- binlog預防删庫跑路

檢視binlog内容

通過mysqlbinlog工具可以檢視binlog存儲的内容。首先,找到MySQL安裝路徑下的bin目錄,然後進入指令行,我使用的是Windows系統,其他系統類似。最後,在指令行執行以下指令:

mysqlbinlog D:\ProgramData\mysql-bin.000001 --base64-output=decode-rows -v      
【MySQL系列】- binlog預防删庫跑路

binlog檔案的目錄要是絕對路徑,并且目錄中不要有空格。

​​

​--base64-output=decode-rows -v​

​:表示binlog中的SQL語句以注釋的形式展現出來。

有一張表如下:

【MySQL系列】- binlog預防删庫跑路

修改一下表中資料,通過上面指令檢視binlog并截取其中一段

【MySQL系列】- binlog預防删庫跑路

從binlog中可以看到記錄更新前後的資料,這樣就可以以可讀的方式檢視binlog了。

總結

開啟binlog會使MySQL性能下降,官網中測試表名性能會下降1%左右。但是binlog的開啟利大于弊,在資料需要恢複和主從複制的情況下,binlog的利顯得更大。誰也不能保證一定不會出錯,根據墨菲定律,隻要有可能就一定會發生,萬一資料庫真的是不小心被格式化了,binlog就發揮很大作用了,binlog可以不用,但一定要有。

參考:

​​https://dev.mysql.com/doc/refman/5.7/en/binary-log.html​​