一、什么是Binlog日志

MySQL 的 Binlog 日志是一种二进制格式的日志,Binlog 记录所有的 DDL 和 DML 语句(除了数据查询语句SELECT、SHOW等),以 Event 的形式记录,同时记录语句执行时间

Binlog 的主要作用有两个:

  1. 数据恢复
    因为 Binlog 详细记录了所有修改数据的 SQL,当某一时刻的数据误操作而导致出问题,或者数据库宕机数据丢失,那么可以根据 Binlog来回放历史数据
  2. 主从复制
    想要做多机备份的业务,可以去监听当前写库的 Binlog 日志,同步写库的所有更改。

Binlog 包括两类文件:

  1. 二进制日志索引文件(.index):记录所有的二进制文件
  2. 二进制日志文件(.00000*):记录所有 DDL 和 DML 语句事件

Binlog 日志功能默认是开启的,线上情况下 Binlog 日志的增长速度是很快的,在 MySQL 的配置文件 my.cnf 中提供一些参数来对 Binlog 进行设置。

二、Binlog主要参数

  1. log-bin:设置此参数表示启用binlog功能,并制定二进制日志的存储目录
    log-bin=/home/mysql/binlog/
  2. max_binlog_size:日志文件最大字节(单位:字节)#设置最大100MB
    max_binlog_size=104857600
  3. expire_logs_days :设置了只保留7天BINLOG(单位:天)
    expire_logs_days = 7

expire_logs_days :Binlog 过期删除不是服务定时执行,是需要借助事件触发才执行,事件包括:

  • 服务器重启
  • 服务器被更新
  • 日志达到了最大日志长度 max_binlog_size
  • 日志被刷新
  1. binlog-do-db:binlog日志只记录指定库的更新
    binlog-do-db=db_name
  2. binlog-ignore-db: binlog日志不记录指定库的更新
    binlog-ignore-db=db_name
  3. sync_binlog: 写缓冲多少次,刷一次磁盘,默认0
    sync_binlog=0
  4. max_binlog_size : Binlog 最大值
    max_binlog_size :1G
  • 值得注意的是:Binlog 最大和默认值是 1G,该设置并不能严格控制 Binlog 的大小,尤其是 Binlog比较靠近最大值而又遇到一个比较大事务时,为了保证事务的完整性不可能做切换日志的动作,只能将该事务的所有 SQL都记录进当前日志直到事务结束。所以真实文件有时候会大于 max_binlog_size 设定值

二进制日志由配置文件的 log-bin选项负责启用,MySQL 服务器将在数据根目录创建两个新文件mysql-bin.000001 和mysql-bin.index,若配置选项没有给出文件名,MySQL 将使用主机名称命名这两个文件,其中 .index文件包含一份全体日志文件的清单。

  • sync_binlog:这个参数决定了 Binlog 日志的更新频率。默认 0 ,表示该操作由操作系统根据自身负载自行决定多久写一次磁盘。
  • sync_binlog = 1 表示每一条事务提交都会立刻写盘。sync_binlog=n 表示 n 个事务提交才会写盘。
  • 根据 MySQL 文档,写 Binlog 的时机是:SQL transaction 执行完,但任何相关的 Locks 还未释放或事务还未最终commit 前。这样保证了 Binlog 记录的操作时序与数据库实际的数据变更顺序一致。

三、Binlog实例

  • 检查 Binlog 文件是否已开启:show variables like '%log_bin%';

    MySQL 会把用户对所有数据库的内容和结构的修改情况记入 mysql-bin.n 文件,而不会记录 SELECT 和没有实际更新的 UPDATE 语句。
  • 如果你不知道现在有哪些 Binlog 文件,可以使用如下命令:
    show binary logs; #查看binlog列表
    show master status; #查看最新的binlog

  • Binlog 文件是二进制文件,强行打开看到的必然是乱码,MySQL 提供了命令行的方式来展示 Binlog 日志:
mysqlbinlog mysql-bin.000025 | more


如若该命令遇到问题,可参考该文章
看起来凌乱其实也有迹可循。Binlog 通过事件的方式来管理日志信息,可以通过 show binlog events in 的语法来查看当前 Binlog 文件对应的详细事件信息。

Binlog 的版本是V4,可以看到日志的结束时间为 Stop。出现 Stop event 有两种情况:

  1. 是 master shut down 的时候会在 Binlog 文件结尾出现
  2. 是备机在关闭的时候会写入 relay log 结尾,或者执行RESET SLAVE 命令执行

