MySQL从3.23版本开始引入了二进制日志,用于的数据复制, 二进制日志根据MySQL的版本不同,目前有4个版本:
https://dev.mysql.com/doc/internals/en/binlog-version.html

Version 1: supported statement based replication events.
Version 2: can be ignored as it was only used in early alpha versions of MySQL 4.1.x
and won't be documented here.
Version 3: added the relay logs and changed the meaning of the log position.
Version 4: added the FORMAT_DESCRIPTION_EVENT and made the protocol extensible.
二进制日志版本是向后兼容的, 后一个版本可以看成是对前一个版本的继承和扩展,需要注意的是,version 2是一个临时版本, 可以忽略。事实上可以只关心v4版本,因为现在跑的MySQL都应该是MySQL 5+了,就如现再讨论Oracle 8i, 9i没什么实际意义。截至当前最新的MySQL 8版本,使用的依然是v4版本。

题外话:
BinlogMiner的解析器为保持代码稳定,做了接口将功能和具体实现分隔, 但实际上目前也只有一个BinlogParser4实现。也许以后会有V5版本,还有一个问题就是开源软件的碎片化,目前主流的有3个分支,本人偏爱Percona版本,Percona版本完全兼容官方版本,而在性能和可维护性上有提高,非常讨人喜欢。国内一些大的互联网企业如腾讯,阿里也有做基于MySQL的数据库,目前还没有研究,不知道兼容性如何。

MySQL的二进制日志文件以事件为单位进行封装,文件的结构如下:

说明:二进制日志可以看成是二进制事件的集合,不同的事件,对应于不同的功能,MySQL包含的事件类型可以参考:
https://dev.mysql.com/doc/internals/en/binlog-event-type.html

A start event (START_EVENT_V3) is the first event of a binlog for binlog-version 1 to 3.
A format description event (FORMAT_DESCRIPTION_EVENT) is the first event of a binlog for binlog-version 4.

v1-v3版本, 二进制日志文件的第一个事件是START_EVENT_V3, 而v4版本开始第一个事件是FORMAT_DESCRIPTION_EVENT,替代掉START_EVENT_V3.
二进制日志的结束事件为STOP_EVENT或者ROTATE_EVENT,出现其中之一就说应二进制文件已经结束, 其中STOP_EVENT说应MySQL服务器已经关闭, 而ROTATE_EVENT则说明二进制达到了max_binlog_size的阈值,或者在线修改了binlog-format,导致了二进制文件的切换。

二进制日志QUERY_EVENT和ROWS_EVENT(包括WRITE_ROWS_EVENT/UPDATE_ROWS_EVENT/DELETE_ROWS_EVENT)来记录数据变化, 所有的DDL,如(create table ...)都是通过QUERY_EVENT记录的, 而DML(inert/update/delete)则根据复制模式的不同(binlog-format)而不同, 基于语句的复制(Statement-Based),DML语句以语句形式记录在QUERY_EVENT中,而基于行的复制(Row-Based Replication),则将受到DML语句影响的行的值,记录在ROWS_EVENT中。显而易见, 基于语句的复制一个明显的优势就是数据量小,delete table xxx,只记录一个语句就可以了,但是行模式则需要记录所有行的值。但如前文说的基于语句的复制不是绝对安全的,当遇到"Nondeterministic"的语句,会由问题,比如SYSDATE(),如果将函数复制到备库执行,得到的结果和主库肯定不一样,又如USER()调用的用户不同,得到的结果也不同。当然可以通过一些选项,在遇到有些函数时转换成函数的结果复制,但并不是说有的函数都能解决,特别是自定义的函数。基于行的赋值,ROWS_EVENT中还包含修改的“前值”,BinlogMiner就是通过这些“前值”达到闪回的效果。

1. magic number
用于表示二进制日志文件, 4个字节长度, 其值为固定的:0xfe 0x62 0x69 0x6e; 紧接着的是一个个的二进制日志事件。二进制日志的每个事件的结构如下:

2. Common Header

通用文件头, 其实定义了一个事件的基本信息, 包含事件的起止位置, 类型, 时间搓和服务器ID等信息, 我们依赖这些信息特别起止位置来遍历整个二进制日志文件,Common Header的结构如下:

https://dev.mysql.com/doc/internals/en/binlog-event-header.html
Binlog header Payload:
  4  timestamp
  1  event type
  4  server-id
  4  event-size
  if binlog-version > 1:
    4 log pos
    2 flags

可以看到Common Header的长度是固定的13个字节或者19个字节。只有v1版本是13个字节, 后续的版本都是19个字节, 主要是多了log pos, 也就是当前事件的结束位置, v1版本虽然没有结束位置, 但是是可以通过事件的开始位置 + 事件长度(event-size)计算出来的,之所以称为Common Header,是因为这部分是与具体事件无关的。

3. Post-Header
Common Header后紧跟着的是Post-Header部分, Post-Header是跟具体事件相关的,而且并不是每个事件都有Post-Header(可以为0),Post-Header的长度对于一个MySQL版本是固定的,但不同版本可能不同,每种事件的Post-header的长度在FORMAT_DESCRIPTION_EVENT中有记录。

