Mysql binlog 基礎知識

>新搭建的我的博客,歡迎光臨<mysql

一. Binlog格式介紹  sql

模式1 Row:日誌中會記錄成每一行數據被修改的形式,而後在slave端再對相同的數據進行修改。數據庫

優勢:
row level模式下,bin-log中能夠不記錄執行的sql語句的上下文相關的信息,僅僅只須要記錄那一條記錄被修改了,修改爲什麼樣了。因此row level的日誌內容會很是清楚的記錄下每一行數據修改的細節。且不會出現某些特定狀況下的存儲過程,或function,以及 trigger的調用和觸發沒法被正確複製的問題。緩存

缺點:
row level模式下,全部的執行的語句當記錄到日誌中的時候,都將以每行記錄的修改來記錄,這樣可能會產生大量的日誌內容,好比有這樣一條update語句:update product set owner_member_id = ‘b’ where owner_member_id = ‘a’,執行以後,日誌中記錄的不是這條update語句所對應額事件(MySQL以事件的形式來記錄bin-log日誌),而是這條語句所更新的每一條記錄的變化狀況,這樣就記錄成不少條記錄被更新的不少個事件。天然,bin-log日誌的量就會很大。尤爲是當執行alter table之類的語句的時候,產生的日誌量是驚人的。由於MySQL對於alter table之類的表結構變動語句的處理方式是整個表的每一條記錄都須要變更,實際上就是重建了整個表。那麼該表的每一條記錄都會被記錄到日誌中。app

模式2 Statement:每一條會修改數據的sql都會記錄到 master的bin-log中。slave在複製的時候sql進程會解析成和原來master端執行過的相同的sql來再次執行。函數

優勢:
statement level下的優勢首先就是解決了row level下的缺點,不須要記錄每一行數據的變化,減小bin-log日誌量,節約IO,提升性能。由於他只須要記錄在Master上所執行的語句的細節,以及執行語句時候的上下文的信息。性能

缺點:
因爲他是記錄的執行語句,因此,爲了讓這些語句在slave端也能正確執行,那麼他還必須記錄每條語句在執行的時候的一些相關信息,也就是上下文信息,以保證全部語句在slave端杯執行的時候可以獲得和在master端執行時候相同的結果。另外就是,因爲MySQL如今發展比較快,不少的新功能不斷的加入,使MySQL得複製遇到了不小的挑戰,天然複製的時候涉及到越複雜的內容,bug也就越容易出現。在statement level下,目前已經發現的就有很多狀況會形成MySQL的複製出現問題,主要是修改數據的時候使用了某些特定的函數或者功能的時候會出現,好比:sleep()函數在有些版本中就不能真確複製,在存儲過程當中使用了last_insert_id()函數,可能會使slave和master上獲得不一致的id等等。因爲row level是基於每一行來記錄的變化,因此不會出現相似的問題。測試

模式3 Mixed:能夠理解爲是前兩種模式的結合。通常的語句修改使用statment格式保存binlog,如一些函數,statement沒法完成主從複製的操做,則採用row格式保存binlog。
Mixed模式下,MySQL會根據執行的每一條具體的sql語句來區分對待記錄的日誌形式,也就是在Statement和Row之間選擇一種。
新版本中的Statment level仍是和之前同樣,僅僅記錄執行的語句。而新版本的MySQL中隊row level模式也被作了優化,並非全部的修改都會以row level來記錄,像遇到表結構變動的時候就會以statement模式來記錄,若是sql語句確實就是update或者delete等修改數據的語句,那麼仍是會記錄全部行的變動。優化

Mixed日誌說明:unix

在slave日誌同步過程當中,對於使用now這樣的時間函數,MIXED日誌格式,會在日誌中產生對應的unix_timestamp()*1000的時間字符串,slave在完成同步時,取用的是sqlEvent發生的時間來保證數據的準確性。另外對於一些功能性函數slave能完成相應的數據同步,而對於上面指定的一些相似於UDF函數,致使Slave沒法知曉的狀況,則會採用ROW格式存儲這些Binlog,以保證產生的Binlog能夠供Slave完成數據同步。
在配置文件中的參數:

log-bin = mysql-bin
#binlog_format=」STATEMENT」
#binlog_format=」ROW」
binlog_format=」MIXED」

運行時在線修改參數也是能夠的:

mysql> SET SESSION binlog_format = ‘STATEMENT’;
mysql> SET SESSION binlog_format = ‘ROW’;
mysql> SET SESSION binlog_format = ‘MIXED’;
mysql> SET GLOBAL binlog_format = ‘STATEMENT’;
mysql> SET GLOBAL binlog_format = ‘ROW’;
mysql> SET GLOBAL binlog_format = ‘MIXED’;

相同操做在不一樣模式下導出文件的例子:

row模式下導出sql:

mysqlbinlog --base64-output=decode-rows -v .../mysql-bin.00000x >/x.sql