一般来说一份正常的 Binlog 日志文件会以 Rotate event 结束。当 Binlog 文件超过指定大小,Rotate event 会写在文件最后,指向下一个 Binlog 文件。

  • 对 event 查询的数据行关键字段来解释一下:
  • Pos:当前事件的开始位置,每个事件都占用固定的字节大小,结束位置(End_log_position)减去Pos,就是这个事件占用的字节数。上面的日志中我们能看到,第一个事件位置并不是从 0 开始,而是从 4。MySQL 通过文件中的前 4 个字节,来判断这是不是一个 Binlog 文件。这种方式很常见,很多格式的文件,如 pdf、doc、jpg等,都会通常前几个特定字符判断是否是合法文件。

  • Event_type:表示事件的类型

  • Server_id:表示产生这个事件的 MySQL server_id,通过设置 my.cnf 中的 server-id 选项进行配置

  • End_log_position:下一个事件的开始位置

  • Info:包含事件的具体信息

四、Binlog 日志格式

针对不同的使用场景,Binlog 也提供了可定制化的服务,提供了三种模式来提供不同详细程度的日志内容。

  • Statement 模式:基于 SQL 语句的复制(statement-based replication-SBR)
  • Row模式:基于行的复制(row-based replication-RBR)
  • Mixed 模式:混合模式复制(mixed-basedreplication-MBR)
  1. Statement 模式:保存每一条修改数据的SQL。

该模式只保存一条普通的SQL语句,不涉及到执行的上下文信息。因为每台 MySQL 数据库的本地环境可能不一样,那么对于依赖到本地环境的函数或者上下文处理的逻辑 SQL 去处理的时候可能同样的语句在不同的机器上执行出来的效果不一致。比如像 sleep()函数,last_insert_id()函数,等等,这些都跟特定时间的本地环境有关。

  1. Row 模式:记录具体被修改的信息

MySQL V5.1.5 版本开始支持Row模式的 Binlog,它与 Statement 模式的区别在于它不保存具体的 SQL 语句,而是记录具体被修改的信息。比如一条 update 语句更新10条数据,如果是 Statement 模式那就保存一条 SQL 就够,但是 Row 模式会保存每一行分别更新了什么,有10条数据。Row 模式的优缺点就很明显了。保存每一个更改的详细信息必然会带来存储空间的快速膨胀,换来的是事件操作的详细记录。所以要求越高代价越高。

  1. Mixed 模式:两种模式的综合体

Mixed 模式即以上两种模式的综合体。既然上面两种模式分别走了极简和一丝不苟的极端,那是否可以区分使用场景的情况下将这两种模式综合起来呢?在 Mixed 模式中,一般的更新语句使用 Statement 模式来保存 Binlog,但是遇到一些函数操作,可能会影响数据准确性的操作则使用 Row 模式来保存。这种方式需要根据每一条具体的 SQL 语句来区分选择哪种模式。

  • 注意:MySQL 从 V5.1.8 开始提供 Mixed 模式,V5.7.7 之前的版本默认是Statement 模式,之后默认使用Row模式, 但是在 8.0 以上版本已经默认使用 Mixed 模式了

五、如何通过 mysqlbinlog 命令手动恢复数据

上面说过每一条 event 都有位点信息,如果我们当前的 MySQL 库被无操作或者误删除了,那么该如何通过 Binlog 来恢复到删除之前的数据状态呢?

  1. 首先发现误操作之后,先停止 MySQL 服务,防止继续更新

  2. 接着通过 mysqlbinlog命令对二进制文件进行分析,查看误操作之前的位点信息在哪里

  3. 接下来肯定就是恢复数据,当前数据库的数据已经是错的,那么就从开始位置到误操作之前位点的数据肯定的都是正确的;如果误操作之后也有正常的数据进来,这一段时间的位点数据也要备份

比如说:误操作的位点开始值为 501,误操作结束的位置为705,之后到800的位点都是正确数据。那么从 0 - 500 ,706 - 800 都是有效数据,接着我们就可以进行数据恢复了。先将数据库备份并清空。

  1. 接着使用 mysqlbinlog 来恢复数据:

0 - 500 的数据:

mysqlbinlog --start-position=0  --stop-position=500  bin-log.000003 > /root/back.sql;

上面命令的作用就是将 0 -500 位点的数据恢复到自定义的 SQL 文件中。同理 706 - 800 的数据也是一样操作。之后我们执行这两个 SQL 文件就行了。

六、Binlog 事件类型

上面我们说到了 Binlog 日志中的事件,不同的操作会对应着不同的事件类型,且不同的 Binlog 日志模式同一个操作的事件类型也不同,下面我们一起看看常见的事件类型。

首先我们看看源码中的事件类型定义:源码位置:/libbinlogevents/include/binlog_event.h

