支持 GH-OST 和 PT-OSC
简介
CloudCanal 实现了对 Online DDL 工具如 GH-OST 和 PT-OSC 的支持,保证了对端实时同步源端的 Online DDL 操作。
本文以 MySQL -> MySQL 同步链路使 用 GH-OST 为例,介绍 CloudCanal 是如何支持实时同步 GH-OST 产生的 DDL 的。
Online DDL 技术背景
市面上常用的两款MySQL Online DDL 工具分别是 GH-OST 和 PT-OSC,CloudCanal 对他们都做了兼容处理使得用户可以实时同步 Online DDL 工具产生的 DDL 。下面简单介绍下他们的工作流程,以便于读者理解后续章节的内容。
Online DDL 工具 PT-OSC 原理
PT-OSC 是较为常用的 Online DDL 工具,通过触发器来同步增量数据,相较于 MySQL 原生的 Online DDL 性能得到了极大的提高,原理如下:
- 对源表进行检查
- 创建一个与源表(origin)结构一致的空表,命名为 _origin_new
- 根据alter参数修改新表的表结构
- 在源表中创建三个触发器:Delete / Update / Insert,将源表中的增删改语句同步执行到新表中,同时将源表中的数据以数据块的形式 copy 到新表
- 将源表(origin)rename为 _origin_old,将 _origin_new rename 为 origin,然后删除旧表(可选)
- 删除触发器
总结:PT-OSC 是通过创建临时表,并用触发器将增量数据同步到新表,通过当前读和事务来实现增量与全量的有序,不会阻塞读写操作,但运行过程中出现异常,无法从上一个位置继续进行,需要从头开始。
Online DDL 工具 GH-OST 原理
GH-OST 也是一款常用的 Online DDL 工具,采用读取 binlog 日志的方式来同步增量数据,原理如下:
- 对源表(origin)进行检查
- 在主/从节点中添加binlog日志监听
- 创建日志记录表(_origin_ghc)和与源表结构一致的影子表(_origin_gho)
- 根据alter参数修改影子表的表结构
- 全量拷贝源表数据同时拷贝源表增量数据到影子表中,并记录日志到日志记录表中
- 删除日志记录表,将源表改名为 _origin_del, 将影子表改名为 origin,_origin_del 可选删除
总结: GH-OST 的性能与 PT-OSC 相近,相较于PT-OSC 的优点就在于其是不使用触发器的,只异步读取二进制日志,因此修改表定义的负载和正常的业务负载解耦开了,它不需要考虑被修改的表上的并发操作和竞争等,并且相较于 PT-OSC 的中断从头开始,GH-OST 可以从心跳日志中恢复到指定位置。
CloudCanal 技术点
前文中对 Online DDL 工具的原理中我们知道,无论采用哪种 Online DDL 工具,源端都会产生一些临时表的创建和数据写入,如果不做任何兼容处理,这会影响正常的迁移同步链路。
因此为了支持 GH-OST 和 PT-OSC 工具的使用,CloudCanal 在 MySQL 源端做了大量优化,完美的适配并优化了 GH-OST 和 PT-OSC 的 Online DDL 能力
同步临时表数据
GH-OST 和 PT-OSC 工具都有一个共同的特点,其原理都是采用临时表的方式来保证 DDL 与 DML 的并发操作。
CloudCanal 默认的表订阅模式是只订阅原表,不订阅与原表相关的临时表(订阅表即同步该表的 DDL 与 DML 语句),而 CloudCanal 为了满足对 Online DDL 工具的支持,在源数据端配置上新增了 extraDDL 参数来实现对临时表的订阅。
- extraDDL参数:
- 可选参数:NONE / GHOST / PT
- 作用:选择 NONE 则不订阅任何临时表,选择 GHOST / PT 则订阅相应的默认临时表
CloudCanal 针对临时表订阅采用的是两种模式:自动订阅临时表模式和自动同步元数据模式
- 自动订阅临时表:CloudCanal 会自动根据 extraDDL 参数将默认的临时表加入到订阅表集合中,随后读取binlog日志时将不会过滤掉临时表的所有变更事件,保证了对端数据源表结构与数据的最终一致性
- 自动同步元数据:CloudCanal 会自动过滤临时表,在读取binlog日志时不会执行 Online DDL 的操作,在 Online DDL 执行完毕后发送最新的表结构,期间的 DML 语句也会同步发送到对端,保证对端数据源表结构与数据的最终一致性
由于各数据源对同步数据的消费并不相同,如消息队列只需要解析 Online DDL 后的表结构即可,无需订阅临时表,因此我们需要根据对端数据源的消费模式做出不同的处理。

