概述
binlog(binary log)顾名思义是一组二进制日志文件,其中包含了对MySQL服务器实例的数据修改信息。它也包含了一些其它的元数据
- 有关正确再现语句所需的服务状态信息
- 错误码
- 维护二进制日志本身所需的元数据(例如,轮换事件,详见下文)
binlog是运行期服务状态改变的追踪,它所包含的Events描述了状态的改变。更确切的说,binlog中的Events描述了那些能够用来再现服务状态改变的行为。
用途
binlog有两种用途
- 主从复制(结合Slave的relay log来实现)
- 备份恢复
总之,都是通过binlog上的events信息来再现服务的状态
- events 记录的是SQL语句就执行SQL语句
- 如果记录的是数据更改直接保存数据更改后的状态
查看binary log文件列表
两种方式,
- SQL语句SHOW BINARY LOGS
- 查看HOSTNAME.index文件(下文介绍)
查看当前source服务的binlog状态
- SQL语句SHOW MASTER STATUS
注意:该操作需要系统权限,而且当GTID mode启用时Executed_Gtid_Set才会存在,表示二进制日志中写入的一组全局事务ID。
格式
binlog支持三种格式,
- statement-based
此时events包含了所有产生数据变更的SQL语句—— DDL(修改表结构,创建表库等),DML(增删改)。如果使用statement作为日志格式,在某些情况下做数据恢复和备份会产生问题,比如服务引擎设置不一致、UUID()、自定义函数、存储过程或触发器等,都会导致replica数据状态与source数据状态无法达成一直。
- row-based【 defalut 】
此时events分别描述了对单个行的更改。某些情况下row-based也会自动选择记录SQL语句而并非数据更改,比如一系列DDL……
- mixed-based
Mixed-baed默认使用 statement-based 格式记录日志但必要条件下会自动转换成 row-based 格式来记录。
注意:
- Row-based and Mixed-based 在 MySQL 5.1.* 之后可用。
- 三种类型格式各有优缺点,至于如何选择,可以根据业务数据特征、存储引擎、集群模式来判断。
设置格式
- 启动时设置,两种方式
- 传入启动参数--binlog-format=format
- 读取配置文件etc/my.cnf中binlog-format=format
- 运行时设置,两种作用域(要求权限)
- SET GLOBAL binlog_format = ‘format’
- SET SESSION binlog_format = 'format'
优先级:
session > global > 启动参数 > 配置文件
结构与内容
binlog是一组日志文件,包含了对一个MySQL服务实例的数据修改信息。
- 日志文件包括一组binary log文件(默认是HOSTNAME-bin.NNNNNN),再加上一个index文件(默认HOSTNAME.index,index文件是一个包含了当前binary log文件名列表的文本文件)。
- 每个日志文件的开头包含一个4byte的魔数,紧随其后的是描述数据修改的一系列events
- 魔数字节是0xfe 0x62 0x69 0x6e=“þbin”
- 每个Event包含header字节数组和跟在后面的data字节数组两部分:
- header bytes 部分提供了一些信息,比如Event生成时间timestamp(单位:s)、服务身份标识server_id等其他信息。
- data bytes 部分提供特定于event类型的信息,例如特定的数据修改。
- 第一个event被称为descriptor event(描述符事件,START_EVENT_V3和FORMAT_DESCRIPTION_EVENT统称为描述符事件)—— 用来描述binlog文件格式版本(用来写events到日志文件的格式)。
- 随后的一系列events需要依照descriptor event提供的format version来解析。
- 最后的event是ROTATE_EVENT(日志轮转事件, 当MySQL服务切换到一个新的日志文件时发生,由server重启、flush logs 或日志大小到达阈值触发,用来指定下一个binlog的文件名。)
查看binlog文件内容
由于binlog的文件内容是二进制的,如果直接通过文本工具去查看,那是很费力的,MySQL提供了binlog解析工具mysqlbinlog,
参考链接:https://dev.mysql.com/doc/refman/8.0/en/mysqlbinlog.html
尤其注意,当 binlog-format 是 Row-based时,events的data bytes部分被使用base-64编码,你可以通过增加参数--base64-output=DECODE-ROWS来解码查看(其实是告诉server引擎不使用BINLOG语句来编码)
binlog的核心其实就是记录在日志文件中的,各种各样的events,所以我们也可以使用SQL语句 ——SHOW BINLOG EVENTS IN 'filename',直接查看binary log文件中的events列表
SHOW BINLOG EVENTS在日志文件中的每个event都展示出如下几个字段:
- Log_name —— 文件名
- Pos —— event 起始位置
- Event_type —— 事件类型描述,参考链接:
- Server_id —— 事件发生的MySQL server实例标识
- End_log_pos —— event 结束位置,等于Pos + event bytes length
- Info —— 关于event type 的更多详细信息,信息的格式取决于event type
对于压缩的事务负载,Transaction_payload_event 首先被单独打印出来,然后解压并一一打印负载中的每个event。