enum Log_event_type
{/**Every time you update this enum (when you add a type), you have tofix Format_description_event::Format_description_event().*/UNKNOWN_EVENT= 0,START_EVENT_V3= 1,QUERY_EVENT= 2,STOP_EVENT= 3,ROTATE_EVENT= 4,INTVAR_EVENT= 5,LOAD_EVENT= 6,SLAVE_EVENT= 7,CREATE_FILE_EVENT= 8,APPEND_BLOCK_EVENT= 9,EXEC_LOAD_EVENT= 10,DELETE_FILE_EVENT= 11,/**NEW_LOAD_EVENT is like LOAD_EVENT except that it has a longersql_ex, allowing multibyte TERMINATED BY etc; both types share thesame class (Load_event)*/NEW_LOAD_EVENT= 12,RAND_EVENT= 13,USER_VAR_EVENT= 14,FORMAT_DESCRIPTION_EVENT= 15,XID_EVENT= 16,BEGIN_LOAD_QUERY_EVENT= 17,EXECUTE_LOAD_QUERY_EVENT= 18,TABLE_MAP_EVENT = 19,/**The PRE_GA event numbers were used for 5.1.0 to 5.1.15 and aretherefore obsolete.*/PRE_GA_WRITE_ROWS_EVENT = 20,PRE_GA_UPDATE_ROWS_EVENT = 21,PRE_GA_DELETE_ROWS_EVENT = 22,/**The V1 event numbers are used from 5.1.16 until mysql-trunk-xx*/WRITE_ROWS_EVENT_V1 = 23,UPDATE_ROWS_EVENT_V1 = 24,DELETE_ROWS_EVENT_V1 = 25,/**Something out of the ordinary happened on the master*/INCIDENT_EVENT= 26,/**Heartbeat event to be send by master at its idle timeto ensure master's online status to slave*/HEARTBEAT_LOG_EVENT= 27,/**In some situations, it is necessary to send over ignorabledata to the slave: data that a slave can handle in case thereis code for handling it, but which can be ignored if it is notrecognized.*/IGNORABLE_LOG_EVENT= 28,ROWS_QUERY_LOG_EVENT= 29,/** Version 2 of the Row events */WRITE_ROWS_EVENT = 30,UPDATE_ROWS_EVENT = 31,DELETE_ROWS_EVENT = 32,GTID_LOG_EVENT= 33,ANONYMOUS_GTID_LOG_EVENT= 34,PREVIOUS_GTIDS_LOG_EVENT= 35,TRANSACTION_CONTEXT_EVENT= 36,VIEW_CHANGE_EVENT= 37,/* Prepared XA transaction terminal event similar to Xid */XA_PREPARE_LOG_EVENT= 38,/**Add new events here - right above this comment!Existing events (except ENUM_END_EVENT) should never change their numbers*/ENUM_END_EVENT /* end marker */
};

这么多的事件类型我们就不一一介绍,挑出来一些常用的来看看。

  1. FORMAT_DESCRIPTION_EVENT

FORMAT_DESCRIPTION_EVENT 是 Binlog V4 中为了取代之前版本中的 START_EVENT_V3 事件而引入的。它是 Binlog 文件中的第一个事件,而且,该事件只会在 Binlog 中出现一次。MySQL 根据FORMAT_DESCRIPTION_EVENT 的定义来解析其它事件。它通常指定了 MySQL 的版本,Binlog 的版本,该 Binlog 文件的创建时间

  1. QUERY_EVENT

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

  1. 事务开始时,执行的 BEGIN 操作
  2. STATEMENT 格式中的 DML 操作
  3. ROW 格式中的 DDL 操作
  1. XID_EVENT
    在事务提交时,不管是 STATEMENT 还 是ROW 格式的 Binlog,都会在末尾添加一个 XID_EVENT 事件代表事务的结束。该事件记录了该事务的 ID,在 MySQL 进行崩溃恢复时,根据事务在 Binlog 中的提交情况来决定是否提交存储引擎中状态为 prepared 的事务。
  2. ROWS_EVENT

对于 ROW 格式的 Binlog,所有的 DML 语句都是记录在 ROWS_EVENT 中。ROWS_EVENT分为三种:

  • WRITE_ROWS_EVENT:对应insert
    对于 insert 操作,WRITE_ROWS_EVENT 包含了要插入的数据。
  • UPDATE_ROWS_EVENT:对应update
    对于 update 操作,UPDATE_ROWS_EVENT 不仅包含了修改后的数据,还包含了修改前的值。
  • DELETE_ROWS_EVENT:对应delete
    对于 delete 操作,仅仅需要指定删除的主键(在没有主键的情况下,会给定所有列)。

对比 QUERY_EVENT 事件,是以文本形式记录 DML 操作的。而对于 ROWS_EVENT 事件,并不是文本形式,所以在通过 mysqlbinlog 查看基于 ROW 格式的 Binlog 时,需要指定 -vv --base64-output=decode-rows。

