查看MySQL二进制文件中的内容有两种方式

1.  mysqlbinlog

2.  SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]

下面来测试一下,在mysql中执行如下操作

  1. mysql> flush logs;
  2. Query OK, 0 rows affected (0.01 sec)
  3.  
  4. mysql> insert into test.t1 values(1,'a');
  5. Query OK, 1 row affected (0.00 sec)
  6.  
  7. mysql> use test
  8. Reading table information for completion of table and column names
  9. You can turn off this feature to get a quicker startup with -A
  10.  
  11. Database changed
  12. mysql> insert into test.t1 values(2,'b');
  13. Query OK, 1 row affected (0.00 sec)
  14.  
  15. mysql> show master status;
  16. +------------------+----------+--------------+------------------+-------------------+
  17. | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
  18. +------------------+----------+--------------+------------------+-------------------+
  19. | mysql-bin.000021 | 546 | | | |
  20. +------------------+----------+--------------+------------------+-------------------+
  21. 1 row in set (0.00 sec)

对应二进制日志中的内容如下

通过mysqlbinlog查看

# mysqlbinlog mysql-bin.000021

  1. /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;
  2. /*!40019 SET @@session.max_insert_delayed_threads=0*/;
  3. /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;
  4. DELIMITER /*!*/;
  5. # at
  6. # :: server id end_log_pos CRC32 0xf9bbe803 Start: binlog v , server v 5.6.-log created ::
  7. # Warning: this binlog is either in use or was not closed properly.
  8. BINLOG '
  9. Ln2zVw8BAAAAdAAAAHgAAAABAAQANS42LjMxLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
  10. AAAAAAAAAAAAAAAAAAAAAAAAEzgNAAgAEgAEBAQEEgAAXAAEGggAAAAICAgCAAAACgoKGRkAAQPo
  11. u/k=
  12. '/*!*/;
  13. # at
  14. # :: server id end_log_pos CRC32 0x0182ee55 Query thread_id= exec_time= error_code=
  15. SET TIMESTAMP=/*!*/;
  16. SET @@session.pseudo_thread_id=/*!*/;
  17. SET @@session.foreign_key_checks=, @@session.sql_auto_is_null=, @@session.unique_checks=, @@session.autocommit=/*!*/;
  18. SET @@session.sql_mode=/*!*/;
  19. SET @@session.auto_increment_increment=, @@session.auto_increment_offset=/*!*/;
  20. /*!\C utf8 *//*!*/;
  21. SET @@session.character_set_client=,@@session.collation_connection=,@@session.collation_server=/*!*/;
  22. SET @@session.lc_time_names=/*!*/;
  23. SET @@session.collation_database=DEFAULT/*!*/;
  24. BEGIN
  25. /*!*/;
  26. # at
  27. # :: server id end_log_pos CRC32 0xf9049380 Query thread_id= exec_time= error_code=
  28. SET TIMESTAMP=/*!*/;
  29. insert into test.t1 values(,'a')
  30. /*!*/;
  31. # at
  32. # :: server id end_log_pos CRC32 0xdb58b5b4 Xid =
  33. COMMIT/*!*/;
  34. # at
  35. # :: server id end_log_pos CRC32 0xcc370a55 Query thread_id= exec_time= error_code=
  36. SET TIMESTAMP=/*!*/;
  37. BEGIN
  38. /*!*/;
  39. # at
  40. # :: server id end_log_pos CRC32 0x4fa06a6e Query thread_id= exec_time= error_code=
  41. use `test`/*!*/;
  42. SET TIMESTAMP=/*!*/;
  43. insert into test.t1 values(,'b')
  44. /*!*/;
  45. # at
  46. # :: server id end_log_pos CRC32 0x5f51e8bd Xid =
  47. COMMIT/*!*/;
  48. DELIMITER ;
  49. # End of log file
  50. ROLLBACK /* added by mysqlbinlog */;
  51. /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
  52. /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

解析如下:

1. at xxx,不仅仅是事件开始的位置,同样是二进制日志的物理大小

譬如上述日志中,结束位置是end_log_pos 546,则二进制日志的大小也是546.

  1. # ll mysql-bin.
  2. -rw-rw---- mysql mysql Aug : mysql-bin.

2. at 4,对应的事件类型是FORMAT_DESCRIPTION_EVENT,是所有binlog文件中的第一个事件,在一个binlog中仅出现一次,MySQL会根据FORMAT_DESCRIPTION_EVENT事件的定义来解析binlog中的其它事件。该事件类型定义了binlog版本,MySQL Server的版本,binlog的创建时间等。

