MySQL日志文件解析(binlog)

前言:

    binlog(二进制文件)一直来说都是一个比较难搞懂的点,笔者前后读了几遍,读了当时理解了,但是事后还是很模糊,尤其是跟redo log放在一起的时候,更是蒙的不行。

    总结原因:还是没有真正理解binlog的作用。所以才促成了这篇博客,希望通过这篇博客前后梳理一下binlog的整个流程。

1.什么是binlog?

    binlog也叫作二进制日志(顾名思义,其格式是二进制的)。

    那么这个日志记录了什么呢?它记录了数据库执行更改的所有操作,不包括select之类的操作(因为这些操作对数据没有修改)。

2.binlog的作用

    我们记录下来了数据库更改操作,能做什么呢?

    作用如下(比较空洞的概念):

        * 恢复:通过binlog来恢复数据

        * 复制:主从数据,可以通过binlog来做

        * 审计:针对这些更改操作进行审计,查看是否被攻击

3.如何查询binlog

    binlog默认是不开启的,我们可以通过在配置文件my.ini中修改log-bin=your-file-name来启动binlog,如果不指定的话,则默认为主机名。笔者修改如下:

# Binary Logging.
log-bin=bin_log

    则此时会产生一个名为bin_log.000001的文件。后面我们会分析下如何查询binlog日志,来具体查看下binlog如何记录数据变更情况。

4.binlog主要参数  

    参数查看方式同样是通过show variables来查看

show variables like '%binlog%';
// res
# Variable_name, Value
'binlog_cache_size', '32768'
'binlog_checksum', 'CRC32'
'binlog_direct_non_transactional_updates', 'OFF'
'binlog_error_action', 'ABORT_SERVER'
'binlog_format', 'STATEMENT'
'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'

    我们来分析几个主要参数

    1)max_binlog_size

        指定单个二进制日志文件的最大值,超过该值,则产生一个新的二进制日志文件,文件顺序+1,记录到index中,(貌似重启MySQL之后也会产生一个新的binlog文件,文件顺序+1来命名)。默认为1G。

    2)binlog_cache_size

        在InnoDB存储引擎下,所有未提交的事务二进制日志会被记录到一个缓存中去,当事务提交时才会将缓冲中的日志写入到binlog文件中。

        该缓冲区的大小是由该参数来决定的,默认为32KB。

        binlog_cache_size基于会话产生的。每当一个线程开启一个事务时,则会被分配一个32KB的缓存空间

    3)sync_binlog

        表示每写缓冲多少次就同步到磁盘,如果设置为1,则表示采用同步写磁盘的方式来写。

    4)binlog_format

        记录二进制日志的格式,可设置的值有STATEMENT/ROW/MIXED。

        STATEMENT:二进制日志文件记录逻辑SQL语句(有哪些update的语句则记录在binlog中)

        ROW:不再简单记录sql语句了,而是记录表的行更改情况(相对STATEMENT而言会增大binlog)

        MIXED:默认采用STATEMENT格式来记录,在一些情况下采用ROW的格式来记录(比如使用函数CURRENT_USER()/UUID()等函数时)

5.binlog_format格式为STATEMENT、ROW两种情况下的binlog值

    1)STATEMENT格式下的变更记录

 // 1. 首先我们来查看当前binlog_format
select @@session.binlog_format; //STATEMENT 当前为该格式

// 2. 查看当前binlog日志文件
show master status;
// res(可以看到结果值,文件为bin_log.000003,大小为154):
# File, Position, Binlog_Do_DB, Binlog_Ignore_DB, Executed_Gtid_Set
'bin_log.000003', '154', '', '', ''

// 3.指定update操作
update world.city_copy set District=UPPER(District);
// res(可以看到有4055行记录被修改):
// 22:55:26	update world.city_copy set District=UPPER(District)	4055 row(s) affected Rows matched: 4079  Changed: 4055  
// Warnings: 0	0.562 sec

