Debezium 3.3.0.Alpha1 带来了一系列激动人心的新创新,包括核心连接器的精确一次语义,以及社区主导的全新 CockroachDB 连接器。凭借对新兴数据类型的支持、更深入的 Quarkus 集成以及增强的工具,此版本为现代变更数据捕获解决方案设定了新标准。准备好看看有什么新内容了吗?让我们深入了解。
重大变更
与任何新软件的主要版本一样,通常会有一些破坏性更改。Debezium 3.3.0.Alpha1 版本也不例外,所以让我们讨论一下您应该注意的主要变化。
已弃用的快照模式已移除
在 Debezium 2.6 中,我们将快照模式的名称与其预期功能保持一致,其中包括
-
弃用了
schema_only_recovery并替换为recovery。 -
弃用了
schema_only并替换为no_data。
从 Debezium 3.3 开始,schema_only_recovery 和 schema_only 都已被移除 (DBZ-8171)。仍然依赖已弃用模式的连接器配置在升级后会导致无效配置错误,因此相应地调整连接器配置非常重要。
新功能和改进
以下描述了 Debezium 3.3.0.Alpha1 中所有值得注意的新功能和改进。有关完整列表,请务必阅读 发行说明 以获取更多详细信息。
新的 CockroachDB 连接器
CockroachDB 连接器是一个新连接器,由社区与 Cockroach Labs 合作开发 (DBZ-9289)。该连接器构建在 CockroachDB 的 change-feed 子系统之上,用于捕获行级更改,并将它们作为更改事件发出。
这个新连接器需要 CockroachDB 25.2+ 并启用 rangefeed 选项,以及 Java 21+。该连接器目前处于孵化阶段,并且社区正在积极开发中。
如果您想开始使用该连接器,可以使用以下坐标获取连接器
<dependency>
<groupId>io.debezium</groupId>
<artifactId>debezium-connector-cockroachdb</artifactId>
<version>3.3.0.Alpha1</version>
</dependency> 该连接器的文档仍在开发中,但您可以在存储库的 README 中找到有关其配置选项和使用方法的说明。
精确一次语义支持
社区对 Debezium 的精确一次语义支持提出了许多要求。通俗地说,精确一次语义意味着一个事件只应被传递和写入 Kafka 主题一次,从而避免重复的可能性。
我们很高兴地宣布 Debezium 3.3 为所有核心连接器(包括 MariaDB、MongoDB、MySQL、Oracle、PostgreSQL 和 SQL Server)引入了精确一次语义支持 (DBZ-9177)。
禁用上下文头
在 Debezium 3.2 中,我们引入了几个新头,为 OpenLineage 提供上下文,这些头会自动添加到每个发出的事件中。一些用户报告了这些头被添加但无法禁用,因为某些环境需要保持事件负载尽可能精简。
根据社区反馈,我们引入了一个新的配置选项 extended.headers.enabled,可以将其设置为 false,从而禁用这些上下文事件头的添加 (DBZ-9248)。
MariaDB 11.7+ 向量数据类型支持
MariaDB 11.7 引入了 VECTOR(n) 数据类型,允许将关系数据库中的值存储,就像它是一个向量数据库一样。通过此新数据类型,可以存储和搜索由 AI 模型生成的向量值。
Debezium 3.3 在 MariaDB 源连接器和 JDBC 接收器连接器(写入 MariaDB 目标数据库时)中引入了 MariaDB 向量数据类型支持 (DBZ-8582)。
MariaDB 和 MySQL Schema History 改进
MariaDB 和 MySQL Schema History 主题由连接器用于存储从二进制日志捕获的各种 DDL 操作,使连接器能够从表模式更改的历史记录中构建关系模型。
在 Debezium 3.3 中,Schema History 主题的过滤器已更新,以避免在主题中存储与 Debezium 功能无关的特定语句,例如存储过程、函数、视图、触发器和 grant/revoke 语句 (DBZ-9186)。
| 对于新连接器,此类语句将不会被存储。对于现有连接器,只有新捕获的符合改进过滤器的 DDL 语句才会被省略,现有主题事件不会被移除。 |
Oracle 遗留小数处理模式行为
在 Debezium 2.7 中,我们引入了一个 bug 修复,将 Oracle 连接器中使用 double 或 string 模式的 decimal.handling.mode 的行为与其他关系连接器保持一致。此 bug 修复改变了事件的 schema,并给那些未预料到此类更改的升级用户带来了许多问题。
我们考虑了多种选项,例如通过 CustomConverter 或 Transformation 引入遗留支持,但是,我们认为需要将遗留支持内置到连接器中才能提供充分的解决方案。
在 Debezium 3.3 中,添加了一个新的配置属性 legacy.decimal.handling.strategy,允许用户恢复使用有缺陷的行为,其中零标度的数值不会自动转换为 double 或 string,而是作为整数值发出,只要其长度小于或等于 18 (DBZ-9166)。
| 如果您从 Debezium 2.7 之前的版本升级,建议您至少在初始阶段启用此功能,以尽量减少升级到 Debezium 3.3 或更高版本的复杂性。 如果您已升级到 Debezium 2.7 至 3.2,则不建议启用此遗留行为,因为它将引入相同的 schema 更改复杂性,但方向相反。 |
Oracle LogMiner 实验性 CTE 查询支持
我们为 Oracle LogMiner 引入了一项新的内部和实验性功能,该功能利用了 CTE 查询(或通用表表达式查询)的概念。CTE 查询是一种 SQL 构造,允许在另一个 SQL 操作的执行过程中定义一个临时的、命名的结果集,这在各种情况下都很有用。
对于 Debezium Oracle 连接器,新的 internal.log.mining.use.cte.query 功能会切换一个特殊的预处理步骤,该步骤会检查所有事务并执行预过滤步骤 (DBZ-9272)。此过滤步骤旨在仅为包含至少一个已捕获表 DML 操作的事务发送 START、COMMIT 和 ROLLBACK 事件。换句话说,如果有人执行了 100 个事务,而其中只有一个事务修改了您捕获的表,那么我们不仅不会收到其他 99 个事务的 DML 事件,而且事务标记也会被省略。
| 此功能并非没有缺点,最显著的是它需要对事务日志进行两次扫描。对于非捕获表与捕获表之间更改量不成比例地更高的系统,额外的读取传递可能值得,以最小化额外事务标记事件的网络和连接器处理开销。 |
PostgreSQL 文本搜索向量支持
在 PostgreSQL 13+ 中,添加了全文搜索数据类型。tsvector 数据类型表示一个针对文本搜索进行了优化的文档形式,提供排序的唯一词位列表。
使用 Debezium 3.3,您现在可以捕获对使用 tsvector 数据类型的列所做的更改 (DBZ-8470)。这些列类型使用名为 io.debezium.data.Tsvector 的逻辑类型发出,并在事件中表示为 *字符串* 数据类型。
Outbox 扩展支持最新的 Quarkus
Debezium Quarkus Outbox 扩展与大多数基于 Quarkus 的扩展一样,依赖于 Hibernate 进行持久化。在最新的 Quarkus 3.23.x 中,Hibernate 的版本已更新到 7.x。这个新版本的 Hibernate 引入了各种破坏性更改,导致扩展不兼容。
在 Debezium 3.3(并向即将发布的 Debezium 3.2.1 向后移植)中,Debezium Quarkus Outbox 扩展与最新的 Quarkus 构建兼容,可以与 Hibernate 7+ 一起工作 (DBZ-9219)。
| 由于兼容性更改,当使用 Debezium 3.2.0.Final 或更早版本时,Quarkus 应用程序必须基于 Quarkus 3.22.x 或更早版本。只有在使用 Debezium 3.2.1 / 3.3.x 或更高版本时,才能使用 Quarkus 3.24.x 或更高版本。 |
Azure Event Hubs 的内置哈希分区键
Azure Event Hub 的分区键长度限制为 128 个字符。如果事件的键导致分区键超过该限制,Debezium Server 的 Azure Event Hubs 接收器适配器将抛出异常,并且连接器将终止。这种行为不太理想,并对源表引入了限制,而这些限制在源端可能无法解决。
为了解决此问题,可以将 Azure Event Hubs 接收器配置为使用几种哈希算法之一,以在处理分区键可能超出最大允许大小时,遵守最大分区键长度 (DBZ-9245)。
要启用 Azure Event Hubs 接收器使用内置的哈希分区键,必须使用 debezium.sink.eventhubs.hashmessagekey 配置属性(设置为 true,默认为 false)进行配置。启用后,可以设置 debezium.sink.eventhubs.hashmessagekeyfunction 为 java(默认)、md5、sha1 或 sha256 来确定使用的哈希算法类型。
Debezium Platform 引入智能编辑器
跨不同运行时管理类似的 Debezium 连接器会带来其独特的维护挑战,因为每个运行时使用不同的格式,例如 Kafka Connect 使用 JSON,而 Debezium Server 使用键/值属性文件。Debezium Platform 还使用自己的基于 JSON 的格式,该格式与 Kafka Connect 略有不同,这增加了额外的复杂性。
Quarkus 扩展改进
Debezium 产品组合中最新的添加之一是 Debezium Quarkus 扩展,它允许开发人员在 JVM 或原生构建的基于 Quarkus 的应用程序中直接利用 Debezium 的 CDC 功能。我们增加了一些新的改进,所以让我们分别介绍一下。
心跳监听器
Debezium 可以通过 heartbeat.interval.ms 进行配置,使 Debezium 定期向事件流发出心跳事件。心跳事件可以用于各种原因,但其主要用途是确保即使在捕获表低/无活动期间,偏移量也与源数据库上的当前读取状态保持一致。
使用 Debezium 扩展的 Quarkus 应用程序也可以通过观察 CDI 事件 DebeziumHeartbeat 在发出心跳时执行额外的操作。这允许为每个心跳执行应用程序特定的代码 (DBZ-8960)。
以下示例中,监听器在观察到心跳时仅写入控制台。
@ApplicationScoped
public class HeartbeatListener {
public void consoleHeartbeat(@Observes DebeziumHeartbeat event) {
System.out.println("Debezium emitted a heartbeat event!");
}
} 轻松实现自定义转换器
Debezium CustomConverter 是一个可用于更改 Debezium 如何发出给定列类型值的工具。对于需要特定格式数据的消费者来说,这可能非常强大。
在您的 Quarkus 应用程序中,您可以通过在 application.properties 文件中将其指定为连接器配置的一部分来定义 CustomConverter 的传统方式;但是,Debezium 3.3 增加了一种新的基于注解的方法,该方法简化了配置,并使迭代开发更加轻松快速 (DBZ-8966)。
例如,以下内容展示了定义一个转换器,该转换器将给定的原始字段转换为事件中的*字符串*值,使用 Java 的 toString() 函数。
@ApplicationScoped
class RawToStringConverter {
@CustomConverter
public ConverterDefinition<SchemaBuilder> bind(ConvertedField field) {
return new ConverterDefinition<>(SchemaBuilder.string(), Object::toString);
}
} 此外,自定义转换器可以有选择地应用于字段。开发人员可能会倾向于在注释方法中的自定义转换器中实现此行为,虽然这很有效,但可以使用组件驱动的方式通过 FieldFilteringStrategy 来实现。
例如,以下内容展示了相同的自定义转换器,但使用了字段过滤策略
@ApplicationScoped
class RawToStringConverter {
@CustomConverter(filter = CustomFieldFilteringStrategy.class)
public ConverterDefinition<SchemaBuilder> bind(ConvertedField field) {
return new ConverterDefinition<>(SchemaBuilder.string(), Object::toString);
}
}
@ApplicationScoped
class CustomFieldFilteringStrategy implements FieldFilteringStrategy {
@Override
public boolean filter(ConvertedField field) {
/* implement your selective logic here */
return false;
}
} CDC 事件作为 POJO
Debezium Quarkus 扩展将更改事件作为结构化的 ChangeEvent<K, V> 类型发出。但在某些情况下,将更改事件转换为 Java 记录或域特定 POJO 可能很有用。对于这些情况,Debezium 的 Quarkus 扩展提供了一种标准化的方法,将 ChangeEvent 反序列化到您的 Java 记录或 POJO 中。
例如,假设我们的源中有一个 products 表,并且我们定义了一个捕获处理程序。在此处理程序中,我们希望处理 Product 对象,如下所示。
@ApplicationScoped
class ProductHandler {
@Capturing(destination = "prefix.inventory.products")
public void captureProducts(Product product) {
/* do something with product */
}
} 为了实现这一点,需要实现一个 Deserializer<T> 来将 ChangeEvent 转换为目标 POJO 类型 Product。该扩展提供了一个实现来使用 Jackson,ObjectMapperDeserializer 来处理此问题。
public class ProductDeserializer extends ObjectMapperDeserializer<Product> {
public ProductDeserializer() {
super(Product.class);
}
} 最后一步是定义 Quarkus 配置中的反序列化映射,以将它们粘合在一起。
quarkus.debezium.capturing.product.destination=prefix.inventory.products
quarkus.debezium.capturing.product.deserializer=<the-java-package>.ProductDeserializer 该扩展将使用此配置将目的地为 prefix.inventory.products 主题的事件映射到使用 product 反序列化器。此反序列化器映射到 <the-java-package>.ProductDeserializer 类,该类使用 Jackson 将 ChangeEvent 转换为 Product 对象。转换后,将使用 Product 对象调用带有 @Capturing 注解的方法,而不是发出的 ChangeEvent。
其他更改
-
在 Oracle 只读副本中执行 Debezium DBZ-8319
-
精细日志记录配置 DBZ-8638
-
Debezium Engine Quarkus 扩展:引入 PostProcessor 处理程序 DBZ-8965
-
在挖掘会话期间,将 ORA-00310 重做日志视为不一致 DBZ-8870
-
为缓存事件添加 JMX 指标/统计信息 DBZ-8991
-
为 OpenLineage 创建一个展示示例 DBZ-9058
-
ORACLE NVARCHAR 数据中的 '||' 会导致异常 DBZ-9132
-
[ORACLE] DDL 解析失败 DBZ-9172
-
移除配置中的心跳创建,以支持 HeartbeatFactory DBZ-9176
-
在使用非恢复快照模式时,偏移量未重置 DBZ-9208
-
SqlServer 的日志位置验证可能会失败 DBZ-9212
-
可能出现回归,抛出 DebeziumException 而非警告 DBZ-9217
-
通过 NATS Jetstream sink 双重发布事件 DBZ-9221
-
由于 DebeziumHeaderProducer 未注册,抛出 NullPointerException DBZ-9225
-
MongoDB ExtractNewDocumentState SMT 在 3.2 版本中崩溃,出现数组中的嵌套结构 DBZ-9231
-
Mongodb 增量快照未遵守附加条件 DBZ-9232
-
INSERT 语句中的 WithClause 抛出 DDL 解析器异常 DBZ-9233
-
Oracle 快照边界模式没有字段显示名称 DBZ-9236
-
请求修复 jdbc postgres 目标的多任务 CREATE TABLE 冲突,导致任务崩溃 DBZ-9237
-
Oracle 分区表拆分不支持在线模式 DBZ-9238
-
异常大的挖掘窗口可能导致意外的指标/性能问题 DBZ-9241
-
在 Debezium-connector-postgres 中,当缺失心跳表时抛出异常 DBZ-9247
-
允许 Oracle 心跳操作查询错误处理程序对 ORA-02396 保持弹性 DBZ-9280
-
OpenLineage 输出数据集使用错误的数据类型 DBZ-9285
-
将 Informix JDBC 驱动程序更新到 4.50.12 DBZ-9288
-
Debezium platform 验证信号数据收集失败 DBZ-9290
-
AsyncEmbeddedEngine 中的 OffsetStorageWriter.doFlush() 抛出未检查的异常,导致 OffsetStorageWriter 中的信号量未释放,可能导致引擎失败 DBZ-9292
-
Reselect 后处理器无法处理 VariableScaleDecimal 主键 DBZ-9293
-
使用基于 pgoutput 插件的 postgres 连接器时出现重复键异常 DBZ-9305
-
在 LogMiner 失败期间记录 LogMiner 会话日志中的所有行 DBZ-9322
非常感谢社区所有为本次发布辛勤付出的贡献者:Aleksei Silantev, Alvar Viana Gomez, Animesh Kumar, Anisha Mohanty, Chris Cranford, Giovanni Panice, Hesjona Hilaj, Jiri Pechanec, IFIG LE PENNEC, Lars M. Johansson, Liam Wu, Lucas Gazire, Mario Fiore Vitale, Pierre-Yves Péton, Pranav Tiwari, Robert Roldan, Shubham Kalla, Thomas Thornton, Virag Tripathi, 和 Vojtech Juranek!
关于 Debezium
Debezium 是一个开源的分布式平台,可以将现有数据库转变为事件流,使应用程序能够几乎即时地看到并响应数据库中已提交的每个行级更改。Debezium 构建在 Kafka 之上,并提供了 Kafka Connect 兼容的连接器,用于监控特定的数据库管理系统。Debezium 将数据更改的历史记录在 Kafka 日志中,这样您的应用程序可以随时停止和重新启动,并可以轻松地消费在未运行时错过的所有事件,确保所有事件都被正确且完整地处理。Debezium 在 Apache 许可证 2.0 下是 开源 的。