3. at 120,是第一个事务开始的偏移量,对应的事件类型是QUERY_EVENT,实际上也只执行了一个BEGIN操作。

4. 下面来截取一个事件来看看

  1. # at
  2. # :: server id end_log_pos CRC32 0xf9049380 Query thread_id= exec_time= error_code=
  3. SET TIMESTAMP=/*!*/;
  4. insert into test.t1 values(,'a')
  5. /*!*/;

该事件对应的事件类型是QUERY_EVENT

QUERY_EVENT类型的事件通常在以下几种情况下使用。

1> 事务开始时的BEGIN操作

2> 对于STATEMENT格式的DML操作

3> 对于ROW格式的DDL操作。

该事件会指明server_id,slave_proxy_id(会话的线程id),execution time(查询从开始执行到记录到binlog所花的时间,单位为秒),error-code(错误码),status-vars(status-vars是以键值对的形式保存起来的一系列由SET命令设置的上下文信息,譬如当前的时间戳),schema(当前选择的数据库),query(原生的DML语句,譬如insert into test.t1 values(1,'a'))

5. 同样是insert操作,一个没有切换schema,直接执行insert into test.t1 values(1,'a'),一个是先use test,再执行insert操作,反映在binlog中的内容也不一样,实际上,这会影响基于库的部分复制的判断逻辑。

6. 在执行基于binlog的部分恢复时,截止的时间点应该是commit操作的end_log_pos,而不是commit操作之前的的at xxx。

譬如,针对上面的commit操作

  1. # at
  2. # :: server id end_log_pos CRC32 0x5f51e8bd Xid =
  3. COMMIT/*!*/;

如果要执行第二个insert语句,则--stop-position=546,而不是515。

7. 在用mysqlbinlog查看binlog后都会带上ROLLBACK操作,这个在执行基于binlog的部分恢复时,会有用处。

# mysqlbinlog --stop-position=515 mysql-bin.000021

  1. ....
  2. # at
  3. # :: server id end_log_pos CRC32 0x4fa06a6e Query thread_id= exec_time= error_code=
  4. use `test`/*!*/;
  5. SET TIMESTAMP=/*!*/;
  6. insert into test.t1 values(,'b')
  7. /*!*/;
  8. DELIMITER ;
  9. # End of log file
  10. ROLLBACK /* added by mysqlbinlog */;
  11. /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
  12. /*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

我只应用到binlog偏移量为515的位置,这个时候只有insert操作,而没有针对该操作的commit,所以mysqlbinlog会显式增加一个rollback操作,直接回滚事务。

通过SHOW BINLOG EVENTS查看

通过这种方式查看还是蛮直观的

  1. mysql> show binlog events in 'mysql-bin.000021';
  2. +------------------+-----+-------------+-----------+-------------+-----------------------------------------------+
  3. | Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
  4. +------------------+-----+-------------+-----------+-------------+-----------------------------------------------+
  5. | mysql-bin.000021 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.31-log, Binlog ver: 4 |
  6. | mysql-bin.000021 | 120 | Query | 1 | 195 | BEGIN |
  7. | mysql-bin.000021 | 195 | Query | 1 | 298 | insert into test.t1 values(1,'a') |
  8. | mysql-bin.000021 | 298 | Xid | 1 | 329 | COMMIT /* xid=25 */ |
  9. | mysql-bin.000021 | 329 | Query | 1 | 408 | BEGIN |
  10. | mysql-bin.000021 | 408 | Query | 1 | 515 | use `test`; insert into test.t1 values(2,'b') |
  11. | mysql-bin.000021 | 515 | Xid | 1 | 546 | COMMIT /* xid=33 */ |
  12. +------------------+-----+-------------+-----------+-------------+-----------------------------------------------+
  13. 7 rows in set (0.00 sec)

事务的操作是何时写入到binlog中的?

MySQL使用binlog_cache_mngr结构来缓存一个事务的所有操作,如果用户执行commit操作,则将binlog_cache_mngr中的内容写入到binlog中;如果用户执行rollback操作,则直接丢弃binlog_cache_mngr中的内容。否则的话,如果事务中的操作立刻写入到binlog中,那么在回滚时就相当麻烦。

当时有一点需要注意的是,对于非事务的存储引擎,所有的修改会立刻写入到binlog中。

