重新选择列

概述

为了提高性能和减少存储开销,数据库可以为某些列使用外部存储。这种类型的存储用于存储大量数据的列,例如 PostgreSQL 的 TOAST(超大属性存储技术)、Oracle Large Object (LOB) 或 Oracle Exadata 扩展字符串数据类型。为了减少 I/O 开销并提高查询速度,当表行中的数据发生更改时,数据库只检索包含新值 的列,而忽略外部存储的、未更改的列中的数据。因此,外部存储列的值不会记录在数据库日志中,Debezium 随后会在发出事件记录时省略该列。下游消费者在接收到省略了必需值的事件记录时,可能会遇到处理错误。

如果数据库日志条目中没有外部存储列的值,当 Debezium 为该事件发出记录时,它会用 unavailable.value.placeholder 哨兵值替换缺失的值。这些哨兵值将被插入到适当类型的字段中,例如,字节数组用于字节,字符串用于字符串,键值映射用于映射。

要检索初始查询中未提供的列的数据,您可以应用 Debezium 重新选择列后处理器 (ReselectColumnsPostProcessor)。您可以将后处理器配置为从表中重新选择一个或多个列。配置后处理器后,它会监视连接器发出的包含您指定的要重新选择的列名的事件。当它检测到带有指定列的事件时,后处理器会重新查询源表以检索指定列的数据,并获取它们的当前状态。

您可以将后处理器配置为重新选择以下列类型:

  • null 列。

  • 包含 unavailable.value.placeholder 哨兵值的列。

您只能将 ReselectColumnsPostProcessor 后处理器与 Debezium 源连接器一起使用。
此后处理器不支持 Debezium JDBC 接收连接器。

无键表

重新选择列后处理器会生成一个重新选择查询,该查询返回要修改的行。为了构造查询的 WHERE 子句,默认情况下,后处理器使用基于表主键列或为表定义的唯一索引的关系表模型。

对于无键表,ReselectColumnsPostProcessor 提交的 SELECT 查询可能会返回多行,在这种情况下,Debezium 始终只使用第一行。您无法优先排序返回行的顺序。为了使后处理器能够为无键表返回一致可用的结果,最好指定一个自定义键来标识唯一行。自定义键必须能够基于列的组合唯一标识源表中的记录。

要定义这样的自定义消息键,请在连接器配置中使用 message.key.columns 属性。定义自定义键后,将 reselect.use.event.key 配置属性设置为 true。设置此选项可使后处理器使用指定的事件键字段作为选择条件,而不是主键列。请务必测试配置,以确保重新选择查询提供预期的结果。

配置示例

配置后处理器类似于配置 自定义转换器单个消息转换 (SMT)。要使连接器使用 ReselectColumnsPostProcessor,请将以下条目添加到连接器配置中:

  "post.processors" : "reselector", (1)
  "reselector.type" : "io.debezium.processors.reselect.ReselectColumnsPostProcessor", (2)
  "reselector.reselect.columns.include.list" : "<schema>.<table>:<column>,<schema>.<table>:<column>", (3)
  "reselector.reselect.unavailable.values" : "true", (4)
  "reselector.reselect.null.values" : "true", (5)
  "reselector.reselect.use.event.key" : "false", (6)
  "reselector.reselect.error.handling.mode" : "WARN" (7)
Item 描述

1

逗号分隔的后处理器前缀列表。

2

后处理器的完全限定类类型名称。

3

逗号分隔的列名列表,使用以下格式指定:<schema>.<table>:<column>

4

启用或禁用包含 unavailable.value.placeholder 哨兵值的列的重新选择。

5

启用或禁用 null 列的重新选择。

6

启用或禁用基于事件键字段的重新选择。

7

当重新选择找不到行或引发数据库异常时,记录警告或抛出异常。

配置选项

下表列出了您可以为重新选择列后处理器设置的配置选项。

表 1. 重新选择列后处理器配置选项

属性

Default (默认值)

描述

无默认值

要从源数据库重新选择的列名的逗号分隔列表。使用以下格式指定列名:

<schema>.<table>:<column>

如果设置了 reselect.columns.exclude.list 属性,则不要设置此属性。

无默认值

要从重新选择中排除的源数据库中的列名的逗号分隔列表。使用以下格式指定列名:

<schema>.<table>:<column>

如果设置了 reselect.columns.include.list 属性,则不要设置此属性。

true

指定后处理器是否重新选择匹配 reselect.columns.include.list 过滤器且列值由连接器的 unavailable.value.placeholder 属性提供的列。

true

指定后处理器是否重新选择匹配 reselect.columns.include.list 过滤器且列值为 null 的列。

false

指定后处理器是根据事件的键字段名进行重新选择,还是使用关系表的主键列名进行重新选择。

默认情况下,重新选择查询基于关系表的主键列或唯一键索引。对于没有主键的表,将此属性设置为 true,并在连接器配置中配置 message.key.columns 属性,以指定连接器在创建事件时使用的自定义键。然后,后处理器将指定的键字段名用作 SQL 重新选择查询中的主键。

WARN

指定重新选择后处理器如何响应某些条件。

默认情况下,当找不到行或发生数据库选择错误时,后处理器会记录一条警告消息。

当设置为 FAIL 时,如果在重新选择时行已不存在或重新选择行时发生数据库故障,连接器将停止处理更改。