zoukankan      html  css  js  c++  java
  • 有关binlog的那点事(二)(mysql5.7.13)

    上次,我们仅仅把binlog做了一个概述,并没有去深入探索(1)binlog file究竟是怎么构成的?(2)binlog file的单元binlog events是怎么构成的?(3)我们能不能伪造出一个mysqlbinlog识别的binlog file? 当然,第三个问题看起来很cool,蛮有挑战性的。

    这次我们讨论的是第4版本的binlogfile, 一般5.0.x以上的mysql使用该版本的binlogfile。

    首先回答第一个问题

    一、binlog file的构成

    (1)binlog file的大致构成

    这个问题其实之前也回答过,但是很不深入。这次,我会深度探索它,首先我们扒一扒官方的说法;

    http://dev.mysql.com/doc/internals/en/binlog-file.html

    这块就说了一句话:binlog file是由binlog file header和binlog events构成的,至于binlog file header其实就是0xfe62696e。换言之,binlog file先写了个0xfe62696e,然后后面跟着许多binlog event 。官方的文档还是很给力的,我们可以打开任意一个binlog file,以16进制形式打开,开头就是0xfe62696e。

    (2)binlog events的组织方式

    许多binlog event是否存在着自己的组织方式呢?答案是肯定的,跟在binlog file header后面的一般先是Binlog::FORMAT_DESCRIPTION_EVENT,这是第4版本的binlog event的开头,这个会在本文的"二、binlog events的构成"中详细提到。

    紧接着一般是事务性的binlog events,要强调的是,在binlog file里所有的update, delete, insert语句都是存在于一组事务性的binlog event。

    事务性的binlog events的格式如下(SQL代表任一SQL语句,当然一般只包含select,update, delete, insert语句,不包括ddl语句):

    sql语句形式 statement格式   row格式
    / Anonymous_gtid_event     Anonymous_gtid_event    
    BEGIN      Query_event(BEGIN)  Query_event(BEGIN) 
    SQL Query_event(SQL)    Table_map_event & Rows_event      
    SQL Query_event(SQL)     Table_map_event & Rows_event
    ...... ...... ......
    COMMIT                      Xid_event   Xid_event 

     

     

     

     

     

     

     

    至于mixed格式就是statement格式 和row格式交替出现,三种格式的不同也就在这个上面,至于上面看到的binlog events的格式,我们将在本文的"二、binlog events的构成"中详细提到。

    最后会以STOP_EVENT或者ROTATE_EVENT结尾,这两个也会在本文的"二、binlog events的构成"中详细提到。

    其他的一些binlog event不是特别重要,有兴趣的可以通过

    http://dev.mysql.com/doc/internals/en/binlog-event.html去了解

     二、binlog event的构成

     (1)binlog event的构成

    binlog event分为四部分:common header, post header, body以及footor,翻译能力有限,不知道怎么翻译,但是只要明白就好,common header和footor是共有的,而post header, body则是每个event都独有的。

    common header 一般包含下面几个

    名称 格式 描述
    when 4字节整形 事件发生的时间,从1970年开始到现在的秒数
    type_code 1字节整形 binglog event的类型
    unmasked_server_id 4字节整形 服务器id
    data_written 4字节整形 binglog event的长度,即common header的长度 + post header的长度 + body的长度+4
    log_pos 4字节整形 下一个binglog event在文件中的位置
    flags 2字节整形 binglog 的版本号

     

     

     

     

     

     

     

    footor则包含一个crc32校验码,它的格式是4字节的整形。

    (2)重要的binlog event的构成

    1)FORMAT_DESCRIPTION_EVENT

    参考自http://dev.mysql.com/doc/internals/en/format-description-event.html

    body:

    名称 格式 描述
    binlog-version 2字节整形 binlog的版本,一般为4
    mysql-server version 50字节字符串 mysql数据库的版本
    create timestamp 4字节整形 创建时间
    event header length 1字节整形 common header的长度,一般为19
    event type header lengths EOF型字符串 各种binlog event的post header的长度

     

     

     

     

     

     

     

    2)Xid_event

    参考自http://dev.mysql.com/doc/internals/en/xid-event.html

    body:

    名称 格式 描述
    XID 8字节整形 提交的事务id

     

     

     

    3) Anonymous_gtid_event

    没有可以参考的网站

    post header:

    名称 格式 描述
    commit flag 1字节整形 是否提交,1代表提交,0代表没有提交
    ENCODED SID 16字节整形 一般为0
    ENCODED GNO 8字节整形 一般为0
    TS_TYPE 1字节整形 一般为2

     

     

     

     

     

    body:

    名称 格式 描述
    last_committed 8字节整形 上一次提交的序列号
    sequence_number 8字节整形 本次的序列号

     

     

     

     

    4)STOP_EVENT

    参考自http://dev.mysql.com/doc/internals/en/stop-event.html

    没有post header和body

    5)ROTATE_EVENT

    参考自http://dev.mysql.com/doc/internals/en/rotate-event.html

    post header:

    名称 格式 描述
    position 8字节整形 下一个binlog event的位置

     

     

     

     

    body:

    名称 格式 描述
    name of the next binlog 字符串 下一个binlog event所在的文件名

     

     

     

     

    6)Table_map_event 

    参考自http://dev.mysql.com/doc/internals/en/table-map-event.html

    post header

    名称 格式 描述
    table id 4字节整形 表id,在mysql数据库中每个表都有一个唯一的id标识
    flgas 2字节整形 当前保留,为以后使用

     

     

     

     

    body:

    名称 格式 描述
    schema name length 1字节整形 数据库名长度
    schema name NULL字符串 数据库名
    table name length 1字节整形 表名长度
    table name NULL字符串 表名
    column-count 可变的整形 列数量
    column-def 字符串 描述每列的数据类型
    column-meta-def 字符串 描述每列的元数据
    NULL-bitmask 字符串 描述每列的是不是可以为空

     

     

     

     

     

     

     

     

     

    7)ROWS_EVENT

    参考自http://dev.mysql.com/doc/internals/en/rows-event.html

    post header

    名称 格式 描述
    table id 4字节整形 表id,在mysql数据库中每个表都有一个唯一的id标识
    flgas 2字节整形 当前保留,为以后使用

    body

    名称 格式 描述
    var_header_len 4字节整形 表的列数
    columns_before_image 字符串 被使用列的比特值,例如,表有3列,只有第1列和第3列被使用,则该值为0xfa,只有第1列和第2列被使用,则该值为0xfc
    columns_after_image 字符串 仅用于update命令,即更新后的情况是在这里获取的,delete和insert都没有该项
    row 字符串

    string.var_len nul-bitmap, length (bits set in 'columns-present-bitmap1'+7)/8
    string.var_len value of each field as defined in table-map
    这里的包含每一个行,每一行含有 nul-bitmap代表已使用的列是否为null,然后紧接着是数据value of each field as defined in table-map

    8) QUERY_EVENT

    参考自http://dev.mysql.com/doc/internals/en/query-event.html

    post header

    名称 格式 描述
    slave_proxy_id 4字节整形 从机代理id
    execution time 4字节整形 执行时间
    schema length 1字节整形 数据库名长度
    error-code 2字节整形 错误码
    status-vars length 2字节整形 状态长度

    body

    名称 格式 描述
    status-vars 字符串 执行sql语句的mysql的环境变量
    schema NULL字符串 数据库名
    query EOF字符串 SQL语句

    三、伪造的binlog文件

    现在通过上面的介绍,我们已经能伪造我们的binlog文件,只不过我们只能伪造statement格式下的binlog,因为row模式下的binlog是需要sql执行时的真实数据的。

    四、补充:

    1.INTVAR_EVENT

    对于写入带有自增列的表时,binlog会在statement模式下增加一个事件,就是INTVAR_EVENT,他会规定插入的语句的自增列数,一般出现在BEGIN的Query_event之后,出现在普通的Query_event之前,mysqlbinlog会把它解析成"SET INSERT_ID = 自增id"语句后

    我们可以看到他的格式如图所示

    body

    名称 格式 描述
    type 1字节整形 代表INTVAR_EVENT的类型
    value 8字节整形 自增id

    关于type类型,我们已经确认的是在上述的情况中类型是INSERT_ID_EVENT,而其他两种类型INVALID_INT_EVENT和LAST_INSERT_ID_EVENT还没有出现过,为此这是待确认的事件,以后补充。

  • 相关阅读:
    销售人员个人提升经典书籍推荐
    销售必看的书籍推荐
    我在公司敲代码,你却在家和老王………————程序员的那些梗
    某程序员动了公司的祖传代码"屎山",半年后怒交辞职报告!
    为什么说程序员的前三年不要太看重工资水平?
    好的员工关系应该是怎样的?
    粒子群优化算法(PSO)python 3实现
    Python基础篇-安装python
    Python设置matplotlib.plot的坐标轴刻度间隔以及刻度范围
    空TreeList添加节点不显示
  • 原文地址:https://www.cnblogs.com/onlyac/p/6043595.html
Copyright © 2011-2022 走看看