# at 192
#170731 16:06:55 server id 1  end_log_pos 240 CRC32 0xfd979c03     Table_map: `test`.`a` mapped to number 71
# at 240
#170731 16:06:55 server id 1  end_log_pos 335 CRC32 0x9762b145     Delete_rows: table id 71 flags: STMT_END_F
### DELETE FROM `test`.`a`
### WHERE
###   @1=11
###   @2='tt'
###   @3=25
### DELETE FROM `test`.`a`
### WHERE
###   @1=12
###   @2='jj'
###   @3=20
### DELETE FROM `test`.`a`
### WHERE
###   @1=13
###   @2='kk'
###   @3=21
### DELETE FROM `test`.`a`
### WHERE
###   @1=14
###   @2='mm'
###   @3=31
### DELETE FROM `test`.`a`
### WHERE
###   @1=15
###   @2='nn'
###   @3=32
# at 335

mixed模式下導出sql:

# at 199
#170731 16:01:50 server id 1  end_log_pos 298 CRC32 0xad14f7aa     Query    thread_id=5865    exec_time=0    error_code=0
use `test`/*!*/;
SET TIMESTAMP=1501488110/*!*/;
delete from a where id>10
/*!*/;
# at 298

二.Binlog基本配製與格式設定

1.基本配製

Mysql BInlog日誌格式能夠經過mysql的my.cnf文件的屬性binlog_format指定。如如下:

binlog_format = MIXED               // binlog日誌格式

log_bin = 目錄/mysql-bin.log         // binlog日誌名

expire_logs_days = 7                // binlog過時清理時間

max_binlog_size = 100m              // binlog每一個日誌文件大小

2.Binlog日誌格式選擇

Mysql默認是使用Statement日誌格式

因爲一些特殊使用,能夠考慮使用ROWED,如本身經過binlog日誌來同步數據的修改,這樣會節省不少相關操做。對於binlog數據處理會變得很是輕鬆,相對mixed,解析也會很輕鬆(固然前提是增長的日誌量所帶來的IO開銷在容忍的範圍內便可)。

3.mysqlbinlog格式選擇

mysql對於日誌格式的選定原則:若是是採用 INSERT,UPDATE,DELETE 等直接操做表的狀況,則日誌格式根據 binlog_format 的設定而記錄,若是是採用 GRANT,REVOKE,SET PASSWORD 等管理語句來作的話,那麼不管如何 都採用 SBR 模式記錄

三.Binlog日誌分析

經過MysqlBinlog指令查看具體的mysql日誌,以下:

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SET TIMESTAMP=1350355892/*!*/;

BEGIN

/*!*/;

# at 1643330

#121016 10:51:32 server id 1  end_log_pos 1643885        Query     thread_id=272571   exec_time=0   error_code=0

SET TIMESTAMP=1350355892/*!*/;

Insert into T_test….)

/*!*/;

# at 1643885

#121016 10:51:32 server id 1  end_log_pos 1643912        Xid = 0

COMMIT/*!*/;

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

1.開始事物的時間:

SET TIMESTAMP=1350355892/*!*/;

BEGIN

2.sqlevent起點

#at 1643330 :爲事件的起點,是以1643330字節開始。

3.sqlevent 發生的時間點

#121016 10:51:32:是事件發生的時間,

4.serverId

server id 1 :爲master 的serverId

5.sqlevent終點及花費時間,錯誤碼

end_log_pos 1643885:爲事件的終點,是以1643885 字節結束。

execTime 0: 花費的時間

error_code=0:錯誤碼

Xid:事件指示提交的XA事務

四.Binlog相關參數

log_bin:設置此參數表示啓用binlog功能,並指定路徑名稱

log_bin_index:設置此參數是指定二進制索引文件的路徑與名稱

binlog_do_db:表示只記錄指定數據庫的二進制日誌

binlog_ignore_db:表示不記錄指定的數據庫的二進制日誌

max_binlog_cache_size:表示binlog使用的內存最大的尺寸

binlog_cache_use:使用二進制日誌緩存的事務數量

 

binlog_cache_size:表示binlog使用的內存大小,能夠經過狀態變量binlog_cache_use和binlog_cache_disk_use來幫助測試


binlog_cache_disk_use:使用二進制日誌緩存但超過binlog_cache_size值並使用臨時文件來保存事務中的語句的事務數量

max_binlog_size:Binlog最大值,最大和默認值是1GB,該設置並不能嚴格控制Binlog的大小,尤爲是Binlog比較靠近最大值而又遇到一個比較大事務時,爲了保證事務的完整性,不可能作切換日誌的動做,只能將該事務的全部SQL都記錄進當前日誌,直到事務結束

sync_binlog:這個參數直接影響mysql的性能和完整性

sync_binlog=0:當事務提交後,Mysql僅僅是將binlog_cache中的數據寫入Binlog文件,但不執行fsync之類的磁盤,同步指令通知文件系統將緩存刷新到磁盤,而讓Filesystem自行決定何時來作同步,這個是性能最好的

sync_binlog=n:在進行n次事務提交之後,Mysql將執行一次fsync之類的磁盤同步指令,同志文件系統將Binlog文件緩存刷新到磁盤。Mysql中默認的設置是sync_binlog=0,即不做任何強制性的磁盤刷新指令,這時性能是最好的,但風險也是最大的。一旦系統繃Crash,在文件系統緩存中的全部Binlog信息都會丟失

相關文章
相關標籤/搜索