show master status 命令,此命令中回带回当前最新 binlog 存储在哪个文件,以及对应哪个偏移量。如果想从当前开始接收 binlog, 则在后面发送 binlog dump 命令的时候用这两个值就好。show global variables like 'binlog_checksum' 命令,这是由于 binlog event 发送回来的时候需要,在最后获取 event 内容的时候,会增加 4 个额外字节做校验用。mysql5.6.5 以后的版本中 binlog_checksum=crc32, 而低版本都是 binlog_checksum=none。如果不想校验,可以使用 set 命令设置 set binlog_checksum=none当客户端向服务端发送 COM_BINLOG_DUMP 指令后, MySQL 服务端便开始向客户端以字节流的形式传送 Binlog, 对于 Statement-Based Binlog, 日志是由事件序列构成的, 事件有多种类型, 具体的事件列表可以参看 Binlog-EventType, MySQL 服务端在传送 Binlog 时, 会在每个事件前面添加 0x00 这样一个分界符字节, 每个事件都由事件头和主体构成, 主体进一步分为固定部分和可变部分, 因此也可以理解为事件是由三部分构成的, 事件头(EventHeader), 主体的固定部分(PostHeader) 和主体的可变部分(Payload), 所有的 Binlog 文件都是以固定的 4 字节开头, 这 4 个字节分别是 0xfe 0x62 0x69 0x6e, 即 0xfe 'b''i''n', 在解析 Binlog 数据时, 如果开头不是这 4 个字节可以认为数据是非法的或者文件已损坏, 在 Binlog 文件中, 第一个事件比较特殊, 在早期版本的 MySQL 中, 第一个事件是 START_EVENT_V3 事件, 记录了 Binlog 的版本, MySQL 服务端的版本以及文件创建的时间戳等, 在 MySQL 5.0 之后, 使用 FORMAT_DESCRIPTION_EVENT 来替代 START_EVENT_V3 结构, FORMAT_DESCRIPTION_EVENT 拥有比 START_EVENT_V3 更丰富的字段信息, 并具有扩展性, 除了在 START_EVENT_V3 中的诸如 Binlog 版本、MySQL Server 版本以及时间戳之外, 还描述了每种事件类型对应的事件头(EventHeader)的长度, 客户端可以根据这些信息来解码读取对应的事件类型, 在 MySQL 服务端, Binlog 是以普通二进制文件存放的, 它们的名字形如 mysql-bin.NNNNNN(如 mysql-bin.000001、mysql-bin.000002 等)每个 Binlog 文件都有最大限制, 可以在 MySQL 的配置文件中设置单个 Binlog 的最大长度, 当 Binlog 文件长度超过特定的限制后, MySQL Server 便会创建一个新的 Binlog 文件并继续保存相应的日志(另外当执行 FLUSH LOGS 时也会新创建 Binlog 文件), 除了日志文件本身, MySQL Server 还维护了一个 mysql-bin.index 文件, 该文件是用文本形式存放的, 记录了当前已有的 Binlog 文件名。
整个主从同步过程是这样的, MySQL Server 当有数据变更时会将数据按设定的格式写入到形如 mysql-bin.NNNNNN 的文件中, 当接收到 Slave 的 DUMP 请求后, Server 端便开启 Dump Thead, 用于并发地读取 Binlog 文件内容并发送给 Slave, 而 Slave 设置了一个 IO Thread 来接收客户端发来的字节流, 并其写入到 Relay log 中, Relay log 与 Binlog 的格式完全相同, 所以 IO Thread 其实并不会对数据做任何修改, 只是单纯地读取字节流并写入本地文件, Relay log 设置的目的是为了缓冲, 若没有 Relay log, 则 Slave 必须以完全同步的方式接收并执行 Master 发来的数据, 同时在 Slave 端也设置了一个 SQL Thread 它并发地读取 Relay Log, 并将数据应用到数据库中, 整个过程可以用如下的图示来描述。
在 MySQL 协议中数据类型只有两大类, 分别是整数(Integers) 和字符串(Strings), 这两种数据类型又会分为多个更小的数据类型, 对于整数类型, 可以进一步分为定长整数(Fixed-Length Integer) 和长度编码型整数(Length-Encoded Integer), 对于定长整数, 顾名思义, 其长度是固定的, 定长整数有 int<1>、int<2>、int<3>、int<4>、int<6>、int<8> 共 6 种, 定长整数都是以小端字节序存放的, 即最低有效位在前, 举例来说, 对于 int<4> 的数字 2, 其字节概况为 10 00 00 00; 而长度编码型整数, 它所占用的字节数不是固定的, 取决于值的大小, 记为 int
详情参考 MySQL 官方文档:https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_dt_integers.html
字符串类型(Strings) 是字节序列构成的数据类型, 它可以细分为固定长度的字符串 string
详情参考 MySQL 官方文档:https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_dt_strings.html
MySQL 的客户端和服务端交互是以数据包(Packet) 为单位进行的, 每个包的大小长度有限制, 最长为 224−1224−1 个字节(即 16MB), 若包长度过大, 则客户端需要自行将包分片, 使得每段的长度在 MySQL 包的最大长度之下, MySQL Packet 由 Header 和 Body 组成, Header 包含两个字段: 包长度(payload_length)、序列号(sequence_id), Body 则是包的主体部分, 它的长度由 Header 中的 payload_length 字段指示, 包长度字段固定使用 int<3> 类型, 序列号固定使用 int<1> 类型, 当客户端和服务端开始交互时, 由客户端初始化 0 序列号, 之后每次交互, 数据发出方都基于前一个 sequence_id 增一, sequence_id 不是恒定唯一的, 当交互次数足够多后, 它会重新回到 0, MySQL 的 Packet 可以用如下所示的图来直观表示。
详情参考 MySQL 官方文档:https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_basic_packets.html#sect_protocol_basic_packets_packet
binlog 报文由 Event Header 和 Event Body 组成。
Event Header 结构:
下面会介绍几种不同类型的 Event Body 。
「Rotate Event」
当MySql的binlog文件从file1滚动到file2的时候会发生此事件,会在文件末尾写入 ROTATE_EVENT,指向序列中的下一个文件。该事件是让从属设备知道它将要接收的下一个二进制日志的名称的信息。
「TableMap Event」
在基于行的模式下,每个行操作事件之前都有一个 Table_map_event , 也就是在任何的行变更之前都会记录一个 TableMapEvent。会记录那个数据库的那张表发生了行变更。
「FORMAT_DESCRIPTION Event」
MySQL Binlog v3以前版本, 二进制日志文件的第一个事件是START_EVENT_V3, 从v4版本开始第一个事件为FORMAT_DESCRIPTION_EVENT(以下简称FD事件),替代掉START_EVENT_V3。具体到MySQL服务器版本来说,MySQL 5.0以前版本二进制日志的第一个事件是START_EVENT_V3,而后续版本的第一个事件都是FD事件。
「XID Event」
XID 事件是为修改支持 XA 的存储引擎的一个或多个表的事务提交而生成的。
「QUERY Event」
Rows查询事件类型,它是Ignorable_event的子类,用于在RBR中记录原始查询的rows事件。
「Write Rows Event」
插入行时触发该事件。
「Update Rows Event」
有行更新时触发该事件。
「Delete Rows Event」
有行删除时触发该事件。
「GTID Event」
GTID 代表 Global Transaction IDentifier 它由两部分组成:
SID 表示源标识符,以及 GNO 代表组号。基本思想是 将标识符(全局事务标识符或 GTID)关联到每个事务。当事务被复制到从属设备、在从属设备上重新执行并写入从属设备的二进制日志时,GTID 会被保留。当从站连接到主站时,从站使用GTID而不是(文件,偏移量)。
其它还有很多中类型的事件详情参考 :https://dev.mysql.com/doc/dev/mysql-server/latest/namespacemysql_1_1binlog_1_1event.html
欢迎加入 DevXTalk 的技术交流群,在这里你可以和大佬们一起交流分享技术,行业经验,提升自我。结识新的业内朋友,扩大自己的圈子,当你想换工作的时候也许就能拿到不错的 offer 。总之期待你的加入...

「看完本文有收获?转发给更多的朋友吧」
「DevXTalk 不止于技术」
原文作者:DevXTalk;如有侵权,请联系管理员删除。