>新搭建的我的博客,欢迎光临<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信息都会丢失