譬如下面的测试中,t_myisam是myisam表,t1是innodb表,在两张表中分别插入一条记录,再执行回滚。

  1. mysql> set autocommit=0;
  2. Query OK, 0 rows affected (0.05 sec)
  3.  
  4. mysql> insert into t_myisam values(1,'a');
  5. Query OK, 1 row affected (0.07 sec)
  6.  
  7. mysql> insert into t1 values(4,'d');
  8. Query OK, 1 row affected (0.06 sec)
  9.  
  10. mysql> rollback;
  11. Query OK, 0 rows affected, 1 warning (0.00 sec)
  12.  
  13. mysql> show warnings;
  14. +---------+------+---------------------------------------------------------------+
  15. | Level | Code | Message |
  16. +---------+------+---------------------------------------------------------------+
  17. | Warning | 1196 | Some non-transactional changed tables couldn't be rolled back |
  18. +---------+------+---------------------------------------------------------------+

但通过查看binlog日志的内容,即便该事务回滚了,针对t_myisam表的操作还是写入到binlog中了

  1. mysql> show binlog events in 'mysql-bin.000017';
  2. +------------------+-----+-------------+-----------+-------------+------------------------------------------------+
  3. | Log_name | Pos | Event_type | Server_id | End_log_pos | Info |
  4. +------------------+-----+-------------+-----------+-------------+------------------------------------------------+
  5. | mysql-bin.000017 | 4 | Format_desc | 1 | 120 | Server ver: 5.6.31-log, Binlog ver: 4 |
  6. | mysql-bin.000017 | 120 | Query | 1 | 199 | BEGIN |
  7. | mysql-bin.000017 | 199 | Query | 1 | 307 | use `test`; insert into t_myisam values(1,'a') |
  8. | mysql-bin.000017 | 307 | Query | 1 | 387 | COMMIT |
  9. +------------------+-----+-------------+-----------+-------------+------------------------------------------------+
  10. 4 rows in set (0.00 sec)

binlog的相关参数

max_binlog_size

指定binlog文件的大小,如果当前binlog文件的大小达到了参数指定的阀值,则会创建一个新的binlog文件。

注意:binlog文件的大小可能会超过max_binlog_size的值,因为一个事务所产生的所有事件都必须要记录在同一个binlog文件中,所以即使binlog文件的大小超过max_binlog_size的值,也会等到当前事务的所有操作全部写入到binlog文件中才能切换。

sql_log_bin

会话变量,设置sql_log_bin=0表示禁用当前会话的binlog功能。

sync_binlog

MySQL 5.7.7之前,默认为0,即binlog文件在每次写入内容后并不会立即持久化到磁盘中,具体的持久化操作交给操作系统去处理。如果操作系统崩溃,可能导致对binlog的修改丢失。

为了避免这种情况,可将sync_binlog设置为1,这样在每次事务提交时,该事务的操作写入到binlog后,都会调用fsync操作将binlog的修改同步到磁盘中。但这样会降低MySQL的性能,所以可将sync_binlog设置为N,代表N个事务后才执行一次fsync操作。

实际上,在引入binlog group commit后,上述持久化的单位并不是事务了,而是一组事务。

官档解释如下:

  1. Controls the number of binary log commit groups to collect before synchronizing the binary log to disk. When sync_binlog=, the binary log is never synchronized to disk, and when sync_binlog is set to a value greater than this number of binary log commit groups is periodically synchronized to disk. When sync_binlog=, all transactions are synchronized to the binary log before they are committed.

参考

1. MariaDB原理与实现

2. MySQL 5.7 Reference Manual

