当前位置:首页 > 文章列表 > 数据库 > MySQL > 什么是Binlog?浅析MySQL中的Binlog

什么是Binlog?浅析MySQL中的Binlog

来源:SegmentFault 2023-02-24 13:41:38 0浏览 收藏

小伙伴们有没有觉得学习数据库很有意思?有意思就对了!今天就给大家带来《什么是Binlog?浅析MySQL中的Binlog》,以下内容将会涉及到MySQL、binlog,若是在学习中对其中部分知识点有疑问,或许看了本文就能帮到你!

原文地址:https://xcoder.in/2015/08/10/mysql-binlog-try/

  花瓣网的搜索架构需要重构,尤其是在索引建立或者更新层面。

  目前的一个架构导致的结果就是时间越久,数据本体与搜索引擎索引中的数据越不同步,相差甚大。

  新的一个架构打算从 MySQL 的 Binlog 中读取数据更新、删除、新增等历史记录,并把相应信息提取出来丢到队列中慢慢去同步。

  所以我就在这里小小去了解一下 Binlog。

准备工作

什么是 Binlog

  MySQL Server 有四种类型的日志——Error Log、General Query Log、Binary Log 和 Slow Query Log。

  第一个是错误日志,记录 mysqld 的一些错误。第二个是一般查询日志,记录 mysqld 正在做的事情,比如客户端的连接和断开、来自客户端每条 Sql Statement 记录信息;如果你想准确知道客户端到底传了什么瞎 [哔哔] 玩意儿给服务端,这个日志就非常管用了,不过它非常影响性能。第四个是慢查询日志,记录一些查询比较慢的 SQL 语句——这种日志非常常用,主要是给开发者调优用的。

  剩下的第三种就是 Binlog 了,包含了一些事件,这些事件描述了数据库的改动,如建表、数据改动等,也包括一些潜在改动,比如

  • v1,用于 MySQL 3.2.3

  • v3,用于 MySQL 4.0.2 以及 4.1.0

  • v4,用于 MySQL 5.0 以及更高版本

  •   实际上还有一个 v2 版本,不过只在早期 4.0.x 的 MySQL 版本中使用过,但是 v2 已经过于陈旧并且不再被 MySQL 官方支持了。

    通常我们现在用的 MySQL 都是在 5.0 以上的了,所以就略过 v1 ~ v3 版本的 Binlog,如果需要了解 v1 ~ v3 版本的 Binlog 可以自行前往上述的《High-level...》文章查看。

    事件头

      一个事件头有 19 字节,依次排列为四字节的时间戳、一字节的当前事件类型、四字节的服务端 ID、四字节的当前事件长度描述、四字节的下个事件位置(方便跳转)以及两字节的标识。

      用 ASCII Diagram 表示如下:

    +---------+---------+---------+------------+-------------+-------+
    |timestamp|type code|server_id|event_length|next_position|flags  |
    |4 bytes  |1 byte   |4 bytes  |4 bytes     |4 bytes      |2 bytes|
    +---------+---------+---------+------------+-------------+-------+

      也可以字节编造一个结构体来解读这个头:

    c

    struct BinlogEventHeader
    {
        int   timestamp;
        char  type_code;
        int   server_id;
        int   event_length;
        int   next_position;
        char  flags[2];
    };

    如果你要直接用这个结构体来读取数据的话,需要加点手脚。

    因为默认情况下 GCC 或者 G++ 编译器会对结构体进行字节对齐,这样读进来的数据就不对了,因为 Binlog 并不是对齐的。为了统一我们需要取消这个结构体的字节对齐,一个方法是使用

    #pragma pack(n)
    ,一个方法是使用
    __attribute__((__packed__))
    ,还有一种情况是在编译器编译的时候强制把所有的结构体对其取消,即在编译的时候使用
    fpack-struct
    参数,如:

    ```sh
     $ g++ temp.cpp -o a -fpack-struct=1


      根据上述的结构我们可以明确得到各变量在结构体里面的偏移量,所以在 MySQL 源码里面([libbinlogevents/include/binlog_event.h](https://github.com/mysql/mysql-server/blob/5.7/libbinlogevents/include/binlog_event.h#L353))有下面几个常量以快速标记偏移: ```c #define EVENT_TYPE_OFFSET    4 #define SERVER_ID_OFFSET     5 #define EVENT_LEN_OFFSET     9 #define LOG_POS_OFFSET       13 #define FLAGS_OFFSET         17

      而具体有哪些事件则在 libbinlogevents/include/binlog_event.h#L245 里面被定义。如有个

    FORMAT_DESCRIPTION_EVENT
    事件的
    type_code
    是 15、
    UPDATE_ROWS_EVENT
    type_code
    是 31。

      还有那个

    next_position
    ,在 v4 版本中代表从 Binlog 一开始到下一个事件开始的偏移量,比如到第一个事件的
    next_position
    就是 4,因为文件头有一个字节的长度。然后接下去对于事件 n 和事件 n + 1 来说,他们有这样的关系:

    next_position(n + 1) = next_position(n) + event_length(n)

      关于 flags 暂时不需要了解太多,如果真的想了解的话可以看看 MySQL 的相关官方文档

    事件体

      事实上在 Binlog 事件中应该是有三个部分组成,

    header
    post-header
    payload
    ,不过通常情况下我们把
    post-header
    payload
    都归结为事件体,实际上这个
    post-header
    里面放的是一些定长的数据,只不过有时候我们不需要特别地关心。想要深入了解可以去查看 MySQL 的官方文档。

      所以实际上一个真正的事件体由两部分组成,用 ASCII Diagram 表示就像这样:

    +=====================================+
    | event  | fixed part (post-header)   |
    | data   +----------------------------+
    |        | variable part (payload)    |
    +=====================================+

      而这个

    post-header
    对于不同类型的事件来说长度是不一样的,同种类型来说是一样的,而这个长度的预先规定将会在一个“格式描述事件”中定好。
    格式描述事件

      在上文我们有提到过,在 Magic Number 之后跟着的是一个格式描述事件(Format Description Event),其实这只是在 v4 版本中的称呼,在以前的版本里面叫起始事件(Start Event)。

      在 v4 版本中这个事件的结构如下面的 ASCII Diagram 所示。

    +=====================================+
    | event  | timestamp         0 : 4    |
    | header +----------------------------+
    |        | type_code         4 : 1    | = FORMAT_DESCRIPTION_EVENT = 15
    |        +----------------------------+
    |        | server_id         5 : 4    |
    |        +----------------------------+
    |        | event_length      9 : 4    | >= 91
    |        +----------------------------+
    |        | next_position    13 : 4    |
    |        +----------------------------+
    |        | flags            17 : 2    |
    +=====================================+
    | event  | binlog_version   19 : 2    | = 4
    | data   +----------------------------+
    |        | server_version   21 : 50   |
    |        +----------------------------+
    |        | create_timestamp 71 : 4    |
    |        +----------------------------+
    |        | header_length    75 : 1    |
    |        +----------------------------+
    |        | post-header      76 : n    | = array of n bytes, one byte per event
    |        | lengths for all            |   type that the server knows about
    |        | event types                |
    +=====================================+

      这个事件的

    type_code
    是 15,然后
    event_length
    是大于等于 91 的值的,这个主要取决于所有事件类型数。

      因为从第 76 字节开始后面的二进制就代表一个字节类型的数组了,一个字节代表一个事件类型的

    post-header
    长度,即每个事件类型固定数据的长度。

      那么按照上述的一些线索来看,我们能非常快地写出一个简单的解读 Binlog 格式描述事件的代码。

    如上文所述,如果需要正常解读 Binlog 文件的话,下面的代码编译时候需要加上

    -fpack-struct=1
    这个参数。

    cpp
    #include 
    #include 
    
    struct BinlogEventHeader
    {
        int  timestamp;
        unsigned char type_code;
        int  server_id;
        int  event_length;
        int  next_position;
        short flags;
    };
    
    int main()
    {
        FILE* fp = fopen("/usr/local/var/mysql/master-bin.000001", "rb");
        int magic_number;
        fread(&magic_number, 4, 1, fp);
    
        printf("%d - %sn", magic_number, (char*)(&magic_number));
    
        struct BinlogEventHeader format_description_event_header;
        fread(&format_description_event_header, 19, 1, fp);
    
        printf("BinlogEventHeadern{n");
        printf("    timestamp: %dn", format_description_event_header.timestamp);
        printf("    type_code: %dn", format_description_event_header.type_code);
        printf("    server_id: %dn", format_description_event_header.server_id);
        printf("    event_length: %dn", format_description_event_header.event_length);
        printf("    next_position: %dn", format_description_event_header.next_position);
        printf("    flags[]: %dn}n", format_description_event_header.flags);
    
        short binlog_version;
        fread(&binlog_version, 2, 1, fp);
        printf("binlog_version: %dn", binlog_version);
    
        char server_version[51];
        fread(server_version, 50, 1, fp);
        server_version[50] = '
    版本声明
    本文转载于:SegmentFault 如有侵犯,请联系study_golang@163.com删除
    mysql_real_escape_stringmysql_real_escape_string
    上一篇
    mysql_real_escape_string
    MySQL怎么批量插入数据?效率如何?(效率比较)
    下一篇
    MySQL怎么批量插入数据?效率如何?(效率比较)
    查看更多
    最新文章
    查看更多
    课程推荐
    • 前端进阶之JavaScript设计模式
      前端进阶之JavaScript设计模式
      设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
      542次学习
    • GO语言核心编程课程
      GO语言核心编程课程
      本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
      508次学习
    • 简单聊聊mysql8与网络通信
      简单聊聊mysql8与网络通信
      如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
      497次学习
    • JavaScript正则表达式基础与实战
      JavaScript正则表达式基础与实战
      在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
      487次学习
    • 从零制作响应式网站—Grid布局
      从零制作响应式网站—Grid布局
      本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
      484次学习
    查看更多
    AI推荐
    • 笔灵AI生成答辩PPT:高效制作学术与职场PPT的利器
      笔灵AI生成答辩PPT
      探索笔灵AI生成答辩PPT的强大功能,快速制作高质量答辩PPT。精准内容提取、多样模板匹配、数据可视化、配套自述稿生成,让您的学术和职场展示更加专业与高效。
      13次使用
    • 知网AIGC检测服务系统:精准识别学术文本中的AI生成内容
      知网AIGC检测服务系统
      知网AIGC检测服务系统,专注于检测学术文本中的疑似AI生成内容。依托知网海量高质量文献资源,结合先进的“知识增强AIGC检测技术”,系统能够从语言模式和语义逻辑两方面精准识别AI生成内容,适用于学术研究、教育和企业领域,确保文本的真实性和原创性。
      22次使用
    • AIGC检测服务:AIbiye助力确保论文原创性
      AIGC检测-Aibiye
      AIbiye官网推出的AIGC检测服务,专注于检测ChatGPT、Gemini、Claude等AIGC工具生成的文本,帮助用户确保论文的原创性和学术规范。支持txt和doc(x)格式,检测范围为论文正文,提供高准确性和便捷的用户体验。
      30次使用
    • 易笔AI论文平台:快速生成高质量学术论文的利器
      易笔AI论文
      易笔AI论文平台提供自动写作、格式校对、查重检测等功能,支持多种学术领域的论文生成。价格优惠,界面友好,操作简便,适用于学术研究者、学生及论文辅导机构。
      38次使用
    • 笔启AI论文写作平台:多类型论文生成与多语言支持
      笔启AI论文写作平台
      笔启AI论文写作平台提供多类型论文生成服务,支持多语言写作,满足学术研究者、学生和职场人士的需求。平台采用AI 4.0版本,确保论文质量和原创性,并提供查重保障和隐私保护。
      35次使用
    微信登录更方便
    • 密码登录
    • 注册账号
    登录即同意 用户协议隐私政策
    返回登录
    • 重置密码