前段时间在做实时数据同步项目,使用了mysql binlog同步技术,其核心是mysql的复制协议,于是我顺便就仔细研究了一下这个协议
Binlog File
mysql的各种操作事件(insert,update,delete,alert等)会记录到binlog-file里。Binlog文件格式由Binlog Header(文件头)和Binlog Event组成。
Binlog version
binlog格式目前有4个不同版本
摘自官网如下
Version 1
supported statement based replication events
Version 2
can be ignored as it was only used in early alpha versions of MySQL 4.1.x and won’t be documented here
Version 3
added the relay logs and changed the meaning of the log position
Version 4
added the FORMAT_DESCRIPTION_EVENT and made the protocol extensible
In MySQL 5.1.x the Row Based Replication Events were added.
Binlog event
Binlog event主要记录的各种操作东西,主要由 Binlog Event header 和 Event Body 组成
依赖于不同的版本,binlog event事件由很多,其中最重要和复杂的莫过于 Row Based Replication Events 相关事件,里面包括了数据的各种insert,update,delete事件。
如下:
1 | TABLE_MAP_EVENT |
由三个不同版本,分别对应不同的mysql版本
- Version 0
- from MySQL 5.1.0 to 5.1.15
- Version 1
- from MySQL 5.1.15 to 5.6.x
- Version 2
- from MySQL 5.6.x
Binlog dump
当一个slave从库需要同步master的binlog的时候,需要向master发送一些请求命令去告诉master我要同步binlog。第一个请求命令就是*** COM_REGISTER_SLAVE *** ,向master注册。发送如下消息:
1 | 1 [15] COM_REGISTER_SLAVE |
其中最重要的是server_id,必须全局唯一
- server_id (4) – the slaves server-id
奇怪的是,我看debezium源码里面并没有 COM_REGISTER_SLAVE 这个命令的发送,也可以进行同步
接下来就是发送dump命令了。COM_BINLOG_DUMP 通过带上binlog-filename和position 就可以获取指定位置的binlog event了。
在mysql 5.6之后,支持另外一种dump命令,COM_BINLOG_DUMP_GTID ,gtid dump,这种命令是为了解决mysql进行HA切换过程中找position问题,因为老的方式在HA切换中无法精确定位position 需要人工介入。通过gtid方式后 就不需要人为找position了,master会自动算出需要同步的position。
end
mysql复制协议总的来说比较复杂,要实现一个binlog复制协议也是很有挑战的一件事情,因为mysql有多个不同的协议版本,要兼容每一个版本也是很麻烦的事情。好在有很多开源项目已经帮我们做了这个复杂的工作,感谢致敬~~~