Mysql binlog 日志


一. Binlog格式介紹 

模式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之類的表結構變更語句的處理方式是整個表的每一條記錄都需要變動,實際上就是重建了整個表。那么該表的每一條記錄都會被記錄到日志中。

模式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日志說明:

在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日志格式,推薦使用MIXED.

由於一些特殊使用,可以考慮使用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_size表示binlog使用的內存大小,可以通過狀態變量binlog_cache_usebinlog_cache_disk_use來幫助測試
binlog_cache_use:使用二進制日志緩存的事務數量
binlog_cache_disk_use:使用二進制日志緩存但超過binlog_cache_size值並使用臨時文件來保存事務中的語句的事務數量

max_binlog_sizeBinlog最大值,最大和默認值是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信息都會丟失


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM