mysql的binlog日志格式
mysql binlog 三種格式
mysql的binlog日志作用是用來記錄mysql內部增刪改等對mysql數據庫有更新內容的記錄(對數據庫進行改動的操作),對數據庫查詢的語句如show,select開頭的語句,不會被binlog日志記錄,最大的作用是用來數據增量恢復和主從庫復制
ROW
ROW格式會記錄每行記錄修改的記錄,這樣可能會產生大量的日志內容,比如一條update語句修改了100條記錄,那么這100條記錄的修改都會被記錄在binlog日志中,這樣造成binlog日志量會很大,這種日志格式會占用大量的系統資源,mysql5.7和myslq8.0安裝后默認就是這種格式。
STATEMENT
記錄每一條修改數據的SQL語句(批量修改時,記錄的不是單條SQL語句,而是批量修改的SQL語句事件)所以大大減少了binlog日志量,節約磁盤IO,提高性能,看上面的圖解可以很好的理解row和statement 兩種模式的區別。但是STATEMENT對一些特殊功能的復制效果不是很好,比如:函數、存儲過程的復制。由於row是基於每一行的變化來記錄的,所以不會出現類似問題
MIXED
實際上就是前兩種模式的結合。在Mixed模式下,MySQL會根據執行的每一條具體的sql語句來區分對待記錄的日志形式,也就是在Statement和Row之間選擇一種。
相對較老的版本中默認使用的格式可能是STATEMENT,但是我裝了5.7和mysql8.0的版本,默認的格式都是ROW,即便如此,還是比較推薦使用STATEMENT或MIXED
MySQL binlog日志設置
- 查看當前日志格式
mysql> mysql> show variables like '%binlog_format%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| binlog_format | ROW |
+---------------+-------+
1 row in set (0.00 sec)
- 查看binlog詳細相關參數
mysql> show variables like '%binlog%';
+-----------------------------------------+----------------------+
| Variable_name | Value |
+-----------------------------------------+----------------------+
| binlog_cache_size | 32768 |
| binlog_checksum | CRC32 |
| binlog_direct_non_transactional_updates | OFF |
| binlog_error_action | ABORT_SERVER |
| binlog_format | ROW |
| binlog_group_commit_sync_delay | 0 |
| binlog_group_commit_sync_no_delay_count | 0 |
| binlog_gtid_simple_recovery | ON |
| binlog_max_flush_queue_time | 0 |
| binlog_order_commits | ON |
| binlog_row_image | FULL |
| binlog_rows_query_log_events | OFF |
| binlog_stmt_cache_size | 32768 |
| innodb_api_enable_binlog | OFF |
| innodb_locks_unsafe_for_binlog | OFF |
| log_statements_unsafe_for_binlog | ON |
| max_binlog_cache_size | 18446744073709547520 |
| max_binlog_size | 1073741824 |
| max_binlog_stmt_cache_size | 18446744073709547520 |
| sync_binlog | 1 |
+-----------------------------------------+----------------------+
20 rows in set (0.00 sec)
- 修改binlog日志格式,修改my.cnf
[mysqld]
log-bin= /data/binlog/mysql-bin.log #binlog位置及名稱
log-bin-index=/data/binlog/mysql-bin.index #自定義binlog路徑時需要加上改選項
binlog-format="STATEMENT" #binlog日志格式
expire_logs_days = 20 #binlog過期清理時間
max_binlog_size = 200M #單個binlog日志文件大小
sync-binlog = 1 #開啟binlog同步,將二進制日志同步到磁盤,保證數據完整性,在主從復制中也用到。
binlog-do-db=db1 # 需要記錄binlog的數據庫名,如果備份多個數據庫,重復設置這個選項即可
binlog-ignore-db=db2 # 不需要記錄binlog的數據庫庫名,如果備份多個數據庫,重復設置這個選項即可
#最后兩項可以用於主從復制場景
不重啟服務使其生效在mysql終端執行set global binlog_format="STATEMENT";
重新登錄終端查看
mysql> show variables like '%binlog_format%';
+---------------+-----------+
| Variable_name | Value |
+---------------+-----------+
| binlog_format | STATEMENT |
+---------------+-----------+
1 row in set (0.00 sec)
binlog中幾個重要的參數設置
binlog_cache_size:在事務過程中容納二進制日志SQL語句的緩存大小。二進制日志緩存是服務器支持事務存儲引擎並且服務器啟用了二進制日志(—log-bin選項)的前提下為每個客戶端分配的內存,注意,是每個Client都可以分配設置大小的binlogcache空間。如果系統中經常會出現多語句事務的話,可以嘗試增加該值的大小,以獲得更好的性能。可以通過MySQL的以下兩個狀態變量來判斷當前的binlog_cache_size的狀況:Binlog_cache_use和Binlog_cache_disk_use。
max_binlog_cache_size:和”binlog_cache_size”相對應,但是所代表的是binlog能夠使用的最大cache內存大小。當我們執行多語句事務的時候,max_binlog_cache_size如果不夠大的話,系統可能會報出“Multi-statementtransactionrequiredmorethan’max_binlog_cache_size’bytesofstorage”的錯誤。
max_binlog_size:Binlog日志最大值,一般來說設置為512M或者1G,但不能超過1G。該大小並不能非常嚴格控制Binlog大小,尤其是當到達Binlog比較靠近尾部而又遇到一個較大事務的時候,系統為了保證事務的完整性,不可能做切換日志的動作,只能將該事務的所有SQL都記錄進入當前日志,直到該事務結束。這一點和Oracle的Redo日志有點不一樣,因為Oracle的Redo日志所記錄的是數據文件的物理位置的變化,而且里面同時記錄了Redo和Undo相關的信息,所以同一個事務是否在一個日志中對Oracle來說並不關鍵。而MySQL在Binlog中所記錄的是數據庫邏輯變化信息,MySQL稱之為Event,實際上就是帶來數據庫變化的DML之類的Query語句。
sync_binlog:這個參數是對於MySQL系統來說是至關重要的,他不僅影響到Binlog對MySQL所帶來的性能損耗,而且還影響到MySQL中數據的完整性。對於“sync_binlog”參數的各種設置的說明如下:
sync_binlog=0,當事務提交之后,MySQL不做fsync之類的磁盤同步指令刷新binlog_cache中的信息到磁盤,而讓Filesystem自行決定什么時候來做同步,或者cache滿了之后才同步到磁盤。
sync_binlog=n,當每進行n次事務提交之后,MySQL將進行一次fsync之類的磁盤同步指令來將binlog_cache中的數據強制寫入磁盤。
在MySQL中系統默認的設置是sync_binlog=0,也就是不做任何強制性的磁盤刷新指令,這時候的性能是最好的,但是風險也是最大的。因為一旦系統Crash,在binlog_cache中的所有binlog信息都會被丟失。而當設置為“1”的時候,是最安全但是性能損耗最大的設置。因為當設置為1的時候,即使系統Crash,也最多丟失binlog_cache中未完成的一個事務,對實際數據沒有任何實質性影響。從以往經驗和相關測試來看,對於高並發事務的系統來說,“sync_binlog”設置為0和設置為1的系統寫入性能差距可能高達5倍甚至更多
