服务形态

PolarDB-X提供了两种形态的Binlog日志消费订阅能力,且两种形态可同时共存。

  • 单流形态,即单流Binlog日志变更(Global Binlog)能力,将所有DN的Binlog归并到同一个全局队列,提供了保证事务完整性和有序性的日志流,可以提供更高强度的数据一致性保证。例如,在转账场景下,基于Global Binlog,接入PolarDB-X的下游MySQL,可以在任何时刻查询到一致的余额。

  • 多流形态,即多流Binlog日志(Binlog-X)变更能力,并不是将所有DN的Binlog归并到一个全局队列,而是将数据进行Hash打散并分发到不同的日志流,在一定程度上牺牲了事务的完整性,但大大提升了扩展性,可以解决大规模集群下单流Binlog存在的单点瓶颈问题。

Binlog单流形态

将所有DN节点的原始Binlog日志归并到一个队列,并进行排序和合并,剔除内部细节,对外提供兼容MySQL Binlog格式和dump协议的日志流。当购买PolarDB-X实例时,会默认开通单流Binlog服务。

image.png

注意事项

  • CDC的Master节点和Slave节点之间会进行binlog文件的复制,并保证两边数据完全一致,即下游按照filename+position的方式进行消费订阅,当CDC发生主从切换时,无需担心文件名和位点会发生变化。

  • 仅当事务策略指定为TSO时,才支持对分布式事务的合并,否则只能保证数据的最终一致性,PolarDB-X默认的事务策略为TSO。

  • 当需要对某行数据进行分区键值变更时,需在采用TSO事务策略的分布式事务内进行,才能保证delete事件在binlog中的位置早于insert事件,从而保证数据一致。具体来讲,首先需要采用TSO事务策略,然后按如下任意一种进行操作都可以实现分区键值的变更,并可以保证数据一致。

    • 执行一条update sql进行分区键值的修改;

    • 执行一条replace sql进行分区键值的修改;

    • 显示开启事务,先执行delete,调整分区键值,重新insert。

Binlog多流形态

多流Binlog依然完全兼容MySQL Binlog文件格式和dump协议,可以将每条Binlog日志流看作一个单机MySQL,针对单个日志流,可执行诸如change master... 、show binlog events ...等SQL命令消费或查看Binlog数据。

image.png

多流服务不会默认开通,需通过控制台单独开通,对于同一个PolarDB-X实例,可支持同时开通多个多流服务,不同服务之间是完全隔离的,每个服务可单独设置不同的流拆分数量、不同的数据拆分级别、不同的参数规则等,可根据实际需求开通不同形态的多流服务。

image.png

拆分级别

多流Binlog提供了3种形式的数据拆分级别,在开通多流服务时可进行设定,满足不同场景下的使用需求。

  • 库级别有序

    按照数据库的名字计算Hash值并进行分发,即对应同一个库的Binlog数据,会始终按序路由给同一个Binlog数据流,适用于单个PolarDB-X实例上数据库比较多的场景,如果事务不涉及跨库操作,该策略下不仅可以具备多流能力,还可以保证事务的完整性。

  • 表级别有序

    按照数据表的名字计算Hash值并进行分发,即对应同一张表的Binlog数据,会始终按序路由给同一个Binlog数据流,适用于表的数量较多且希望针对单张表的操作(DML/DDL等)在Binlog日志流中保持有序的场景。

  • 行级别有序

    按照数据行的主键计算Hash值并进行分发,即对应同一数据行的Binlog数据,会始终按序路由给同一个Binlog数据流,适用于希望将数据充分打散且不要求日志数据按库或按表保持有序的场景,该策略要求数据表必须含有主键,无主键表的数据会被直接丢弃。

数据拆分级别支持分层配置,分别为服务层和库表层,不管是哪个层级的配置,一旦设置成功就不再支持修改,否则会触发相同数据在不同流之间的“漂移”,导致数据一致性问题。所以,在开通多流服务前,需结合实际业务场景进行评估,预先规划好拆分级别。

  • 服务层

    该多流服务的默认拆分级别,如果针对某个库或表没有单独设置拆分级别,则使用服务层的默认配置。

  • 库表层

    可以针对某个库或表单独设置拆分级别,该配置会对服务层的配置进行重载,以满足差异性需求。

当使用行级别有序的拆分级别时,存在一个使用限制,如果数据表包含唯一性约束,并且会发生唯一键交换的场景,按照行级别有序进行分发,可能会触发数据一致性问题,如下所示,uk(name)=a会先后被id=1和id=2的数据所持有,但因无法保证delete(id=1,name=1)和insert(id=2,name=a)在目标库的执行顺序,当insert(id=2,name=2)先于delete(id=1,name=1)执行时,会出现写入冲突。如果存在类似场景,建议使用表级别有序的拆分级别。

image.png

注意事项

  • 在创建多流服务后,流的个数就无法再进行调整,需提前进行好数量规划,一般建议要大于等于DN的个数。

  • 在创建多流服务后,已经生效的拆分级别就无法再进行调整,需提前进行好规划。

  • 当需要新增数据表时,如果希望针对该表独立设置拆分级别,请在该表有数据写入之前进行配置。

  • 当使用表级别有序的拆分级别时,依然可以对表进行Rename操作,系统会始终依据初始表名进行数据分发。

  • 当使用表级别有序的拆分级别时,为了规避大表数据集中到少数几个流,出现数据倾斜,可单独设定路由规则

  • 如果想调整流的个数和已经生效的数据拆分级别,可以通过开通一个新的多流服务来进行替换,此时会涉及下游消费链路的一些运维调整。

  • 关于DDL语句在每条Binlog日志流上的分布情况的说明:

    拆分级别

    分布方式

    描述

    库级别

    单播+广播

    • CREATE DATABASE和DROP DATABASE对应的DDL语句会广播到每条Binlog日志流,这是因为可以为库中的某张表设置单独的拆分级别,因此建库和删库需要采用广播的方式。

    • 其它类型的DDL语句会单播到某条固定的Binlog日志流。

    表级别

    单播+广播

    • CREATE DATABASE和DROP DATABASE对应的DDL语句会广播到每条Binlog日志流,这是因为可以为库中的某张表设置单独的拆分级别,因此建库和删库需要采用广播的方式。

    • 其它类型的DDL语句会单播到某条固定的Binlog日志流。

    行级别

    广播

    所有类型的DDL语句会广播到每条Binlog日志流。

Binlog透明消费

CDC会优先把构建好的Binlog文件保存在本地磁盘,并支持实时上传到远端存储(如OSS),本地磁盘上的文件一般具有较短的存活周期,远端存储上的文件具有较长的存活周期(如15天)。针对远端存储上的文件,CDC提供了透明消费能力,即屏蔽了本地和远端的存储差异,下游系统无需为访问远端存储上的Binlog数据做任何额外适配。透明消费能力从CDC 2.0.0版本开始支持。

image.png