解析MYSQL BINLOG 二进制格式(1)--准备工作

本文涉及的产品
RDS MySQL DuckDB 分析主实例,基础系列 4核8GB
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
RDS AI 助手,专业版
简介: 原创:转载请说明出处谢谢! 参考源: 1、源码log_event.h log_event.cc pack.c 2、internals-en.epub 一、目的    本系列文件主要为了说明 1、为什么说row格式较statement更占空间 2、为什么说...
原创:转载请说明出处谢谢!

参考源:
1、源码log_event.h log_event.cc pack.c
2、internals-en.epub


一、目的
   本系列文件主要为了说明
1、为什么说row格式较statement更占空间
2、为什么说row格式的binlog更加安全
3、INSERT/UPDATE/DELETE是生成的row binlog如何直接看懂二进制格式
4、DDL生成的binlog是怎么样的
5、INSERT SELECT/CREATE TABLE 如何生成的row binlog

二、使用版本和数字显示
本系列文章重要解释MYSQL 5.6后row格式的binlog格式以及和事物有关的event,按照官方的说法
binlog的格式经历了几个阶段
v1:mysql 3.23
v3:mysql 4.0.2 到 4.1
v4:mysql 5.0以上
v2版本只是短暂的存在过,当然我们要解析当然是v4版本的binlog
因为要看是5.6以上的binlog
关于多字节的数字显示,一般使用 Little-endian模式,做到和OS系统无关,除非刻意说明
关于Little-endian参考:
http://blog.itpub.net/7728585/viewspace-2124159/
三、binlog的魔法数
关于MYSQL BINLOG的作用就不做过多的解析了,在binlog中存储的是一种称之为event的条目,
它们以二进制的格式存储,平时我们使用的mysqlbinlog工具也就是对这种二进制格式的文件
进行解析,得到直观的输出。这里不用mysqlbinlog而改为直接看二进制文件,当然我会对比
MYSQLBINLOG的输出和二进制解析的过程
每一个binlog文件都有4字节的魔法数,其值固定为
[root@testmy mysqld.1]# hexdump -Cv test.000005 
可以看到
fe 62 69 6e .bin

四、binlog event的总体构架
一个event包括了
event header
event data
其中event data又分为
fixed data(posted header)
variable data

event header:全部的event统一固定的格式
fixed data(posted header):每一类event固定
variable data:就是可以变化实际值了

关于event的类型比较多详细参考末尾源码的截取

五、本系列文章要讨论的event
而这里我们只要讨论5.6,5.7中和row binlog格式和innodb
联系比较紧密的几种event如下:
query_log_event/QUERY_EVENT typecode=02
Format_description_log_event/FORMAT_DESCRIPTION_EVENT  typecode=15
Xid_log_event/XID_EVENT  typecode=16
Table_map_log_event/TABLE_MAP_EVENT typecode=19
Write_rows_log_event/WRITE_ROW_EVENT typecode=30
Update_rows_log_event/UPDATE_ROW_EVENT typecode=31 
Delele_rows_log_event/DELETE_ROW_EVENT typecode=32 

因为这些语句是一个事物必须经历的,而Format_description_log_event是一个最重要的
说明性的event

六、通用头文件(event header)解析
下面先解释一下通用的19个字节。
每一个event有一个固定的头信息叫做event header:
event header
timestamp        0:4             
type_code        4:1  
server_id           5:4
event_length     9:4
next_position    13:4
flags                 17:2             


timestamp:固定4字节展示是新纪元(epoch time)以来的秒数
type_code:固定1字节event事件的编码,在源码中是一个enum类型负载最后源码处
server_id:固定4字节就是 show variables like '%server_id';出来的值
event_length:固定4字节整个event的长度,包含固定和非固定长度
next_position:固定4字节下一个event的开始位置(2^32为4G)
flags:固定2字节 event flags
      LOG_EVENT_BINLOG_IN_USE_F   0x1 这个flags表示是否binlog正确的关闭了,这个标示只出现在Format_description_log_event中
      LOG_EVENT_THREAD_SPECIFIC_F 0x4 是否查询基于了临时表,如果基于了临时表MYSQLBINLOG必须设置 @@PSEUDO_THREAD_ID=xx
      LOG_EVENT_SUPPRESS_USE_F    0x8 和--binlog-do-db 、 --replicated-do-db有关
      其他还有很多
      LOG_EVENT_ARTIFICIAL_F 0x20 LOG_EVENT_RELAY_LOG_F 0x40 LOG_EVENT_IGNORABLE_F 0x80 LOG_EVENT_NO_FILTER_F 0x100 。。。
      可以自行参考log_event.h源码头文件中的详细解释
      