// 4.查看当前binlog日志文件
show master status;
// res(可以看到结果值,文件为bin_log.000003,大小为458,日志文件增加了458-154=304字节):
# File, Position, Binlog_Do_DB, Binlog_Ignore_DB, Executed_Gtid_Set
'bin_log.000003', '458', '', '', ''

// 5.查看binlog内容
show binlog events in 'bin_log.000003';
//res: 
# Log_name, Pos, Event_type, Server_id, End_log_pos, Info
'bin_log.000003', '4', 'Format_desc', '1', '123', 'Server ver: 5.7.17-log, Binlog ver: 4'
'bin_log.000003', '123', 'Previous_gtids', '1', '154', ''
'bin_log.000003', '154', 'Anonymous_Gtid', '1', '219', 'SET @@SESSION.GTID_NEXT= \'ANONYMOUS\''
 // 可以看到下面是这次binlog变更的内容
'bin_log.000003', '219', 'Query', '1', '300', 'BEGIN'
'bin_log.000003', '300', 'Query', '1', '427', 'use `world`; update world.city_copy set District=UPPER(District)'
'bin_log.000003', '427', 'Xid', '1', '458', 'COMMIT /* xid=591 */'

    总结:通过上面的操作记录可以看到,最终在binlog中记录的是我们执行的sql

    2)ROW格式下的操作记录

// 1.首先设置binlog_format为ROW
set @@session.binlog_format='ROW';

// 2. 查看当前binlog日志文件
show master status;
// res(可以看到结果值,文件为bin_log.000003,大小为154):
# File, Position, Binlog_Do_DB, Binlog_Ignore_DB, Executed_Gtid_Set
'bin_log.000003', '458', '', '', ''

// 3.指定update操作
update world.city_copy set District=lower(District);
// res(工4075行记录被修改):
23:09:31	update world.city_copy set District=lower(District)	4075 row(s) affected Rows matched: 4079  Changed: 4075  
    //Warnings: 0	0.266 sec

// 4.查看当前binlog日志文件
show master status;
// res(可以看到结果值,文件为bin_log.000003,大小为268994,日志文件增加了268994-458=268536字节):
# File, Position, Binlog_Do_DB, Binlog_Ignore_DB, Executed_Gtid_Set
'bin_log.000003', '268994', '', '', ''

// 5.查看binlog内容
show binlog events in 'bin_log.000003';
    
