binlog的存储结构是什么样子的?

1 个回答

  • 小鹏王
    在漆黑的夜里,你需要一道光照亮夜行的路,我燃烧了我自己,但也造就了你我不能相拥。
    Binlog(Binary Log)是 MySQL 记录所有更改数据的事务日志文件,主要用于 **主从复制** 和 **数据恢复**。它的存储结构大致如下: ### 1. **Binlog 文件结构** Binlog 是由多个 **事件(Event)** 组成的,每个事件记录了一次数据库变更的具体信息。其文件结构如下: ``` +-----------------+ | File Header | # 文件头,固定 4 字节 +-----------------+ | Event 1 | # 第一个事件 +-----------------+ | Event 2 | # 第二个事件 +-----------------+ | ... | # 更多事件 +-----------------+ | Event N | # 最后一个事件 +-----------------+ ``` #### **(1) Binlog 文件头(File Header)** - 长度:固定 4 字节 (`0xFE 0x62 0x69 0x6E`,即 `FEbin`,标识 Binlog 文件) - 主要用于标识文件格式,确保 MySQL 服务器能正确解析 Binlog。 #### **(2) 事件(Event)** 每个 **Event** 由 **事件头(Event Header)+ 事件体(Event Body)** 组成: ##### **a. 事件头(Event Header)** - 长度:19 字节(在 MySQL 5.6 之前是 13 字节) - 结构: | 字节数 | 字段名 | 说明 | |--------|---------------|------| | 4 | Timestamp | 事件发生的时间戳 | | 1 | Event Type | 事件类型(如事务开始、表结构修改、数据变更等) | | 4 | Server ID | 服务器 ID,用于区分不同 MySQL 实例 | | 4 | Event Size | 事件总大小(包括头部+数据) | | 4 | Log Position | 下一个事件的偏移量(用于复制) | | 2 | Flags | 事件的标志位(是否是事务结尾等) | ##### **b. 事件体(Event Body)** - 记录具体的 SQL 操作,比如 `INSERT`、`UPDATE`、`DELETE`,以及表的元数据信息。 ### 2. **常见的 Binlog 事件类型** Binlog 事件用于记录各种 SQL 操作,常见事件如下: | 事件类型 | 说明 | |----------------------|------| | **Format_description_event** | Binlog 版本信息 | | **Query_event** | `CREATE TABLE`、`ALTER TABLE` 等 DDL 语句 | | **Xid_event** | 事务提交 (`COMMIT`) | | **Table_map_event** | 记录表的元数据,后续 `Write_rows_event` 依赖 | | **Write_rows_event** | `INSERT` 记录 | | **Update_rows_event** | `UPDATE` 记录 | | **Delete_rows_event** | `DELETE` 记录 | | **Rotate_event** | 记录 Binlog 轮转信息(新文件开始) | | **Previous_gtids_event** | 记录 GTID 信息 | ### 3. **Binlog 的存储格式** Binlog 支持三种格式: 1. **Statement-based(SBR)**:记录 SQL 语句本身 2. **Row-based(RBR)**:记录数据变更的具体行数据(推荐) 3. **Mixed(MIXED)**:SBR 和 RBR 结合 **示例(Row-based)** ``` Table_map_event: table_id=123 (users) Write_rows_event: table_id=123 (users) (id=1, name='Alice') ``` 这表示 `users` 表的 `id=1` 这一行插入了 `name='Alice'` 的数据。 ### 4. **Binlog 轮转(Rotation)** 当 Binlog 文件达到 `max_binlog_size`,MySQL 会自动创建新的 Binlog 文件,如: ``` mysql-bin.000001 mysql-bin.000002 mysql-bin.000003 ``` `Rotate_event` 事件会指向下一个 Binlog 文件。 ### 5. **Binlog 的索引文件** MySQL 还维护一个 **binlog 索引文件(`mysql-bin.index`)**,其中记录了所有 Binlog 文件: ``` /var/lib/mysql/mysql-bin.000001 /var/lib/mysql/mysql-bin.000002 /var/lib/mysql/mysql-bin.000003 ``` 这个索引文件用于 **恢复数据** 和 **主从复制**。 ### 6. **Binlog 示例** 可以使用 `mysqlbinlog` 工具解析 Binlog: ```sh mysqlbinlog --base64-output=DECODE-ROWS --verbose mysql-bin.000001 ``` 示例输出(Row-based): ``` # at 789 #200325 10:15:27 server id 1 end_log_pos 891 CRC32 0xe5b2a569 Table_map: table_id=51 (test.users) # at 891 #200325 10:15:27 server id 1 end_log_pos 999 CRC32 0xcad2e234 Write_rows: table_id=51 flags=STMT_END_F ### INSERT INTO `test`.`users` ### SET ### @1=1 ### @2='Alice' ``` ### 7. **Binlog 在主从复制中的作用** - **主库(Master)** 记录 Binlog,Binlog 事件通过 `IO Thread` 传输到从库(Slave)。 - **从库(Slave)** 使用 `SQL Thread` 解析 Binlog 并执行相应的 SQL 变更。 示意图: ``` Master: Binlog --> Relay Log --> Slave SQL Thread 执行 ``` ### 8. **总结** - Binlog 由 **文件头 + 一系列事件** 组成。 - 每个事件包括 **事件头(Event Header)+ 事件体(Event Body)**。 - 支持 **Statement、Row、Mixed** 三种格式。 - 主要用于 **主从复制** 和 **数据恢复**。 - 可以使用 `mysqlbinlog` 解析和查看 Binlog 内容。
    编辑于 2025-03-11 20:44 •IP属地 美国
    举报
    评论
    收藏