七、packed interger
在binlog中部分数字使用这种方式显示,在后面的解析中会提到
按照文档和源码中的说明
如果第一个字节为0-250及0X0-0XFA那么这个字节就是实际显示的数字值
源码的:
  if (length < (ulonglong) LL(251))
  {
    *packet=(uchar) length;
    return packet+1;
  }
如果第一个字节为252及0XFC那么后面的2个字节的值为0XFB-0XFFFF
源码的:
if (length < (ulonglong) LL(65536))
  {
    *packet++=252;
    int2store(packet,(uint) length);
    return packet+2;
  }
如果第一个字节为253及0XFD那么后面的3个字节的值为0XFFFF-0XFFFFFF
源码的:
if (length < (ulonglong) LL(16777216))
  {
    *packet++=253;
    int3store(packet,(ulong) length);
    return packet+3;
  }
如果第一个字节为254及0XFE那么后面的8个字节的值为0XFFFFFF-0XFFFFFFFFFFFFFFFF
  *packet++=254;
  int8store(packet,length);

可以自行参考源码接口,函数返回值为一个下一个位置的指针
uchar *net_store_length(uchar *packet, ulonglong length)


点击(此处)折叠或打开

  1. enum Log_event_type
  2. {
  3.   /**
  4.     Every time you update this enum (when you add a type), you have to
  5.     fix Format_description_event::Format_description_event().
  6.   */
  7.   UNKNOWN_EVENT= 0,
  8.   START_EVENT_V3= 1,
  9.   QUERY_EVENT= 2,
  10.   STOP_EVENT= 3,
  11.   ROTATE_EVENT= 4,
  12.   INTVAR_EVENT= 5,
  13.   LOAD_EVENT= 6,
  14.   SLAVE_EVENT= 7,
  15.   CREATE_FILE_EVENT= 8,
  16.   APPEND_BLOCK_EVENT= 9,
  17.   EXEC_LOAD_EVENT= 10,
  18.   DELETE_FILE_EVENT= 11,
  19.   /**
  20.     NEW_LOAD_EVENT is like LOAD_EVENT except that it has a longer
  21.     sql_ex, allowing multibyte TERMINATED BY etc; both types share the
  22.     same class (Load_event)
  23.   */
  24.   NEW_LOAD_EVENT= 12,
  25.   RAND_EVENT= 13,
  26.   USER_VAR_EVENT= 14,
  27.   FORMAT_DESCRIPTION_EVENT= 15,
  28.   XID_EVENT= 16,
  29.   BEGIN_LOAD_QUERY_EVENT= 17,
  30.   EXECUTE_LOAD_QUERY_EVENT= 18,

  31.   TABLE_MAP_EVENT = 19,

  32.   /**
  33.     The PRE_GA event numbers were used for 5.1.0 to 5.1.15 and are
  34.     therefore obsolete.
  35.    */
  36.   PRE_GA_WRITE_ROWS_EVENT = 20,
  37.   PRE_GA_UPDATE_ROWS_EVENT = 21,
  38.   PRE_GA_DELETE_ROWS_EVENT = 22,

  39.   /**
  40.     The V1 event numbers are used from 5.1.16 until mysql-trunk-xx
  41.   */
  42.   WRITE_ROWS_EVENT_V1 = 23,
  43.   UPDATE_ROWS_EVENT_V1 = 24,
  44.   DELETE_ROWS_EVENT_V1 = 25,

  45.   /**
  46.     Something out of the ordinary happened on the master
  47.    */
  48.   INCIDENT_EVENT= 26,

  49.   /**
  50.     Heartbeat event to be send by master at its idle time
  51.     to ensure master's online status to slave
  52.   */
  53.   HEARTBEAT_LOG_EVENT= 27,

  54.   /**
  55.     In some situations, it is necessary to send over ignorable
  56.     data to the slave: data that a slave can handle in case there
  57.     is code for handling it, but which can be ignored if it is not
  58.     recognized.
  59.   */
  60.   IGNORABLE_LOG_EVENT= 28,
  61.   ROWS_QUERY_LOG_EVENT= 29,

  62.   /** Version 2 of the Row events */
  63.   WRITE_ROWS_EVENT = 30,
  64.   UPDATE_ROWS_EVENT = 31,
  65.   DELETE_ROWS_EVENT = 32,

  66.   GTID_LOG_EVENT= 33,
  67.   ANONYMOUS_GTID_LOG_EVENT= 34,

  68.   PREVIOUS_GTIDS_LOG_EVENT= 35,

  69.   TRANSACTION_CONTEXT_EVENT= 36,

  70.   VIEW_CHANGE_EVENT= 37,

  71.   /* Prepared XA transaction terminal event similar to Xid */
  72.   XA_PREPARE_LOG_EVENT= 38,
  73.   /**
  74.     Add new events here - right above this
  75.     Existing events (except ENUM_END_EVENT) should never change their numbers
  76.   */
  77.   ENUM_END_EVENT /* end marker */
  78. };


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
6月前
|
SQL 运维 关系型数据库
深入探讨MySQL的二进制日志(binlog)选项
总结而言,对MySQL binlogs深度理解并妥善配置对数据库运维管理至关重要;它不仅关系到系统性能优化也是实现高可靠性架构设计必须考虑因素之一。通过精心规划与周密部署可以使得该机能充分发挥作用而避免潜在风险带来影响。
202 6
|
7月前
|
存储 SQL 关系型数据库
MySQL中binlog、redolog与undolog的不同之处解析
每个都扮演回答回溯与错误修正机构角色: BinLog像历史记载员详细记载每件大大小小事件; RedoLog则像紧急救援队伍遇见突發情況追踪最后活动轨迹尽力补救; UndoLog就类似时间机器可倒带历史让一切归位原始样貌同时兼具平行宇宙观察能让多人同时看见各自期望看见历程而互不干扰.
405 9
|
8月前
|
存储 SQL 关系型数据库
MySQL的Redo Log与Binlog机制对照分析
通过合理的配置和细致的管理,这两种日志机制相互配合,能够有效地提升MySQL数据库的可靠性和稳定性。
265 10
|
10月前
|
SQL 监控 关系型数据库
MySQL日志分析:binlog、redolog、undolog三大日志的深度探讨。
数据库管理其实和写小说一样,需要规划,需要修订,也需要有能力回滚。理解这些日志的作用与优化,就像把握写作工具的使用与运用,为我们的数据库保驾护航。
575 23
|
11月前
|
SQL 运维 关系型数据库
MySQL Binlog 日志查看方法及查看内容解析
本文介绍了 MySQL 的 Binlog(二进制日志)功能及其使用方法。Binlog 记录了数据库的所有数据变更操作,如 INSERT、UPDATE 和 DELETE,对数据恢复、主从复制和审计至关重要。文章详细说明了如何开启 Binlog 功能、查看当前日志文件及内容,并解析了常见的事件类型,包括 Format_desc、Query、Table_map、Write_rows、Update_rows 和 Delete_rows 等,帮助用户掌握数据库变化历史,提升维护和排障能力。
|
存储 SQL 关系型数据库
mysql的undo log、redo log、bin log、buffer pool
MySQL的undo log、redo log、bin log和buffer pool是确保数据库高效、安全和可靠运行的关键组件。理解这些组件的工作原理和作用,对于优化数据库性能和保障数据安全具有重要意义。通过适当的配置和优化,可以显著提升MySQL的运行效率和数据可靠性。
225 4
|
SQL 存储 关系型数据库
简单聊聊MySQL的三大日志(Redo Log、Binlog和Undo Log)各有什么区别
在MySQL数据库管理中,理解Redo Log(重做日志)、Binlog(二进制日志)和Undo Log(回滚日志)至关重要。Redo Log确保数据持久性和崩溃恢复;Binlog用于主从复制和数据恢复,记录逻辑操作;Undo Log支持事务的原子性和隔离性,实现回滚与MVCC。三者协同工作,保障事务ACID特性。文章还详细解析了日志写入流程及可能的异常情况,帮助深入理解数据库日志机制。
1498 0
|
6月前
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
469 158
|
6月前
|
关系型数据库 MySQL 数据库
自建数据库如何迁移至RDS MySQL实例
数据库迁移是一项复杂且耗时的工程,需考虑数据安全、完整性及业务中断影响。使用阿里云数据传输服务DTS,可快速、平滑完成迁移任务,将应用停机时间降至分钟级。您还可通过全量备份自建数据库并恢复至RDS MySQL实例,实现间接迁移上云。
|
6月前
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
1116 152

推荐镜像

更多