mysql8.0版本更详细的Event_type详解

参考文章

Mysql - Binlog相关推荐

  1. Mysql binlog日志及binlog恢复数据库操作

    初识MySQL 日志binlog MySQL重要log,二进制日志文件,记录所有DDL和DML语句(除select),事件形式记录,包含语句所执行的消耗时间,事务安全型. DDL(数据库定义语言),主 ...

  2. MySQL Binlog解析

    概述 MySQL的安装可以参考:Linux(CentOS)中常用软件安装,使用及异常--MySQL, VmTools MySQL关于Binlog的官方文档:The Binary Log 基于Binlo ...

  3. Mysql binlog应用场景与原理深度剖析

    1 基于binlog的主从复制 Mysql 5.0以后,支持通过binary log(二进制日志)以支持主从复制.复制允许将来自一个MySQL数据库服务器(master) 的数据复制到一个或多个其他M ...

  4. mysql binlog的查询

    查mysql bin-log binlog基本定义:二进制日志,也成为二进制日志,记录对数据发生或潜在发生更改的SQL语句,并以二进制的形式保存在磁盘中: 作用:MySQL的作用类似于Oracle的归 ...

  5. php读取binlog,PHP解析Mysql Binlog

    PHP解析Mysql Binlog,依赖于mysql-replication-listener库 详见:[https://github.com/bullsoft/php-binlog](https:/ ...

  6. mysql binlog 多少,MySQL binlog后面的编号最大是多大?

    在上课中讲到MySQL的binlog是mysql-bin.000001,有细心的学习提到,是不是这个达到mysql-bin.999999后数据库的binlog就要重新开始了? 对于这个问题一时间也被问 ...

  7. MySQL bin-log 日志清理方式

    MySQL bin-log 作用 1.数据恢复:如果你的数据库出问题了,而你之前有过备份,那么可以看日志文件,找出是哪个命令导致你的数据库出问题了,想办法挽回损失. 2.主从服务器之间同步数据:主服务 ...

  8. mysql基于binlog增量更新_一个应用它提取MySQL binlog,解析binlog并将增量更新数据推送到不同的接收器...

    DolphinBeat Other languages: 中文 This is a high available server that pulls MySQL binlog, parses binl ...

  9. Mysql Binlog三种格式详细介绍

    binlog 的不同模式有什么区别呢? 1.Statement:每一条会修改数据的sql都会记录在binlog中. 优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能.(相比 ...

  10. 好文推荐 | MySQL binlog应用场景与原理深度剖析

    作者:田守枝 来自:田守枝的博客(公众号) 本文深入介绍Mysql Binlog的应用场景,以及如何与MQ.elasticsearch.redis等组件的保持数据最终一致.最后通过案例深入分析binl ...

最新文章

  1. [AVR]使用AVR单片机驱动舵机
  2. java编写一个通讯录_java写的通讯录(小玩意)
  3. java的static关键字
  4. 阿里云服务器Linux配置数据库、jre、tomcat、部署javaweb
  5. hdu3313 最大流找关键点,或者最短路找关键点.
  6. php判断表单修改内容,JavaScript判断用户是否对表单进行了修改的方法_javascript技巧...
  7. Java程序在命令行的编译运行
  8. 诺贝尔化学奖得主田中耕一的故事
  9. redisTemplate设置key零点过期,生成自增的单号
  10. 前端学习(2537):vue源码解析2伪数组转换为真数组
  11. ios支付宝支付失败不回调_为什么 iOS 支付成功后能回到 APP ,但是没有回调?...
  12. Excel教程一:将Excel中一列转换成多行
  13. SecureRandom-随机数的生成
  14. vim替换字符(包括行首行尾添加字符串)
  15. 使用Adobe Acrobat为PDF文件添加图章(仅图片)
  16. 玩转混合云+边缘计算,且看ZStack Mini!
  17. 2021概率论与数理统计辅导讲义-李林
  18. 51单片机的键盘扫描程序,算法简单有效(来自ourdev)
  19. 年度网络购物十大被投诉网站淘宝、当当位居前二正文
  20. VSCode安装使用教程(最新详细版)

热门文章

  1. Golang的模板与渲染
  2. Servlet服务器搭建过程中一些经验 Tomcat+Mysql数据库+http传输
  3. linux 使用buildroot制作文件系统
  4. (十)更快的排序算法(归并、快排、基数)
  5. Java 常用类库 之 Arrays 数组操作类
  6. java基础知识-对象和类
  7. java全面的知识体系结构总结
  8. LoadRunner中常见参数和变量
  9. 在 Windows 7 中安装上网认证客户端
  10. 用Python更改IP地址(转)