// res:
# Log_name, Pos, Event_type, Server_id, End_log_pos, Info
'bin_log.000003', '523', 'Query', '1', '596', 'BEGIN'
'bin_log.000003', '596', 'Table_map', '1', '659', 'table_id: 253 (world.city_copy)'
'bin_log.000003', '659', 'Update_rows', '1', '8863', 'table_id: 253'
'bin_log.000003', '8863', 'Update_rows', '1', '17055', 'table_id: 253'
'bin_log.000003', '17055', 'Update_rows', '1', '25207', 'table_id: 253'
'bin_log.000003', '25207', 'Update_rows', '1', '33421', 'table_id: 253'
'bin_log.000003', '33421', 'Update_rows', '1', '41627', 'table_id: 253'
'bin_log.000003', '41627', 'Update_rows', '1', '49767', 'table_id: 253'
'bin_log.000003', '49767', 'Update_rows', '1', '57907', 'table_id: 253'
'bin_log.000003', '57907', 'Update_rows', '1', '66061', 'table_id: 253'
'bin_log.000003', '66061', 'Update_rows', '1', '74257', 'table_id: 253'
'bin_log.000003', '74257', 'Update_rows', '1', '82433', 'table_id: 253'
'bin_log.000003', '82433', 'Update_rows', '1', '90593', 'table_id: 253'
'bin_log.000003', '90593', 'Update_rows', '1', '98773', 'table_id: 253'
'bin_log.000003', '98773', 'Update_rows', '1', '106929', 'table_id: 253'
'bin_log.000003', '106929', 'Update_rows', '1', '115123', 'table_id: 253'
'bin_log.000003', '115123', 'Update_rows', '1', '123281', 'table_id: 253'
'bin_log.000003', '123281', 'Update_rows', '1', '131461', 'table_id: 253'
'bin_log.000003', '131461', 'Update_rows', '1', '139659', 'table_id: 253'
'bin_log.000003', '139659', 'Update_rows', '1', '147837', 'table_id: 253'
'bin_log.000003', '147837', 'Update_rows', '1', '156043', 'table_id: 253'
'bin_log.000003', '156043', 'Update_rows', '1', '164207', 'table_id: 253'
'bin_log.000003', '164207', 'Update_rows', '1', '172403', 'table_id: 253'
'bin_log.000003', '172403', 'Update_rows', '1', '180589', 'table_id: 253'
'bin_log.000003', '180589', 'Update_rows', '1', '188775', 'table_id: 253'
'bin_log.000003', '188775', 'Update_rows', '1', '196919', 'table_id: 253'
'bin_log.000003', '196919', 'Update_rows', '1', '205077', 'table_id: 253'
'bin_log.000003', '205077', 'Update_rows', '1', '213227', 'table_id: 253'
'bin_log.000003', '213227', 'Update_rows', '1', '221395', 'table_id: 253'
'bin_log.000003', '221395', 'Update_rows', '1', '229559', 'table_id: 253'
'bin_log.000003', '229559', 'Update_rows', '1', '237731', 'table_id: 253'
'bin_log.000003', '237731', 'Update_rows', '1', '245933', 'table_id: 253'
'bin_log.000003', '245933', 'Update_rows', '1', '254093', 'table_id: 253'
'bin_log.000003', '254093', 'Update_rows', '1', '262275', 'table_id: 253'
'bin_log.000003', '262275', 'Update_rows', '1', '268963', 'table_id: 253 flags: STMT_END_F'
'bin_log.000003', '268963', 'Xid', '1', '268994', 'COMMIT /* xid=703 */'

   以上查看binlog内容的方式不够明细,我们还可以通过mysqlbinlog命令来查看。

    在Windows环境下,首先找到%mysql_home%/bin/下的mysqlbinlog.cmd命令,然后在该目录下执行以下命令

mysqlbinlog.cmd -vv --start-position=458 bin_log.00003
// res(会看到产生大量内容,笔者截取一部分):
    
### UPDATE `world`.`city_copy`
### WHERE
###   @1=3254 /* INT meta=0 nullable=0 is_null=0 */
###   @2='Latakia' /* STRING(35) meta=65059 nullable=0 is_null=0 */
###   @3='SYR' /* STRING(3) meta=65027 nullable=0 is_null=0 */
###   @4='LATAKIA' /* STRING(20) meta=65044 nullable=0 is_null=0 */
###   @5=264563 /* INT meta=0 nullable=0 is_null=0 */
### SET
###   @1=3254 /* INT meta=0 nullable=0 is_null=0 */
###   @2='Latakia' /* STRING(35) meta=65059 nullable=0 is_null=0 */
###   @3='SYR' /* STRING(3) meta=65027 nullable=0 is_null=0 */
// 在这里可以很明显的看到update前后的变化,之前是LATAKIA,目前被修改为latakia
###   @4='latakia' /* STRING(20) meta=65044 nullable=0 is_null=0 */
###   @5=264563 /* INT meta=0 nullable=0 is_null=0 */
...

    详细记录了每个字段的变化过程。

    总结:我们在SQL中使用函数、存储过程等功能时,可以考虑使用ROW的方式来记录每行数据的变化。

总结:

    说一千道一万,如果有条件开启MIXED,还是开启MIXED吧。

参考:MySQL技术内幕 InnoDB存储引擎

发布了122 篇原创文章 · 获赞 119 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qq_26323323/article/details/103662307