4. PlayLoad
Post-Header后紧跟着负载(playload), 也就是具体的内容,这部分是不固定长度的,直到事件的结束(也就是Checksum)。

以一个QUERY_EVENT的案例来概览一下Post-header和playLoad:
* QUERY_EVENT: The query event is used to send text querys right the binlog.
*
* References:
* https://dev.mysql.com/doc/internals/en/query-event.html
* https://dev.mysql.com/doc/internals/en/event-data-for-specific-event-types.html
*
* Post-header :
*   4  slave_proxy_id
*   4  execution time
*   1  schema length
*   2  error-code
* if binlog-version ≥ 4:
*     2  status-vars length
*
* Payload:
*   string[$len] status-vars
*    string[$len] schema
*   1 [00]
*   string[EOF] query

5. Checksum
也就是事件的校验值, 在MySQL 5.6.2版本开始引入,5.6.6版本开始默认开启(CRC32), 这部分在事件的结尾处, 目前只支持CRC算法,检验值为4个字节,校验算法在FORMAT_DESCRIPTION_EVENT事件中通过1个字节记录。

https://dev.mysql.com/doc/refman/5.6/en/replication-options-binary-log.html#option_mysqld_binlog-checksum

MySQL二进制日志分析-概述篇的更多相关文章

  1. MySQL二进制日志分析-代码实现(FORMAT_DESCRIPTION_EVENT)

    如前文概述,MySQL Binlog v3以前版本, 二进制日志文件的第一个事件是START_EVENT_V3, 从v4版本开始第一个事件为FORMAT_DESCRIPTION_EVENT(以下简称F ...

  2. MySQL二进制日志总结

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

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

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

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

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

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

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

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

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

  7. 删除MySQL二进制日志

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

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

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

  9. shell日志分析进阶篇

    前面我们说了shell分析日志常用指令,现在我们随ytkah一起看看shell日志分析进阶篇,假设日志文件为ytkah.log //统计不重复抓取数量 cat ytkah.log | awk '{pr ...

随机推荐

  1. java学习-NIO(二)Buffer

    当我们需要与 NIO Channel 进行交互时, 我们就需要使用到 NIO Buffer, 即数据从 Buffer读取到 Channel 中, 并且从 Channel 中写入到 Buffer 中.缓 ...

  2. Vue项目中使用better-scroll

    当 better-scroll 遇见 Vue   在我们日常的移动端项目开发中,处理滚动列表是再常见不过的需求了. 以滴滴为例,可以是这样竖向滚动的列表,如图所示: 也可以是横向滚动的导航栏,如图所示 ...

  3. echarts3.x遇到的坑

    此文章用来记录echarts3.x遇到的坑,方便以后自己不再犯. 1.柱形图设置了yAxis.splitArea.show=true,后面设置的splitLine就会变不可见了.也没在官方文档中找到说 ...

  4. HelloDjango 第 07 篇:创作后台开启,请开始你的表演!

    作者:HelloGitHub-追梦人物 文中涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 在此之前我们完成了 django 博客首页视图的编写,我们希望首页展示发布的博客文章列 ...

  5. day01计算机硬件基础

    1.cpu\内存\硬盘 2.存储器 操作系统 是什么 为什么 如何用 1.什么是编程语言: 语言是一个事物与另一个事物沟通的表达方式 编程语言即程序员与计算机沟通的介质 计算机是程序员的奴隶 2.什么 ...

  6. cogs 80. 石子归并 动态规划

    80. 石子归并 ★★   输入文件:shizi.in   输出文件:shizi.out   简单对比时间限制:1 s   内存限制:128 MB 设有N堆沙(shi)子排成一排,其编号为1,2,3, ...

  7. Nacos(八):Nacos持久化

    参考和感谢 Spring Cloud Alibaba基础教程:Nacos的数据持久化 前言 前景回顾: Nacos(七):Nacos共享配置 Nacos(六):多环境下如何"管理" ...

  8. 搭建SFTP服务器,允许一个或多个用户拥有一个或多个目录的rwx权限

    1.引言 sftp可以为传输文件提供一种安全的网络的加密方法.sftp 与 ftp 有着几乎一样的语法和功能.SFTP 为 SSH的其中一部分,是一种传输档案至 Blogger 伺服器的安全方式.其实 ...

  9. 随笔编号-16 MySQL查看表及索引大小方法

    目标:阿里云OS数据库DMS,单个主库最大存储空间为2T.最近公司业务扩展很快,一天数据量达到7.9G左右.要求备份清理历史数据,备份到其他磁盘. 准备: 如果想知道MySQL数据库中每个表占用的空间 ...

  10. 随笔编号-09 批量导入数据(Mysql)报MySQL server has gone away 问题的解决方法

    问题场景: 使用*.sql 脚本,批量导入数据到mysql实例中,使用DOS 界面导入的,期间,到最后一步 source D:\aaa.sql  回车后,系统提示 MySQL server has g ...