浅析MySQL二进制日志的更多相关文章

  1. mysql 二进制日志后缀数字最大为多少

    之前看到mysql二进制日志后面会加一个以数字递增为结尾的后缀,一直在想当尾数到达999999后会发生什么情况,先查了一下官网,对后缀有这样一句介绍:The server creates binary ...

  2. MySQL二进制日志的备份和恢复

    二进制日志:记录数据库修改的相关操作,作用是即时点回复,主从复制 可以按时间滚动,也可以按大小滚动 server-id:服务器身份标识 一.二进制文件的删除方法,千万不要手动删除 PURGE BINA ...

  3. 删除MySQL二进制日志

    服务器上的120G SSD硬盘空间用了92%,检查后发现,原来是 MySQL的二进制日志没有及时清除,占用了大量的空间, 于是直接用命令:reset master 一把删干净了. 1 reset ma ...

  4. MySQL二进制日志总结

    二进制日志简单介绍 MySQL的二进制日志(binary log)是一个二进制文件,主要用于记录修改数据或有可能引起数据变更的MySQL语句.二进制日志(binary log)中记录了对MySQL数据 ...

  5. MySQL二进制日志(binary log)总结

    本文出处:http://www.cnblogs.com/wy123/p/7182356.html (保留出处并非什么原创作品权利,本人拙作还远远达不到,仅仅是为了链接到原文,因为后续对可能存在的一些错 ...

  6. MySQL二进制日志功能介绍

    二进制日志记录所有更新数据的SQL语句,其中也包含可能更新数据的SQL语句,例如DELETE语句执行过程中无匹配的行.二进制日志中还包含了与执行SQL语句相关的内容,例如SQL语句执行的时间.错误代码 ...

  7. 查看mysql二进制日志报错问题

    在排查网站被黑时想通过Mysql二进制日志找出修改字段时间,但是使用mysqlbinlog报错: [root@zfszsw1 bin]# ./mysqlbinlog /opt/mysql-bin.00 ...

  8. MySQl Study学习之--MySQl二进制日志管理

    MySQl Study学习之--MySQl二进制日志管理 MySQL二进制日志(Binary Log)   a.它包括的内容及作用例如以下:     包括了全部更新了数据或者已经潜在更新了数据(比方没 ...

  9. Mysql 二进制日志备份还原

    Mysql 二进制日志备份还原 一.开启二进制日志 1.进入配置文件[mysqld]下添加配置 方案一 vim /etc/my.cnf log-bin = /usr/local/mysql/logs/ ...

随机推荐

  1. [linux]阿里云主机的免登陆安全SSH配置与思考

    公司服务器使用的第三方云端服务,即阿里云,而本地需要经常去登录到服务器做相应的配置工作,鉴于此,每次登录都要使用密码是比较烦躁的,本着极速思想,我们需要配置我们的免登陆. 一 理论概述 SSH介绍 S ...

  2. ABP文档 - 异常处理

    文档目录 本节内容: 简介 启用错误处理 非AJAX请求 显示异常 UserFriendlyException Error 模型 AJAX 请求 异常事件 简介 这个文档针对Asp.net Mvc和W ...

  3. 初探Vue

    Vue.js(读音/vju:/,类似于view),是近来比较火的前端框架,但一直没有怎么具体了解.实现过,就知道个啥的MVVM啦,数据驱动啦,等这些关于Vue的虚概念. 由于最近,小生在公司中,负责开 ...

  4. 关于VS2015 ASP.NET MVC添加控制器的时候报错

    调试环境:VS2015 数据库Mysql  WIN10 在调试过程中出现类似下两图的同学们,注意啦. 其实也是在学习的过程中遇到这个问题的,找了很多资料都没有正面的解决添加控制器的时候报错的问题,还是 ...

  5. enote笔记法使用范例(2)——指针(1)智能指针

    要知道什么是智能指针,首先了解什么称为 “资源分配即初始化” what RAII:RAII—Resource Acquisition Is Initialization,即“资源分配即初始化” 在&l ...

  6. Java中,异常的处理及抛出

    首先我们需要知道什么是异常? 常通常指,你的代码可能在编译时没有错误,可是运行时会出现异常.比如常见的空指针异常.也可能是程序可能出现无法预料的异常,比如你要从一个文件读信息,可这个文件不存在,程序无 ...

  7. 【SAP业务模式】之ICS(一):业务详述

    PS:本专题系列讲述如何在SAP系统中实现ICS的业务模式,本系列博文系原创,如要转载引用,请保持原文一致并注明出处! SAP系统自身功能非常强大,支持多种业务模式,通过前台后台的配置就可以实现多种效 ...

  8. git如何切换远程仓库

    场景 工作时可能由于git仓库的变动,需要我们将已有代码切换仓库.比如我们先用的gitlab,现在要切换到github上. 迁移命令 代码迁移其实也很简单. 先保证本地代码是最新代码 $ git pu ...

  9. SpringMvc中的数据校验

    SpringMvc中的数据校验 Hibernate校验框架中提供了很多注解的校验,如下: 注解 运行时检查 @AssertFalse 被注解的元素必须为false @AssertTrue 被注解的元素 ...

  10. 微信官方开源UI库-WeUI

    概述 WeUI是一套同微信原生视觉体验一致的基础样式库,为微信Web开发量身设计,可以令用户的使用感知更加统一.包含button.cell.dialog.toast.article.icon等各式元素 ...