Debezium系列之:Debezium2.X之PostgreSQL数据库的Debezium连接器

Debezium系列之:Debezium2.X之PostgreSQL数据库的Debezium连接器

  • 一、概述
  • 二、连接器的工作原理
    • 1.安全
    • 2.快照
    • 3.临时快照
    • 4.触发临时快照
    • 5.增量快照
    • 6.增量快照过程
    • 7.快照窗口
    • 8.触发增量快照
    • 9.临时增量快照additional-condition
    • 10.停止增量快照
    • 11.流式变化
    • 12.PostgreSQL 10+ 逻辑解码支持 ( pgoutput)
    • 13.事物元数据
    • 14.更改数据事件扩充
  • 三、数据变更事件
    • 1.更改事件键
    • 2.更改事件值
    • 3.创建事件
    • 4.更新事件
    • 5.主键更新
    • 6.墓碑事件
    • 7.截断事件
    • 8.消息事件
  • 四、数据类型映射
    • 1.基本类型
    • 2.TIMESTAMP类型
    • 3.Decimal类型
    • 4.HSTORE类型
    • 5.默认值
  • 五、设置 Postgres
    • 1.云中的 PostgreSQL
    • 2.安装逻辑解码输出插件
    • 3.插件差异
  • 六、配置 PostgreSQL 服务器
  • 七、设置用户权限
  • 八、配置 PostgreSQL 以允许使用 Debezium 连接器主机进行复制
  • 九、支持的 PostgreSQL 拓扑
  • 十、WAL磁盘空间消耗
  • 十一、部署
  • 十二、连接器配置示例
  • 十三、连接器属性
  • 十四、Debezium2.X接入PostgreSQL数据库实战详细总结

Debezium PostgreSQL 连接器捕获 PostgreSQL 数据库模式中的行级更改。第一次连接到 PostgreSQL 服务器或集群时,连接器会拍摄所有模式的一致快照。快照完成后,连接器会持续捕获行级更改,这些更改包括插入、更新和删除数据库内容以及提交给 PostgreSQL 数据库的更改。连接器生成数据更改事件记录并将它们流式传输到 Kafka 主题。对于每个表,默认行为是连接器将所有生成的事件流式传输到该表的单独 Kafka 主题。应用程序和服务使用来自该主题的数据更改事件记录。

一、概述

PostgreSQL 的逻辑解码特性是在 9.4 版本中引入的。它是一种允许提取提交给事务日志的更改并借助输出插件以用户友好的方式处理这些更改的机制。输出插件使客户端能够使用更改。

PostgreSQL 连接器包含两个主要部分,它们协同工作以读取和处理数据库更改:

  • 一个逻辑解码输出插件。可能需要安装选择使用的输出插件。在运行 PostgreSQL 服务器之前,必须配置一个使用选择的输出插件的复制槽。插件可以是以下之一:
    • decoderbufs基于 Protobuf 并由 Debezium 社区维护。
    • pgoutput是PostgreSQL 10+标准的逻辑解码输出插件。它由 PostgreSQL 社区维护,并由 PostgreSQL 本身用于逻辑复制。该插件始终存在,因此无需安装额外的库。Debezium 连接器将原始复制事件流直接解释为更改事件。
  • 读取由所选逻辑解码输出插件产生的更改的 Java 代码(实际的 Kafka Connect 连接器)。它通过 PostgreSQL JDBC 驱动程序使用 PostgreSQL 的流复制协议

连接器为捕获的每个行级插入、更新和删除操作生成一个更改事件,并在单独的 Kafka 主题中为每个表发送更改事件记录。客户端应用程序读取与感兴趣的数据库表相对应的 Kafka 主题,并且可以对它们从这些主题接收到的每个行级事件做出反应。

PostgreSQL 通常会在一段时间后清除预写日志 (WAL) 段。这意味着连接器没有对数据库所做的所有更改的完整历史记录。因此,当 PostgreSQL 连接器首次连接到特定的 PostgreSQL 数据库时,它首先对每个数据库模式执行一致的快照。连接器完成快照后,它会继续从创建快照的确切位置流式传输更改。这样,连接器从所有数据的一致视图开始,并且不会遗漏在拍摄快照时所做的任何更改。

连接器可以容忍故障。当连接器读取更改并生成事件时,它会记录每个事件的 WAL 位置。如果连接器因任何原因停止(包括通信故障、网络问题或崩溃),重新启动后连接器会继续读取上次停止的 WAL。这包括快照。如果连接器在快照期间停止,则连接器会在重新启动时开始新的快照。

重要的:
该连接器依赖并反映了 PostgreSQL 的逻辑解码特性,它有以下限制:

  • 逻辑解码不支持 DDL 更改。这意味着连接器无法将 DDL 更改事件报告给使用者。
  • 只有服务器支持逻辑解码复制槽primary。当存在 PostgreSQL 服务器集群时,连接器只能在活动primary服务器上运行。hot它不能在备用副本上运行warm。如果primary服务器出现故障或降级,连接器将停止。服务器恢复后primary,您可以重新启动连接器。如果不同的 PostgreSQL 服务器已升级为primary,请在重新启动连接器之前调整连接器配置。
  • Debezium 目前仅支持使用 UTF-8 字符编码的数据库。使用单字节字符编码,无法正确处理包含扩展 ASCII 代码字符的字符串。

二、连接器的工作原理

要以最佳方式配置和运行 Debezium PostgreSQL 连接器,了解连接器如何执行快照、流式传输更改事件、确定 Kafka 主题名称和使用元数据会很有帮助。

1.安全

要使用 Debezium 连接器从 PostgreSQL 数据库流式传输更改,连接器必须在数据库中以特定权限运行。尽管授予必要权限的一种方法是为用户提供superuser权限,但这样做可能会将PostgreSQL 数据暴露给未经授权的访问。与其授予 Debezium 用户过多的权限,不如创建一个专用的 Debezium 复制用户,可以向其授予特定权限。

2.快照

大多数 PostgreSQL 服务器配置为不在 WAL 段中保留数据库的完整历史记录。这意味着 PostgreSQL 连接器将无法通过仅读取 WAL 来查看数据库的完整历史记录。因此,连接器第一次启动时,它会执行数据库的初始一致快照。执行快照的默认行为包括以下步骤。snapshot.mode您可以通过将连接器配置属性设置为 以外的值来更改此行为initial。

  1. 以可串行化、只读、可延迟的隔离级别启动事务,以确保此事务中的后续读取针对数据的单个一致版本。由于其他客户端的后续INSERT、UPDATE和DELETE操作而导致的任何数据更改对该事务不可见。
  2. 读取服务器事务日志中的当前位置。
  3. 扫描数据库表和模式,READ为每一行生成一个事件并将该事件写入适当的特定于表的 Kafka 主题。
  4. 提交事务。
  5. 在连接器偏移量中记录快照的成功完成。

如果连接器在步骤 1 开始后但在步骤 5 完成之前发生故障、重新平衡或停止,则在重新启动时连接器会开始一个新的快照。在连接器完成其初始快照后,PostgreSQL 连接器继续从它在步骤 2 中读取的位置流式传输。这确保连接器不会错过任何更新。如果连接器出于任何原因再次停止,则在重新启动时,连接器会继续从之前停止的地方流式传输更改。

连接器配置属性的选项

选项 描述
always 连接器在启动时始终执行快照。快照完成后,连接器继续按上述顺序从步骤 3 流式传输更改。此模式在这些情况下很有用:已知一些 WAL 段已被删除,不再可用。集群故障后,新的主节点已被提升。快照always模式确保连接器不会错过在提升新主节点之后但在新主节点上重新启动连接器之前所做的任何更改。
never 连接器从不执行快照。当以这种方式配置连接器时,其启动时的行为如下。如果 Kafka 偏移量主题中存在先前存储的 LSN,则连接器会继续从该位置流式传输更改。如果没有存储 LSN,则连接器从在服务器上创建 PostgreSQL 逻辑复制槽的时间点开始流式传输更改。never只有当您知道所有感兴趣的数据仍然反映在 WAL 中时,快照模式才有用。
initial_only 连接器执行数据库快照并在流式传输任何更改事件记录之前停止。如果连接器已启动但在停止前未完成快照,则连接器将重新启动快照过程并在快照完成时停
exported 已弃用,所有模式都是无锁的。
custom 快照custom模式允许注入自己的io.debezium.connector.postgresql.spi.Snapshotter接口实现。将配置属性设置snapshot.custom.class为 Kafka Connect 集群类路径上的类,或者如果使用EmbeddedEngine.

3.临时快照

默认情况下,连接器仅在首次启动后运行初始快照操作。在这个初始快照之后,在正常情况下,连接器不会重复快照过程。连接器捕获的任何未来更改事件数据仅通过流处理进入。

但是,在某些情况下,连接器在初始快照期间获取的数据可能会变得陈旧、丢失或不完整。为了提供一种重新捕获表数据的机制,Debezium 包含一个执行临时快照的选项。数据库中的以下更改可能会导致执行临时快照:

  • 修改连接器配置以捕获一组不同的表。
  • Kafka 主题被删除,必须重建。
  • 由于配置错误或其他一些问题而发生数据损坏。

可以通过启动所谓的ad-hoc snapshot为之前捕获快照的表重新运行快照。Ad hoc 快照需要使用信令表。可以通过向 Debezium 信号表发送信号请求来启动临时快照。

当启动现有表的临时快照时,连接器会将内容附加到表中已经存在的主题。如果删除了先前存在的主题,Debezium 可以在启用自动创建主题的情况下自动创建一个主题。

临时快照信号指定要包含在快照中的表。快照可以捕获数据库的全部内容,也可以只捕获数据库中表的一个子集。此外,快照可以捕获数据库中表内容的子集。

execute-snapshot您可以通过向信令表发送消息来指定要捕获的表。将信号类型设置execute-snapshot为incremental,并提供要包含在快照中的表的名称,如下表所述:

execute-snapshot表 2. 临时信号记录示例

选项 默认 参数说明
type incremental 指定要运行的快照类型。设置类型是可选的。目前,您只能请求incremental快照。
data-collections 不适用 一个数组,其中包含与要拍摄快照的表的完全限定名称匹配的正则表达式。名称的格式与配置选项的格式相同signal.data.collection。
additional-condition 不适用 一个可选字符串,它根据表的列指定条件,以捕获表内容的子集。
surrogate-key 不适用 一个可选字符串,指定连接器在快照过程中用作表主键的列名。

4.触发临时快照

execute-snapshot可以通过向信令表添加具有信号类型的条目来启动临时快照。连接器处理消息后,开始快照操作。快照过程读取第一个和最后一个主键值,并将这些值用作每个表的起点和终点。根据表中的条目数和配置的块大小,Debezium 将表分成块,并继续为每个块连续快照,一次一个。

目前,execute-snapshot操作类型仅触发增量快照。

5.增量快照

为了提供管理快照的灵活性,Debezium 包括一个补充快照机制,称为增量快照。增量快照依赖 Debezium 机制将信号发送到 Debezium 连接器。

在增量快照中,Debezium 不是像在初始快照中那样一次捕获数据库的完整状态,而是在一系列可配置的块中分阶段捕获每个表。您可以指定希望快照捕获的表以及每个块的大小。块大小决定了在对数据库执行每次提取操作期间快照收集的行数。增量快照的默认块大小为 1 KB。

随着增量快照的进行,Debezium 使用水印来跟踪其进度,维护它捕获的每个表行的记录。与标准的初始快照过程相比,这种分阶段的数据捕获方法具有以下优势:

  • 可以在捕获流式数据的同时运行增量快照,而不是将流式传输推迟到快照完成。在整个快照过程中,连接器继续从更改日志中捕获近乎实时的事件,并且两个操作都不会阻塞另一个。
  • 如果增量快照的进度中断,可以在不丢失任何数据的情况下恢复它。进程恢复后,快照从它停止的位置开始,而不是从头重新捕获表。
  • 可以随时按需运行增量快照,并根据需要重复该过程以适应数据库更新。例如,可能会在修改连接器配置以将表添加到其table.include.list属性后重新运行快照。

6.增量快照过程

当运行增量快照时,Debezium 按主键对每个表进行排序,然后根据配置的块大小将表拆分为块。一个块一个块地工作,然后它捕获一个块中的每个表行。对于它捕获的每一行,快照都会发出一个READ事件。该事件表示块的快照开始时行的值。

随着快照的进行,其他进程可能会继续访问数据库,从而可能修改表记录。为反映此类更改,INSERT、UPDATE或DELETE操作会照常提交到事务日志。同样,正在进行的 Debezium streaming 进程会继续检测这些变更事件,并向 Kafka 发出相应的变更事件记录。

Debezium 如何解决具有相同主键的记录之间的冲突
在某些情况下,流处理发出的UPDATE或DELETE事件是乱序接收的。READ也就是说,流处理可能会在快照捕获包含该行事件的块之前发出修改表行的事件。当快照最终READ为该行发出相应的事件时,它的值已经被取代。为了确保以正确的逻辑顺序处理乱序到达的增量快照事件,Debezium 采用缓冲方案来解决冲突。只有在解决快照事件和流式事件之间的冲突后,Debezium 才会向 Kafka 发出事件记录。

7.快照窗口

为了帮助解决迟到READ事件和修改同一表行的流式事件之间的冲突,Debezium 采用了所谓的快照窗口。快照窗口划分了增量快照捕获指定表块数据的时间间隔。在块的快照窗口打开之前,Debezium 遵循其通常的行为并从事务日志直接向下游发送事件到目标 Kafka 主题。但是从特定块的快照打开的那一刻起,直到它关闭,Debezium 执行重复数据删除步骤来解决具有相同主键的事件之间的冲突。

对于每个数据集合,Debezium 发出两种类型的事件,并将它们的记录存储在单个目标 Kafka 主题中。它直接从表中捕获的快照记录作为READ操作发出。同时,随着用户继续更新数据收集中的记录,事务日志也会更新以反映每次提交,Debezium 会针对每次更改发出UPDATE或DELETE操作。

当快照窗口打开并且 Debezium 开始处理快照块时,它会将快照记录传送到内存缓冲区。在快照窗口期间,READ将缓冲区中事件的主键与传入流式事件的主键进行比较。如果没有找到匹配项,流式事件记录将直接发送到 Kafka。如果 Debezium 检测到匹配项,它会丢弃缓冲READ事件,并将流式记录写入目标主题,因为流式事件在逻辑上会取代​​静态快照事件。块的快照窗口关闭后,缓冲区仅包含READ不存在相关事务日志事件的事件。Debezium 将这些剩余READ事件发送到表的 Kafka 主题。

连接器为每个快照块重复该过程。

警告:

PostgreSQL 的 Debezium 连接器不支持在运行增量快照时更改架构。如果模式更改是在增量快照开始之前但在发送信号之后执行的,则 passthrough 配置选项database.autosave将设置conservative为正确处理模式更改。

8.触发增量快照

目前,启动增量快照的唯一方法是向源数据库上的信号表发送临时快照信号。

将信号作为 SQLINSERT查询提交到信号表。

Debezium 检测到信号表中的更改后,它会读取信号,并运行请求的快照操作。

您提交的查询指定要包含在快照中的表,并且可以选择指定快照操作的类型。目前,快照操作的唯一有效选项是默认值incremental.

要指定要包含在快照中的表,请提供一个data-collections列出表的数组或用于匹配表的正则表达式数组,例如,

{“data-collections”: [“public.MyFirstTable”, “public.MySecondTable”]}

增量快照信号的数组data-collections没有默认值。如果data-collections数组为空,Debezium 检测到不需要任何操作并且不执行快照。

注意:

如果要包含在快照中的表的名称在数据库、模式或表的名称中包含点,则要将表添加到data-collections数组中,必须将名称的每个部分用双引号转义. 例如,要包括存在于架构中且名称为.的

表,请使用以下格式:。publicMy.Table"public".“My.Table”

先决条件

  • 信令已启用。

    • 源数据库上存在信令数据集合。
    • 信令数据收集在属性中指定signal.data.collection。

程序
1.发送 SQL 查询以将临时增量快照请求添加到信令表:

INSERT INTO <signalTable> (id, type, data) VALUES ('', '', '{"data-collections": ["",""],"type":"","additional-condition":""}');

例如,

INSERT INTO myschema.debezium_signal (id, type, data) 
values ('ad-hoc-1',   
    'execute-snapshot',  
    '{"data-collections": ["schema1.table1", "schema2.table2"], 
    "type":"incremental"}, 
    "additional-condition":"color=blue"}'); 

命令中的id、type、 和data参数的值对应于信令表的字段。

下表描述了示例中的参数:

参数 默认值
myschema.debezium_signal 指定源数据库上信令表的完全限定名称。
ad-hoc-1 该id参数指定一个任意字符串,该字符串被指定为id信号请求的标识符。使用此字符串可将日志记录消息标识到信令表中的条目。Debezium 不使用这个字符串。相反,在快照期间,Debezium 会生成自己的id字符串作为水印信号。
execute-snapshot 该type参数指定信号要触发的操作。
data-collections 信号字段的必需组件data,指定表名数组或正则表达式以匹配要包含在快照中的表名。该数组列出了通过完全限定名称匹配表的正则表达式,使用与您在配置属性中指定连接器信令表名称相同的格式signal.data.collection。
incremental 信号字段的可选type组件data,指定要运行的快照操作的类型。目前,唯一有效的选项是默认值incremental.如果不指定值,连接器将运行增量快照。
additional-condition 一个可选字符串,它根据表的列指定条件,以捕获表内容的子集。

9.临时增量快照additional-condition

如果希望快照仅包含表中内容的子集,可以通过将参数附加additional-condition到快照信号来修改信号请求。

典型快照的 SQL 查询采用以下形式:

SELECT * FROM <tableName> ....

通过添加additional-condition参数,可以将WHERE条件附加到 SQL 查询,如以下示例所示:

SELECT * FROM <tableName> WHERE <additional-condition> ....

以下示例显示了一个 SQL 查询,用于将带有附加条件的临时增量快照请求发送到信令表:

INSERT INTO <signalTable> (id, type, data) VALUES ('', '', '{"data-collections": ["",""],"type":"","additional-condition":""}');

例如,假设您有一个products包含以下列的表:

  • id(首要的关键)
  • color
  • quantity

如果希望表的增量快照products只包含where数据项color=blue,可以使用如下SQL语句触发快照:

INSERT INTO myschema.debezium_signal (id, type, data) VALUES('ad-hoc-1', 'execute-snapshot', '{"data-collections": ["schema1.products"],"type":"incremental", "additional-condition":"color=blue"}');

该additional-condition参数还使您能够传递基于多个列的条件。例如,使用上products一个示例中的表,可以提交一个查询来触发增量快照,该快照仅包含满足以下条件的那些项目的color=blue数据quantity>10:

INSERT INTO myschema.debezium_signal (id, type, data) VALUES('ad-hoc-1', 'execute-snapshot', '{"data-collections": ["schema1.products"],"type":"incremental", "additional-condition":"color=blue AND quantity>10"}');

以下示例显示了连接器捕获的增量快照事件的 JSON。

示例:增量快照事件消息

{
    "before":null,
    "after": {
        "pk":"1",
        "value":"New data"
    },
    "source": {
        ...
        "snapshot":"incremental" 
    },
    "op":"r", 
    "ts_ms":"1620393591654",
    "transaction":null
}
字段名称 描述
snapshot 指定要运行的快照操作的类型。
目前,唯一有效的选项是默认值incremental. 在提交给信号表的 SQL 查询中指定一个值是可选的。 如果不指定值,连接器将运行增量快照。
op 指定事件类型。
快照事件的值为r,表示一个READ操作。

10.停止增量快照

还可以通过向源数据库上的表发送信号来停止增量快照。通过发送 SQL 查询向表提交停止快照信号INSERT。

Debezium 检测到信号表中的更改后,它会读取信号,如果正在进行增量快照操作,则会停止。

您提交的查询指定 的快照操作incremental,以及(可选)要删除的当前运行快照的表。

先决条件

  • 信令已启用。

    • 源数据库上存在信令数据集合。
    • 信令数据收集在属性中指定signal.data.collection。

程序
1.发送 SQL 查询以停止对信令表的临时增量快照:

INSERT INTO <signalTable> (id, type, data) values ('', 'stop-snapshot', '{"data-collections": ["",""],"type":"incremental"}');

例如,

INSERT INTO myschema.debezium_signal (id, type, data) 
values ('ad-hoc-1',   
    'stop-snapshot',  
    '{"data-collections": ["schema1.table1", "schema2.table2"], 
    "type":"incremental"}'); 

idsignal 命令中的、type、 和data参数的值对应于信令表的字段。

下表描述了示例中的参数:

表 4 向信令表发送停止增量快照信号的SQL命令字段说明

参数 说明
myschema.debezium_signal 指定源数据库上信令表的完全限定名称。
ad-hoc-1 该id参数指定一个任意字符串,该字符串被指定为id信号请求的标识符。使用此字符串可将日志记录消息标识到信令表中的条目。Debezium 不使用这个字符串。
stop-snapshot 指定type参数指定信号要触发的操作。
data-collections 信号字段的可选组件data,指定表名数组或正则表达式以匹配要从快照中删除的表名。该数组列出了通过完全限定名称匹配表的正则表达式,使用与您在配置属性中指定连接器信令表名称相同的格式signal.data.collection。如果省略该data字段的这一部分,信号将停止正在进行的整个增量快照。
incremental data指定要停止的快照操作类型的信号字段的必需组件。目前,唯一有效的选项是incremental。如果不指定type值,该信号将无法停止增量快照。

11.流式变化

PostgreSQL 连接器通常将绝大部分时间用于从它所连接的 PostgreSQL 服务器流式传输更改。这种机制依赖于PostgreSQL 的复制协议。该协议使客户端能够在服务器的事务日志中某些位置提交更改时从服务器接收更改,这些位置称为日志序列号 (LSN)。

每当服务器提交事务时,一个单独的服务器进程从逻辑解码插件调用回调函数。此函数处理交易中的更改,将它们转换为特定格式(在 Debezium 插件的情况下为 Protobuf 或 JSON)并将它们写入输出流,然后可供客户端使用。

Debezium PostgreSQL 连接器充当 PostgreSQL 客户端。当连接器收到更改时,它会将事件转换为 Debezium创建、更新或删除事件,其中包括事件的 LSN。PostgreSQL 连接器将记录中的这些更改事件转发到在同一进程中运行的 Kafka Connect 框架。Kafka Connect 进程以与生成它们相同的顺序将更改事件记录异步写入适当的 Kafka 主题。

Kafka Connect 会定期记录另一个 Kafka 主题中的最新偏移量。偏移量表示 Debezium 包含在每个事件中的特定于源的位置信息。对于PostgreSQL connector,每个change event中记录的LSN就是offset。

当 Kafka Connect 正常关闭时,它会停止连接器,将所有事件记录刷新到 Kafka,并记录从每个连接器接收到的最后一个偏移量。当 Kafka Connect 重新启动时,它会读取每个连接器的最后记录的偏移量,并以其最后记录的偏移量启动每个连接器。当连接器重新启动时,它会向 PostgreSQL 服务器发送请求,以发送刚好在该位置之后开始的事件。

注意:

PostgreSQL 连接器检索架构信息作为逻辑解码插件发送的事件的一部分。但是,连接器不会检索有关哪些列构成主键的信息。连接器从 JDBC 元数据(侧通道)获取此信息。如果表的主键定义发生变化(通过添加、删除或重命名主键列),则有一小段时间来自 JDBC 的主键信息与逻辑解码插件生成的更改事件不同步. 在这个极短的时间内,可能会创建一条密钥结构不一致的消息。为防止这种不一致,请按如下方式更新主键结构:

  1. 将数据库或应用程序置于只读模式。
  2. 让 Debezium 处理所有剩余的事件。
  3. 停止 Debezium。
  4. 更新相关表中的主键定义。
  5. 将数据库或应用程序置于读/写模式。
  6. 重新启动 Debezium。

12.PostgreSQL 10+ 逻辑解码支持 ( pgoutput)

从 PostgreSQL 10+ 开始,有一种逻辑复制流模式,称为pgoutputPostgreSQL 原生支持的模式。这意味着 Debezium PostgreSQL 连接器可以使用该复制流而无需额外的插件。这对于不支持或不允许安装插件的环境特别有价值。

主题名称
默认情况下,PostgreSQL 连接器将表中发生的所有INSERT、UPDATE和DELETE操作的更改事件写入特定于该表的单个 Apache Kafka 主题。连接器使用以下约定来命名更改事件主题:

topicPrefix.schemaName.tableName

以下列表提供了默认名称组件的定义:

主题前缀:配置属性指定的主题前缀topic.prefix。

架构名称:发生更改事件的数据库模式的名称。

表名:发生更改事件的数据库表的名称。

例如,假设这fulfillment是一个连接器配置中的逻辑服务器名称,该连接器正在捕获 PostgreSQL 安装中的更改,该安装具有一个数据库postgres和一个inventory包含四个表的模式:products、products_on_hand、customers、orders。连接器会将记录流式传输到这四个 Kafka 主题:

  • fulfillment.inventory.products
  • fulfillment.inventory.products_on_hand
  • fulfillment.inventory.customers
  • fulfillment.inventory.orders

现在假设这些表不是特定模式的一部分,而是在默认的publicPostgreSQL 模式中创建的。Kafka 主题的名称将是:

  • fulfillment.public.products
  • fulfillment.public.products_on_hand
  • fulfillment.public.customers
  • fulfillment.public.orders

连接器应用类似的命名约定来标记其事务元数据主题。

如果默认主题名称不符合您的要求,您可以配置自定义主题名称。要配置自定义主题名称,您可以在逻辑主题路由 SMT 中指定正则表达式。

13.事物元数据

Debezium 可以生成代表事务边界的事件并丰富数据更改事件消息。

对于每笔交易BEGIN和END,Debezium 都会生成一个包含以下字段的事件:

status:BEGIN或END。

id:唯一事务标识符的字符串表示,由 Postgres 事务 ID 本身和给定操作的 LSN 组成,用冒号分隔,即格式为txID:LSN.

ts_ms:数据源发生事务边界事件(BEGIN或事件)的时间。END如果数据源未向 Debezium 提供事件时间,则该字段代表 Debezium 处理事件的时间。

event_count(对于END事件):事务发出的事件总数。

data_collections(对于END事件):data_collection和元素对的数组event_count,指示连接器针对源自数据集合的更改发出的事件数。

例子

{
  "status": "BEGIN",
  "id": "571:53195829",
  "ts_ms": 1486500577125,
  "event_count": null,
  "data_collections": null
}

{
  "status": "END",
  "id": "571:53195832",
  "ts_ms": 1486500577691,
  "event_count": 2,
  "data_collections": [
    {
      "data_collection": "s1.a",
      "event_count": 1
    },
    {
      "data_collection": "s2.a",
      "event_count": 1
    }
  ]
}

除非通过选项覆盖topic.transaction,否则事务事件将写入名为的主题。.transaction

14.更改数据事件扩充

启用事务元数据后,数据消息Envelope会增加一个新transaction字段。该字段以字段组合的形式提供有关每个事件的信息:

id:唯一交易标识符的字符串表示。

total_order:该事件在交易产生的所有事件中的绝对位置。

data_collection_order:事件在事务发出的所有事件中的每个数据收集位置。

以下是消息的示例:

{
  "before": null,
  "after": {
    "pk": "2",
    "aa": "1"
  },
  "source": {
   ...
  },
  "op": "c",
  "ts_ms": "1580390884335",
  "transaction": {
    "id": "571:53195832",
    "total_order": "1",
    "data_collection_order": "1"
  }

三、数据变更事件

Debezium PostgreSQL 连接器为每个行级INSERT、UPDATE和DELETE操作生成一个数据更改事件。每个事件都包含一个键和一个值。键和值的结构取决于被更改的表。

Debezium 和 Kafka Connect 是围绕连续的事件消息流设计的。但是,这些事件的结构可能会随着时间的推移而发生变化,这对消费者来说可能很难处理。为了解决这个问题,每个事件都包含其内容的架构,或者,如果您使用的是架构注册表,则还包含一个架构 ID,消费者可以使用该 ID 从注册表中获取架构。这使得每个事件都是独立的。

以下框架 JSON 显示了更改事件的四个基本部分。但是,您如何配置您选择在应用程序中使用的 Kafka Connect 转换器决定了这四个部分在更改事件中的表示。仅当您将转换器配置为生成字段时,字段schema才处于更改事件中。同样,仅当您配置转换器来生成事件键和事件负载时,事件键和事件有效负载才会出现在更改事件中。如果您使用 JSON 转换器并将其配置为生成所有四个基本更改事件部分,则更改事件具有以下结构:

{
 "schema": { 
   ...
  },
 "payload": { 
   ...
 },
 "schema": { 
   ...
 },
 "payload": { 
   ...
 },
}

表 5. 变更事件基本内容概览

schema 第一个schema字段是事件键的一部分。它指定了一个 Kafka Connect 模式,该模式描述了事件键payload部分中的内容。换句话说,第一个schema字段描述了主键的结构,或者如果表没有主键,则为被更改的表的唯一键。可以通过设置message.key.columns连接器配置属性来覆盖表的主键。在这种情况下,第一个模式字段描述了由该属性标识的键的结构
payload 第一个payload字段是事件键的一部分。它具有前一个字段描述的结构schema,并且包含已更改行的键。
schema 第二个schema字段是事件值的一部分。它指定描述事件值payload部分内容的 Kafka Connect 模式。换句话说,第二个schema描述了被更改的行的结构。通常,此架构包含嵌套架构。
payload 第二个payload字段是事件值的一部分。它具有前一个字段所描述的结构schema,并且包含已更改行的实际数据。

默认情况下,连接器流将事件记录更改为名称与事件的原始表相同的主题。

从 Kafka 0.10 开始,Kafka 可以选择使用消息创建(由生产者记录)或由 Kafka 写入日志的时间戳来记录事件键和值。

1.更改事件键

对于给定的表,更改事件的键具有一个结构,该结构在创建事件时包含表主键中每一列的字段。或者,如果表已REPLICA IDENTITY设置为FULL或USING INDEX每个唯一键约束都有一个字段。

考虑customers在数据库架构中定义的表public以及该表的更改事件键的示例。

示例表

CREATE TABLE customers (
  id SERIAL,
  first_name VARCHAR(255) NOT NULL,
  last_name VARCHAR(255) NOT NULL,
  email VARCHAR(255) NOT NULL,
  PRIMARY KEY(id)
);

示例更改事件键
如果topic.prefix连接器配置属性的值为PostgreSQL_server,则具有此定义的表的每个更改事件都customers具有相同的键结构,在 JSON 中如下所示:

{
  "schema": { 
    "type": "struct",
    "name": "PostgreSQL_server.public.customers.Key", 
    "optional": false, 
    "fields": [ 
          {
              "name": "id",
              "index": "0",
              "schema": {
                  "type": "INT32",
                  "optional": "false"
              }
          }
      ]
  },
  "payload": { 
      "id": "1"
  },
}

表 6. 更改事件键的说明

字段名称 描述
schema 键的模式部分指定了一个 Kafka Connect 模式,它描述了键payload部分中的内容。
PostgreSQL_server.inventory.customers.Key 定义密钥负载结构的架构名称。此架构描述了已更改表的主键结构。键模式名称的格式为connector-name。数据库名称。表名。Key. 在这个例子中:PostgreSQL_server是生成此事件的连接器的名称。inventory是包含已更改表的数据库。customers是被更新的表。
optional 指示事件键是否必须在其payload字段中包含一个值。在此示例中,密钥的有效负载中的值是必需的。当表没有主键时,键的有效负载字段中的值是可选的。
fields 指定 中预期的每个字段payload,包括每个字段的名称、索引和架构。
payload 包含为其生成此更改事件的行的键。在此示例中,键包含一个id值为 的字段1。

尽管column.exclude.list和column.include.list连接器配置属性允许您仅捕获表列的子集,但主键或唯一键中的所有列始终包含在事件键中。

如果表没有主键或唯一键,则更改事件的键为空。没有主键或唯一键约束的表中的行不能被唯一标识。

2.更改事件值

更改事件中的值比键复杂一点。与键一样,值也有一个schema部分和一个payload部分。该schema部分包含描述Envelope该payload部分结构的架构,包括其嵌套字段。创建、更新或删除数据的操作的更改事件都有一个带有信封结构的值负载。

考虑用于显示更改事件键示例的同一个示例表:

CREATE TABLE customers (
  id SERIAL,
  first_name VARCHAR(255) NOT NULL,
  last_name VARCHAR(255) NOT NULL,
  email VARCHAR(255) NOT NULL,
  PRIMARY KEY(id)
);

更改此表的更改事件的值部分根据REPLICA IDENTITY事件所针对的设置和操作而变化。

副本身份
REPLICA IDENTITY 是一个特定于 PostgreSQL 的表级设置,用于确定可用于 UPDATE 和 DELETE 事件的逻辑解码插件的信息量。更具体地说,每当发生 UPDATE 或 DELETE 事件时,REPLICA IDENTITY 的设置控制哪些(如果有的话)信息可用于所涉及的表列的先前值。

有 4 个可能的值REPLICA IDENTITY:

  • DEFAULT - 默认行为是 UPDATE 和 DELETE 事件包含该表的主键列的先前值(如果该表具有主键)。对于 UPDATE 事件,仅存在具有更改值的主键列。如果表没有主键,则连接器不会为该表发出 UPDATE 或 DELETE 事件。对于没有主键的表,连接器仅发出创建事件。通常,没有主键的表用于将消息附加到表的末尾,这意味着 UPDATE 和 DELETE 事件没有用。
  • NOTHING - 为 UPDATE 和 DELETE 操作发出的事件不包含有关任何表列的先前值的任何信息。
  • FULL - 为 UPDATE 和 DELETE 操作发出的事件包含表中所有列的先前值。
  • INDEX index-name - 为 UPDATE 和 DELETE 操作发出的事件包含指定索引中包含的列的先前值。 UPDATE 事件还包含具有更新值的索引列。

3.创建事件

以下示例显示了连接器为在表中创建数据的操作生成的更改事件的值部分customers:

{
    "schema": { 
        "type": "struct",
        "fields": [
            {
                "type": "struct",
                "fields": [
                    {
                        "type": "int32",
                        "optional": false,
                        "field": "id"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "first_name"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "last_name"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "email"
                    }
                ],
                "optional": true,
                "name": "PostgreSQL_server.inventory.customers.Value", 
                "field": "before"
            },
            {
                "type": "struct",
                "fields": [
                    {
                        "type": "int32",
                        "optional": false,
                        "field": "id"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "first_name"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "last_name"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "email"
                    }
                ],
                "optional": true,
                "name": "PostgreSQL_server.inventory.customers.Value",
                "field": "after"
            },
            {
                "type": "struct",
                "fields": [
                    {
                        "type": "string",
                        "optional": false,
                        "field": "version"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "connector"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "name"
                    },
                    {
                        "type": "int64",
                        "optional": false,
                        "field": "ts_ms"
                    },
                    {
                        "type": "boolean",
                        "optional": true,
                        "default": false,
                        "field": "snapshot"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "db"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "schema"
                    },
                    {
                        "type": "string",
                        "optional": false,
                        "field": "table"
                    },
                    {
                        "type": "int64",
                        "optional": true,
                        "field": "txId"
                    },
                    {
                        "type": "int64",
                        "optional": true,
                        "field": "lsn"
                    },
                    {
                        "type": "int64",
                        "optional": true,
                        "field": "xmin"
                    }
                ],
                "optional": false,
                "name": "io.debezium.connector.postgresql.Source", 
                "field": "source"
            },
            {
                "type": "string",
                "optional": false,
                "field": "op"
            },
            {
                "type": "int64",
                "optional": true,
                "field": "ts_ms"
            }
        ],
        "optional": false,
        "name": "PostgreSQL_server.inventory.customers.Envelope" 
    },
    "payload": { 
        "before": null, 
        "after": { 
            "id": 1,
            "first_name": "Anne",
            "last_name": "Kretchmar",
            "email": "[email protected]"
        },
        "source": { 
            "version": "2.2.1.Final",
            "connector": "postgresql",
            "name": "PostgreSQL_server",
            "ts_ms": 1559033904863,
            "snapshot": true,
            "db": "postgres",
            "sequence": "[\"24023119\",\"24023128\"]",
            "schema": "public",
            "table": "customers",
            "txId": 555,
            "lsn": 24023128,
            "xmin": null
        },
        "op": "c", 
        "ts_ms": 1559033904863 
    }
}

表 7.创建事件值字段说明

字段名称 描述
schema 值的架构,它描述了值的有效负载的结构。在连接器为特定表生成的每个更改事件中,更改事件的值模式都是相同的。
name 在架构部分,每个名称字段指定值有效负载中字段的架构。PostgreSQL_server.inventory.customers.Value 是负载前后字段的模式。此模式特定于客户表。前后字段的模式名称采用 logicalName.tableName.Value 的形式,这确保了模式名称在数据库中是唯一的。这意味着当使用 Avro 转换器时,每个逻辑源中每个表的 Avro 模式都有自己的演变和历史。
name io.debezium.connector.postgresql.Source 是负载源字段的模式。此架构特定于 PostgreSQL 连接器。连接器将它用于它生成的所有事件。
name PostgreSQL_server.inventory.customers.Envelope 是负载整体结构的模式,其中 PostgreSQL_server 是连接器名称,inventory 是数据库,customers 是表。
payload 该值的实际数据。这是更改事件提供的信息。事件的 JSON 表示可能看起来比它们描述的行大得多。这是因为 JSON 表示必须包括消息的架构和有效负载部分。但是,通过使用 Avro 转换器,您可以显着减小连接器流式传输到 Kafka 主题的消息的大小。
before 一个可选字段,指定事件发生前行的状态。当 op 字段为 c 表示创建时,如本例中所示,before 字段为空,因为此更改事件用于新内容。该字段是否可用取决于每个表的 REPLICA IDENTITY 设置。
after 一个可选字段,指定事件发生后行的状态。在此示例中,after 字段包含新行的 id、first_name、last_name 和 email 列的值。
source 描述事件源元数据的必填字段。此字段包含的信息可用于将此事件与其他事件进行比较,包括事件的起源、事件发生的顺序以及事件是否属于同一事务。源元数据包括:Debezium 版本、连接器类型和名称、包含新行的数据库和表、附加偏移信息的字符串化 JSON 数组。第一个值始终是最后提交的 LSN,第二个值始终是当前的 LSN。任一值都可以为空。架构名称。如果事件是快照的一部分。执行操作的事务 ID。操作在数据库日志中的偏移量。在数据库中进行更改时的时间戳
op 描述导致连接器生成事件的操作类型的强制字符串。在此示例中,c 表示该操作创建了一行。有效值为:c = create、u = update、d = delete、r = read (applies to only snapshots)、t = truncate、m = message
ts_ms 显示连接器处理事件的时间的可选字段。该时间基于运行 Kafka Connect 任务的 JVM 中的系统时钟。在源对象中,ts_ms 指示在数据库中进行更改的时间。通过将 payload.source.ts_ms 的值与 payload.ts_ms 的值进行比较,您可以确定源数据库更新和 Debezium 之间的延迟。

4.更新事件

示例客户表中更新的更改事件的值与该表的创建事件具有相同的模式。同样,事件值的有效负载具有相同的结构。但是,事件值负载在更新事件中包含不同的值。以下是连接器为客户表中的更新生成的事件中更改事件值的示例:

{
    "schema": { ... },
    "payload": {
        "before": { 
            "id": 1
        },
        "after": { 
            "id": 1,
            "first_name": "Anne Marie",
            "last_name": "Kretchmar",
            "email": "[email protected]"
        },
        "source": { 
            "version": "2.2.1.Final",
            "connector": "postgresql",
            "name": "PostgreSQL_server",
            "ts_ms": 1559033904863,
            "snapshot": false,
            "db": "postgres",
            "schema": "public",
            "table": "customers",
            "txId": 556,
            "lsn": 24023128,
            "xmin": null
        },
        "op": "u", 
        "ts_ms": 1465584025523  
    }
}

表 8.更新事件值字段说明

字段名称 描述
before 一个可选字段,包含数据库提交之前行中的值。在此示例中,仅存在主键列 id,因为表的 REPLICA IDENTITY 设置默认为 DEFAULT。 + 要使更新事件包含行中所有列的先前值,您必须通过运行 ALTER TABLE customers REPLICA IDENTITY FULL 来更改 customers 表。
after 一个可选字段,指定事件发生后行的状态。在此示例中,first_name 值现在是 Anne Marie。
source 描述事件源元数据的必填字段。源字段结构与创建事件中的字段相同,但某些值不同。源元数据包括:Debezium 版本、连接器类型和名称、包含新行的数据库和表、架构名称、如果事件是快照的一部分(更新事件总是假的)、执行操作的事务 ID、操作在数据库日志中的偏移量、在数据库中进行更改时的时间戳
op 描述操作类型的强制字符串。在更新事件值中,操作字段值为 u,表示此行因更新而更改。
ts_ms 显示连接器处理事件的时间的可选字段。该时间基于运行 Kafka Connect 任务的 JVM 中的系统时钟。在源对象中,ts_ms 指示在数据库中进行更改的时间。通过将 payload.source.ts_ms 的值与 payload.ts_ms 的值进行比较,您可以确定源数据库更新和 Debezium 之间的延迟。

注意:
更新行的主键/唯一键的列会更改行键的值。当键更改时,Debezium 会输出三个事件:一个 DELETE 事件和一个带有该行旧键的逻辑删除事件,然后是一个带有该行新键的事件。详细信息在下一节中。

5.主键更新

更改行的主键字段的更新操作称为主键更改。对于主键更改,连接器发送旧键的 DELETE 事件记录和新(更新的)键的 CREATE 事件记录,而不是发送 UPDATE 事件记录。这些事件具有通常的结构和内容,此外,每个事件都有一个与主键更改相关的消息头:

  • DELETE 事件记录将 __debezium.newkey 作为消息头。此标头的值是更新行的新主键。
  • CREATE 事件记录将 __debezium.oldkey 作为消息头。此标头的值是更新行具有的先前(旧)主键。

删除事件
删除更改事件中的值与同一表的创建和更新事件具有相同的架构部分。示例客户表的删除事件中的负载部分如下所示:

{
    "schema": { ... },
    "payload": {
        "before": { 
            "id": 1
        },
        "after": null, 
        "source": { 
            "version": "2.2.1.Final",
            "connector": "postgresql",
            "name": "PostgreSQL_server",
            "ts_ms": 1559033904863,
            "snapshot": false,
            "db": "postgres",
            "schema": "public",
            "table": "customers",
            "txId": 556,
            "lsn": 46523128,
            "xmin": null
        },
        "op": "d", 
        "ts_ms": 1465581902461 
    }
}

表 9. 删除事件值字段说明

字段名称 描述
before 可选字段,指定事件发生前行的状态。在删除事件值中,before 字段包含在数据库提交删除之前行中的值。在此示例中,前字段仅包含主键列,因为表的 REPLICA IDENTITY 设置为 DEFAULT。
after 可选字段,指定事件发生后行的状态。在删除事件值中,后字段为空,表示该行不再存在。
source 描述事件源元数据的必填字段。在删除事件值中,源字段结构与同一表的创建和更新事件相同。许多源字段值也是相同的。在删除事件值中,ts_ms 和 lsn 字段值以及其他值可能已更改。但是删除事件值中的源字段提供相同的元数据:Debezium 版本、连接器类型和名称、包含已删除行的数据库和表、架构名称、如果事件是快照的一部分(对于删除事件始终为 false)、执行操作的事务 ID、操作在数据库日志中的偏移量、在数据库中进行更改时的时间戳
op 描述操作类型的强制字符串。 op 字段值为 d,表示该行已被删除。
ts_ms 显示连接器处理事件的时间的可选字段。该时间基于运行 Kafka Connect 任务的 JVM 中的系统时钟。在源对象中,ts_ms 指示在数据库中进行更改的时间。通过将 payload.source.ts_ms 的值与 payload.ts_ms 的值进行比较,您可以确定源数据库更新和 Debezium 之间的延迟。

删除更改事件记录为消费者提供处理此行删除所需的信息。

注意:
为了让消费者能够处理为没有主键的表生成的删除事件,请将表的 REPLICA IDENTITY 设置为 FULL。当表没有主键并且表的 REPLICA IDENTITY 设置为 DEFAULT 或 NOTHING 时,删除事件没有 before 字段。

PostgreSQL 连接器事件旨在与 Kafka 日志压缩一起使用。只要至少保留每个键的最新消息,日志压缩就可以删除一些较旧的消息。这让 Kafka 回收存储空间,同时确保主题包含完整的数据集,并可用于重新加载基于键的状态。

6.墓碑事件

当一行被删除时,删除事件值仍然适用于日志压缩,因为 Kafka 可以删除所有具有相同键的早期消息。但是,要让 Kafka 删除所有具有相同键的消息,消息值必须为空。为实现这一点,PostgreSQL 连接器在删除事件后跟一个特殊的逻辑删除事件,该事件具有相同的键但为空值。

7.截断事件

截断更改事件表示表已被截断。在这种情况下,消息键为空,消息值如下所示:

{
    "schema": { ... },
    "payload": {
        "source": { 
            "version": "2.2.1.Final",
            "connector": "postgresql",
            "name": "PostgreSQL_server",
            "ts_ms": 1559033904863,
            "snapshot": false,
            "db": "postgres",
            "schema": "public",
            "table": "customers",
            "txId": 556,
            "lsn": 46523128,
            "xmin": null
        },
        "op": "t", 
        "ts_ms": 1559033904961 
    }
}

表 10. 截断事件值字段的描述

字段描述 描述
source 描述事件源元数据的必填字段。在截断事件值中,源字段结构与同一表的创建、更新和删除事件相同,提供以下元数据:Debezium 版本、连接器类型和名称、包含新行的数据库和表、架构名称、如果事件是快照的一部分(对于删除事件始终为 false)、执行操作的事务 ID、操作在数据库日志中的偏移量、在数据库中进行更改时的时间戳
op 描述操作类型的强制字符串。 op 字段值为 t,表示此表已被截断。
ts_ms 显示连接器处理事件的时间的可选字段。该时间基于运行 Kafka Connect 任务的 JVM 中的系统时钟。在源对象中,ts_ms 指示在数据库中进行更改的时间。通过将 payload.source.ts_ms 的值与 payload.ts_ms 的值进行比较,您可以确定源数据库更新和 Debezium 之间的延迟。

如果单个 TRUNCATE 语句应用于多个表,将为每个截断表发出一个截断更改事件记录。

请注意,由于截断事件表示对整个表所做的更改并且没有消息键,除非您使用单个分区处理主题,否则与表相关的更改事件没有顺序保证(创建,更新等)并截断该表的事件。例如,当从不同分区读取这些事件时,消费者可能仅在该表的截断事件之后收到更新事件。

8.消息事件

此事件类型仅通过 Postgres 14+ 上的 pgoutput 插件支持(Postgres 文档)

消息事件表示通用逻辑解码消息已被直接插入到 WAL 中,通常使用 pg_logical_emit_message 函数。在这种情况下,消息键是一个具有名为 prefix 的单个字段的结构,带有插入消息时指定的前缀。事务性消息的消息值如下所示:

{
    "schema": { ... },
    "payload": {
        "source": { 
            "version": "2.2.1.Final",
            "connector": "postgresql",
            "name": "PostgreSQL_server",
            "ts_ms": 1559033904863,
            "snapshot": false,
            "db": "postgres",
            "schema": "",
            "table": "",
            "txId": 556,
            "lsn": 46523128,
            "xmin": null
        },
        "op": "m", 
        "ts_ms": 1559033904961, 
        "message": { 
            "prefix": "foo",
            "content": "Ymfy"
        }
    }
}

与其他事件类型不同,非事务性消息不会有任何关联的 BEGIN 或 END 事务事件。非事务性消息的消息值如下所示:

{
    "schema": { ... },
    "payload": {
        "source": { 
            "version": "2.2.1.Final",
            "connector": "postgresql",
            "name": "PostgreSQL_server",
            "ts_ms": 1559033904863,
            "snapshot": false,
            "db": "postgres",
            "schema": "",
            "table": "",
            "lsn": 46523128,
            "xmin": null
        },
        "op": "m", 
        "ts_ms": 1559033904961 
        "message": { 
            "prefix": "foo",
            "content": "Ymfy"
    }
}

表 11. 消息事件值字段的描述

字段名称 描述
source 描述事件源元数据的必填字段。在消息事件值中,源字段结构将没有任何消息事件的表或模式信息,并且只有在消息事件是事务性事件时才具有 txId。Debezium 版本、连接器类型和名称、数据库名称、架构名称(对于消息事件始终为“”)、表名(对于消息事件总是“”)、如果事件是快照的一部分(消息事件总是 false)、执行操作的事务的 ID(对于非事务性消息事件为空)、操作在数据库日志中的偏移量、事务性消息:消息插入 WAL 的时间戳、非事务性消息;连接器遇到消息时的时间戳
op 描述操作类型的强制字符串。 op字段值为m,表示这是一个消息事件。
ts_ms 显示连接器处理事件的时间的可选字段。该时间基于运行 Kafka Connect 任务的 JVM 中的系统时钟。对于事务性消息事件,源对象的 ts_ms 属性指示在事务性消息事件的数据库中进行更改的时间。通过将 payload.source.ts_ms 的值与 payload.ts_ms 的值进行比较,您可以确定源数据库更新和 Debezium 之间的延迟。对于非事务性消息事件,源对象的ts_ms表示连接器遇到消息事件的时间,而payload.ts_ms表示连接器处理事件的时间。这种差异是由于提交时间戳不存在于 Postgres 的通用逻辑消息格式中,并且非事务性逻辑消息之前没有 BEGIN 事件(具有时间戳信息)。
message 包含消息元数据的字段:前缀(文本)、内容(根据二进制处理模式设置编码的字节数组)

四、数据类型映射

PostgreSQL 连接器表示对具有事件的行的更改,这些事件的结构类似于该行所在的表。该事件包含每个列值的字段。该值在事件中的表示方式取决于列的 PostgreSQL 数据类型。以下部分描述连接器如何将 PostgreSQL 数据类型映射到事件字段中的文字类型和语义类型。

  • 文字类型描述了如何使用 Kafka Connect 模式类型按字面表示值:INT8、INT16、INT32、INT64、FLOAT32、FLOAT64、BOOLEAN、STRING、BYTES、ARRAY、MAP 和 STRUCT。
  • 语义类型描述了 Kafka Connect 模式如何使用字段的 Kafka Connect 模式名称来捕获字段的含义。

如果默认数据类型转换不能满足您的需要,您可以为连接器创建自定义转换器。

1.基本类型

下表描述了连接器如何映射基本类型。

表 12. PostgreSQL 基本数据类型的映射

PostgreSQL 数据类型 文字类型(模式类型) 语义类型(模式名称)和注释
BOOLEAN BOOLEAN n/a
BIT(1) BOOLEAN n/a
BIT( > 1) BYTES io.debezium.data.Bits长度模式参数包含一个表示位数的整数。生成的 byte[] 包含小端格式的位,并调整大小以包含指定的位数。例如,numBytes = n/8 + (n % 8 == 0 ? 0 : 1) 其中 n 是位数。
BIT VARYING[(M)] BYTES io.debezium.data.Bits长度模式参数包含一个表示位数的整数(如果没有为列指定长度,则为 2^31 - 1)。生成的 byte[] 包含小端形式的位,并根据内容调整大小。指定的大小(M)存储在 io.debezium.data.Bits 类型的长度参数中。
SMALLINT, SMALLSERIAL INT16 n/a
INTEGER, SERIAL INT32 n/a
BIGINT, BIGSERIAL, OID INT64 n/a
REAL FLOAT32 n/a
DOUBLE PRECISION FLOAT64 n/a
CHAR[(M)] STRING n/a
VARCHAR[(M)] STRING n/a
CHARACTER[(M)] STRING n/a
CHARACTER VARYING[(M)] STRING n/a
TIMESTAMPTZ, TIMESTAMP WITH TIME ZONE STRING io.debezium.time.ZonedTimestamp带有时区信息的时间戳的字符串表示形式,其中时区为 GMT。
TIMETZ, TIME WITH TIME ZONE STRING io.debezium.time.ZonedTime带有时区信息的时间值的字符串表示形式,其中时区为 GMT。
INTERVAL [P] INT64 io.debezium.time.MicroDuration(默认)使用 365.25 / 12.0 公式计算每月平均天数的时间间隔的近似微秒数。
INTERVAL [P] STRING io.debezium.time.Interval(当 interval.handling.mode 设置为字符串时)遵循模式 PYMDTHMS 的间隔值的字符串表示形式,例如 P1Y2M3DT4H5M6.78S。
BYTEA BYTES or STRING 不适用,根据连接器的二进制处理模式设置,可以是原始字节(默认)、base64 编码的字符串、base64-url-safe-encoded 的字符串或十六进制编码的字符串。Debezium 仅支持十六进制值的 Postgres bytea_output 配置。有关 PostgreSQL 二进制数据类型的更多信息,请参阅 PostgreSQL 文档。
JSON, JSONB STRING io.debezium.data.Json包含 JSON 文档、数组或标量的字符串表示形式。
XML STRING io.debezium.data.Xml包含 XML 文档的字符串表示形式。
UUID STRING io.debezium.data.Uuid包含 PostgreSQL UUID 值的字符串表示
POINT STRUCT io.debezium.data.geometry.Point包含具有两个 FLOAT64 字段 (x,y) 的结构。每个字段代表一个几何点的坐标。
LTREE STRING io.debezium.data.Ltree包含 PostgreSQL LTREE 值的字符串表示形式。
CITEXT STRING n/a
INET STRING n/a
INT4RANGE STRING 不适用,整数范围。
INT8RANGE STRING 不适用,bigint 的范围。
NUMRANGE STRING 不适用,数值范围
TSRANGE STRING 不适用,包含不带时区的时间戳范围的字符串表示形式。
TSTZRANGE STRING 不适用,包含具有本地系统时区的时间戳范围的字符串表示形式。
DATERANGE STRING 不适用,包含日期范围的字符串表示形式。它总是有一个唯一的上限。
ENUM STRING io.debezium.data.枚举,包含 PostgreSQL ENUM 值的字符串表示形式。允许的值集在允许的模式参数中维护。

2.时间类型
除了包含时区信息的 PostgreSQL TIMESTAMPTZ 和 TIMETZ 数据类型外,时间类型的映射方式取决于 time.precision.mode 连接器配置属性的值。以下部分描述了这些映射:

  • time.precision.mode=adaptive
  • time.precision.mode=adaptive_time_microseconds
  • time.precision.mode=connect

time.precision.mode=adaptive
当 time.precision.mode 属性设置为自适应时,默认情况下,连接器根据列的数据类型定义确定文字类型和语义类型。这确保事件准确地代表数据库中的值。

表 13. time.precision.mode 自适应时的映射

PostgreSQL 数据类型 文字类型(模式类型) 语义类型(模式名称)和注释
DATE INT32 io.debezium.time.Date表示自纪元以来的天数。
TIME(1), TIME(2), TIME(3) INT32 io.debezium.time.Time表示午夜后的毫秒数,不包括时区信息。
TIME(4), TIME(5), TIME(6) INT64 io.debezium.time.MicroTime表示午夜后的微秒数,不包括时区信息。
TIMESTAMP(1), TIMESTAMP(2), TIMESTAMP(3) INT64 io.debezium.time.MicroTime表示午夜后的微秒数,不包括时区信息。
TIMESTAMP(4), TIMESTAMP(5), TIMESTAMP(6), TIMESTAMP INT64 io.debezium.time.MicroTimestamp表示自纪元以来的微秒数,不包括时区信息。

time.precision.mode=adaptive_time_microseconds

当 time.precision.mode 配置属性设置为 adaptive_time_microseconds 时,连接器根据列的数据类型定义确定时间类型的文字类型和语义类型。这确保事件准确地表示数据库中的值,除了所有 TIME 字段都被捕获为微秒。

表 14. time.precision.mode 为 adaptive_time_microseconds 时的映射

PostgreSQL 数据类型 文字类型(模式类型) 语义类型(模式名称)和注释
DATE INT32 io.debezium.time.Date表示自纪元以来的天数。
TIME([P]) INT64 io.debezium.time.MicroTime表示以微秒为单位的时间值,不包括时区信息。 PostgreSQL 允许精度 P 在 0-6 范围内,以存储高达微秒的精度。
TIMESTAMP(1) , TIMESTAMP(2), TIMESTAMP(3) INT64 io.debezium.time.Timestamp表示经过纪元的毫秒数,不包括时区信息。
TIMESTAMP(4) , TIMESTAMP(5), TIMESTAMP(6), TIMESTAMP INT64 io.debezium.time.MicroTimestamp表示经过纪元的微秒数,不包括时区信息。

time.precision.mode=connect
当 time.precision.mode 配置属性设置为 connect 时,连接器使用 Kafka Connect 逻辑类型。当消费者只能处理内置的 Kafka Connect 逻辑类型而无法处理可变精度时间值时,这可能很有用。但是,由于 PostgreSQL 支持微秒精度,因此当数据库列具有大于 3 的小数秒精度值时,具有连接时间精度模式的连接器生成的事件会导致精度丢失。

表 15. time.precision.mode 连接时的映射

PostgreSQL 数据类型 文字类型(模式类型) 语义类型(模式名称)和注释
DATE INT32 org.apache.kafka.connect.data.date表示自纪元以来的天数。
TIME([P]) INT64 org.apache.kafka.connect.data.Time表示自午夜以来的毫秒数,不包括时区信息。 PostgreSQL 允许 P 在 0-6 范围内以存储高达微秒的精度,尽管当 P 大于 3 时,这种模式会导致精度损失。
TIMESTAMP([P]) INT64 org.apache.kafka.connect.data.Timestamp表示自纪元以来的毫秒数,不包括时区信息。 PostgreSQL 允许 P 在 0-6 范围内以存储高达微秒的精度,尽管当 P 大于 3 时,这种模式会导致精度损失。

2.TIMESTAMP类型

TIMESTAMP 类型表示没有时区信息的时间戳。此类列将转换为基于 UTC 的等效 Kafka Connect 值。例如,当 time.precision.mode 未设置为connect时,TIMESTAMP 值“2018-06-20 15:13:16.945104”由值为“1529507596945104”的 io.debezium.time.MicroTimestamp 表示。

运行 Kafka Connect 和 Debezium 的 JVM 的时区不会影响此转换。

PostgreSQL 支持在 TIMESTAMP 列中使用 +/- 无限值。这些特殊值在正无穷大的情况下转换为时间戳,值为 9223372036825200000,在负无穷大的情况下转换为 -9223372036832400000。此行为模仿 PostgreSQL JDBC 驱动程序的标准行为。有关参考,请参阅 org.postgresql.PGStatement 接口。

3.Decimal类型

PostgreSQL 连接器配置属性 decimal.handling.mode 的设置决定了连接器如何映射十进制类型。

当 decimal.handling.mode 属性设置为 precise 时,连接器对所有 DECIMAL、NUMERIC 和 MONEY 列使用 Kafka Connect org.apache.kafka.connect.data.Decimal 逻辑类型。这是默认模式。

表 16. decimal.handling.mode是precise时的映射

PostgreSQL 数据类型 文字类型(模式类型) 语义类型(模式名称)和注释
NUMERIC[(M[,D])] BYTES org.apache.kafka.connect.data.Decimal,scale 模式参数包含一个整数,表示小数点移动了多少位。
DECIMAL[(M[,D])] BYTES org.apache.kafka.connect.data.Decimal,scale 模式参数包含一个整数,表示小数点移动了多少位。
MONEY[(M[,D])] BYTES org.apache.kafka.connect.data.Decimal,scale 模式参数包含一个整数,表示小数点移动了多少位。比例架构参数由 money.fraction.digits 连接器配置属性确定。

这条规则有一个例外。在没有比例限制的情况下使用 NUMERIC 或 DECIMAL 类型时,来自数据库的值对于每个值具有不同的(可变)比例。在这种情况下,连接器使用 io.debezium.data.VariableScaleDecimal,它包含传输值的值和比例。

表 17. 没有标度约束时 DECIMAL 和 NUMERIC 类型的映射

PostgreSQL 数据类型 文字类型(模式类型) 语义类型(模式名称)和注释
NUMERIC STRUCT io.debezium.data.VariableScaleDecimal包含具有两个字段的结构:包含传输值的标度的 INT32 类型的标度和包含未标度形式的原始值的 BYTES 类型的值。
DECIMAL STRUCT io.debezium.data.VariableScaleDecimal包含具有两个字段的结构:包含传输值的标度的 INT32 类型的标度和包含未标度形式的原始值的 BYTES 类型的值。

当 decimal.handling.mode 属性设置为 double 时,连接器将所有 DECIMAL、NUMERIC 和 MONEY 值表示为 Java double 值,并对它们进行编码,如下表所示。

表 18. decimal.handling.mode 为 double 时的映射

PostgreSQL 数据类型 文字类型(模式类型) 语义类型(模式名称)和注释
NUMERIC[(M[,D])] FLOAT64
DECIMAL[(M[,D])] FLOAT64
MONEY[(M[,D])] FLOAT64

decimal.handling.mode 配置属性的最后一个可能设置是字符串。在这种情况下,连接器将 DECIMAL、NUMERIC 和 MONEY 值表示为它们的格式化字符串表示形式,并如下表所示对它们进行编码。

表 19. decimal.handling.mode 为String时的映射

PostgreSQL 数据类型 文字类型(模式类型) 语义类型(模式名称)和注释
NUMERIC[(M[,D])] STRING
DECIMAL[(M[,D])] STRING
MONEY[(M[,D])] STRING

当 decimal.handling.mode 的设置为 string 或 double 时,PostgreSQL 支持将 NaN(不是数字)作为特殊值存储在 DECIMAL/NUMERIC 值中。在这种情况下,连接器将 NaN 编码为 Double.NaN 或字符串常量 NAN。

4.HSTORE类型

PostgreSQL 连接器配置属性 hstore.handling.mode 的设置决定了连接器如何映射 HSTORE 值。

当 dhstore.handling.mode 属性设置为 json(默认值)时,连接器将 HSTORE 值表示为 JSON 值的字符串表示形式,并对它们进行编码,如下表所示。当 hstore.handling.mode 属性设置为 map 时,连接器将 MAP 架构类型用于 HSTORE 值。

表 20. HSTORE 数据类型的映射

PostgreSQL 数据类型 文字类型(模式类型) 语义类型(模式名称)和注释
HSTORE STRING io.debezium.data.Json,示例:使用 JSON 转换器的输出表示是 {“key” : “val”}
HSTORE MAP 不适用,示例:使用 JSON 转换器的输出表示是 {“key” : “val”}

5.默认值

如果为数据库模式中的列指定了默认值,则 PostgreSQL 连接器将尽可能尝试将此值传播到 Kafka 模式。支持最常见的数据类型,包括:

  • 布尔值
  • 数值类型(INT、FLOAT、NUMERIC 等)
  • 文本类型(CHAR、VARCHAR、TEXT 等)
  • 时间类型(DATE、TIME、INTERVAL、TIMESTAMP、TIMESTAMPTZ)
  • JSON、JSONB、XML
  • UUID

请注意,对于时间类型,默认值的解析由 PostgreSQL 库提供;因此,连接器也应该支持 PostgreSQL 通常支持的任何字符串表示形式。

在默认值由函数生成而不是直接内联指定的情况下,连接器将为给定数据类型导出等效于 0 的值。这些值包括:

  • 假的布尔值
  • 0 具有适当的精度,用于数字类型
  • 文本/XML 类型的空字符串
  • {} 用于 JSON 类型
  • 1970-01-01 用于 DATE、TIMESTAMP、TIMESTAMPTZ 类型
  • 时间为 00:00
  • INTERVAL 的纪元
  • 00000000-0000-0000-0000-000000000000 为 UUID

此支持目前仅扩展到函数的显式使用。例如,括号支持 CURRENT_TIMESTAMP(6),但不支持 CURRENT_TIMESTAMP。

对默认值传播的支持主要是为了在将 PostgreSQL 连接器与模式注册表一起使用时允许安全模式演化,该模式注册表强制执行模式版本之间的兼容性。由于这个主要问题,以及不同插件的刷新行为,Kafka 模式中存在的默认值不能保证始终与数据库模式中的默认值同步。

默认值可能会在 Kafka 架构中出现“延迟”,具体取决于给定插件何时/如何触发内存中架构的刷新。如果默认值在两次刷新之间多次更改,则值可能永远不会在 Kafka 模式中出现/被跳过

如果在连接器有等待处理的记录时触发架构刷新,则默认值可能会出现在 Kafka 架构中的“早期”。这是因为列元数据是在刷新时从数据库中读取的,而不是出现在复制消息中。如果连接器落后并且发生刷新,或者如果连接器停止一段时间而更新继续写入源数据库,则可能会在连接器启动时发生这种情况。

这种行为可能出乎意料,但仍然是安全的。只有模式定义受到影响,而消息中存在的实际值将与写入源数据库的内容保持一致。

五、设置 Postgres

在使用 PostgreSQL 连接器监控 PostgreSQL 服务器上提交的更改之前,请确定您打算使用哪个逻辑解码插件。如果您不打算使用本机 pgoutput 逻辑复制流支持,那么您必须将逻辑解码插件安装到 PostgreSQL 服务器中。之后,启用复制槽,并配置具有足够权限的用户来执行复制。

如果您的数据库由 Heroku Postgres 等服务托管,您可能无法安装该插件。如果是这样,并且如果您使用的是 PostgreSQL 10+,则可以使用 pgoutput 解码器支持来捕获数据库中的更改。如果这不是一个选项,您将无法将 Debezium 与您的数据库一起使用。

1.云中的 PostgreSQL

Amazon RDS 上的 PostgreSQL

可以捕获在 Amazon RDS 中运行的 PostgreSQL 数据库中的更改。去做这个:

  • 将实例参数 rds.logical_replication 设置为 1。
  • 通过以数据库 RDS 主用户身份运行查询 SHOW wal_level 来验证 wal_level 参数是否设置为逻辑。在多区域复制设置中可能不是这种情况。您不能手动设置此选项。当rds.logical_replication参数设置为1时会自动改变。如果在你做上述改变后wal_level没有设置为logical,可能是因为参数组改变后需要重启实例。重新启动发生在您的维护窗口期间,或者您可以手动启动重新启动。
  • 将 Debezium plugin.name 参数设置为 pgoutput。
  • 从具有 rds_replication 角色的 AWS 账户启动逻辑复制。该角色授予管理逻辑槽和使用逻辑槽流式传输数据的权限。默认情况下,只有 AWS 上的主用户账户具有 Amazon RDS 上的 rds_replication 角色。要使主账户以外的用户账户能够发起逻辑复制,您必须授予该账户 rds_replication 角色。例如,将 rds_replication 授予 。您必须具有超级用户访问权限才能向用户授予 rds_replication 角色。要使主账户以外的账户能够创建初始快照,您必须向要捕获的表上的账户授予 SELECT 权限。

Azure 上的 PostgreSQL
可以将 Debezium 与 A​​zure Database for PostgreSQL 一起使用,它支持 Debezium 支持的 pgoutput 逻辑解码插件。

将 Azure 复制支持设置为合乎逻辑的。您可以使用 Azure CLI 或 Azure 门户来配置它。例如,要使用 Azure CLI,需要执行以下 az postgres 服务器命令:

az postgres server configuration set --resource-group mygroup --server-name myserver --name azure.replication_support --value logical

az postgres server restart --resource-group mygroup --name myserver

CrunchyBridge 上的 PostgreSQL
可以将 Debezium 与 CrunchyBridge 一起使用;逻辑复制已经开启。 pgoutput 插件可用。您将必须创建一个复制用户并提供正确的权限。

重要:
使用 pgoutput 插件时,建议将 filtered 配置为 publication.autocreate.mode。如果您使用 all_tables,这是 publication.autocreate.mode 的默认值,并且未找到发布,则连接器会尝试使用 CREATE PUBLICATION FOR ALL TABLES; 创建一个,但由于缺少权限而失败.

2.安装逻辑解码输出插件

从 PostgreSQL 9.4 开始,读取预写日志更改的唯一方法是安装逻辑解码输出插件。插件用 C 语言编写、编译并安装在运行 PostgreSQL 服务器的机器上。插件使用许多 PostgreSQL 特定的 API。

PostgreSQL 连接器与 Debezium 支持的逻辑解码插件之一一起工作,以 Protobuf 格式或 pgoutput 格式从数据库接收更改事件。 pgoutput 插件随 PostgreSQL 数据库开箱即用。

为简单起见,Debezium 还提供了一个基于上游 PostgreSQL 服务器镜像的容器镜像,在容器镜像之上编译和安装插件。您可以使用此图像作为安装所需的详细步骤的示例。

注意:
Debezium 逻辑解码插件仅在 Linux 机器上安装和测试。对于 Windows 和其他操作系统,可能需要不同的安装步骤。

3.插件差异

插件行为并非在所有情况下都完全相同。这些差异已经确定:

虽然所有插件都会在流式传输期间检测到架构更改时从数据库刷新架构元数据,但 pgoutput 插件更“渴望”触发此类刷新。例如,对列的默认值的更改将触发 pgoutput 的刷新,而其他插件将不会知道此更改,直到另一个更改触发刷新(例如,添加新列)。这是由于pgoutput 的行为,而不是 Debezium 本身。

六、配置 PostgreSQL 服务器

如果你使用的是pgoutput以外的逻辑解码插件,安装后在PostgreSQL服务器上配置如下:

1.要在启动时加载插件,请将以下内容添加到 postgresql.conf 文件中:

# MODULES
shared_preload_libraries = 'decoderbufs' 

指示服务器在启动时加载 decoderbufs 逻辑解码插件(插件名称在 Protobuf make 文件中设置)。

2.要配置复制槽而不考虑使用的解码器,请在 postgresql.conf 文件中指定以下内容:

# REPLICATION
wal_level = logical             

指示服务器对预写日志使用逻辑解码。

根据您的要求,您可能必须在使用 Debezium 时设置其他 PostgreSQL 流复制参数。示例包括 max_wal_senders 和 max_replication_slots,用于增加可以同时访问发送服务器的连接器数量,以及用于限制复制槽将保留的最大 WAL 大小的 wal_keep_size。有关配置流复制的更多信息,请参阅 PostgreSQL 文档。

Debezium 使用 PostgreSQL 的逻辑解码,它使用复制槽。即使在 Debezium 中断期间,复制槽也保证保留 Debezium 所需的所有 WAL 段。出于这个原因,密切监视复制槽以避免过多的磁盘消耗和其他可能发生的情况很重要,例如如果复制槽长时间未使用则目录膨胀。

如果您使用 synchronous_commit 设置而不是 on,建议将 wal_writer_delay 设置为 10 毫秒等值,以实现更改事件的低延迟。否则,将应用其默认值,这会增加大约 200 毫秒的延迟。

七、设置用户权限

设置 PostgreSQL 服务器以运行 Debezium 连接器需要可以执行复制的数据库用户。复制只能由具有适当权限的数据库用户执行,并且只能针对配置数量的主机执行。

尽管默认情况下,超级用户具有必要的 REPLICATION 和 LOGIN 角色,但如安全性中所述,最好不要为 Debezium 复制用户提供提升的权限。相反,创建一个具有所需最低权限的 Debezium 用户。

先决条件

  • PostgreSQL 管理权限。

程序

  • 要为用户提供复制权限,请定义至少具有 REPLICATION 和 LOGIN 权限的 PostgreSQL 角色,然后将该角色授予用户。例如:
CREATE ROLE <name> REPLICATION LOGIN;

设置权限以启用 Debezium 在您使用 pgoutput 时创建 PostgreSQL 发布

如果您使用 pgoutput 作为逻辑解码插件,Debezium 必须以具有特定权限的用户身份在数据库中操作。

Debezium 从为表创建的发布中流式传输 PostgreSQL 源表的更改事件。发布包含一组过滤的更改事件,这些事件是从一个或多个表生成的。每个出版物中的数据都根据出版物规范进行过滤。该规范可以由 PostgreSQL 数据库管理员或 Debezium 连接器创建。要允许 Debezium PostgreSQL 连接器创建发布并指定要复制到它们的数据,连接器必须在数据库中以特定权限运行。

有几个选项可用于确定发布的创建方式。通常,最好在设置连接器之前为要捕获的表手动创建发布。但是,您可以以允许 Debezium 自动创建发布并指定添加到其中的数据的方式配置您的环境。

Debezium 使用包含列表和排除列表属性来指定如何将数据插入到发布中。有关启用 Debezium 以创建发布的选项的更多信息,请参阅 publication.autocreate.mode。

要让 Debezium 创建 PostgreSQL 发布,它必须以具有以下权限的用户身份运行:

  • 数据库中的复制权限以将表添加到发布。
  • 对数据库的 CREATE 权限以添加发布。
  • 表上的 SELECT 权限以复制初始表数据。表所有者自动拥有表的 SELECT 权限。

要将表添加到发布,用户必须是表的所有者。但是因为源表已经存在,所以需要一种机制来与原始所有者共享所有权。要启用共享所有权,您可以创建一个 PostgreSQL 复制组,然后将现有表所有者和复制用户添加到该组。

程序
1.创建复制组。

CREATE ROLE <replication_group>;

2.将表的原始所有者添加到组中。

GRANT REPLICATION_GROUP TO <original_owner>;

3,将 Debezium 复制用户添加到组中。

GRANT REPLICATION_GROUP TO <replication_user>;

4.将表的所有权转移到

ALTER TABLE <table_name> OWNER TO REPLICATION_GROUP;

为了让 Debezium 指定捕获配置,publication.autocreate.mode 的值必须设置为 filtered。

八、配置 PostgreSQL 以允许使用 Debezium 连接器主机进行复制

要使 Debezium 能够复制 PostgreSQL 数据,您必须将数据库配置为允许与运行 PostgreSQL 连接器的主机进行复制。要指定允许与数据库进行复制的客户端,请将条目添加到 PostgreSQL 基于主机的身份验证文件 pg_hba.conf。

程序

  • 将条目添加到 pg_hba.conf 文件以指定可以与数据库主机一起复制的 Debezium 连接器主机。例如,

pg_hba.conf file example:

local   replication     <youruser>                          trust   
host    replication     <youruser>  127.0.0.1/32            trust   
host    replication     <youruser>  ::1/128                 trust   
  • 指示服务器允许在本地(即在服务器计算机上)复制
  • 指示服务器允许本地主机上的 使用 IPV4 接收复制更改。
  • 指示服务器允许本地主机上的 使用 IPV6 接收复制更改。

九、支持的 PostgreSQL 拓扑

PostgreSQL 连接器可与独立的 PostgreSQL 服务器或 PostgreSQL 服务器集群一起使用。

如开头所述,PostgreSQL(适用于所有版本 ⇐ 12)仅支持主服务器上的逻辑复制槽。这意味着 PostgreSQL 集群中的副本无法配置为逻辑复制,因此 Debezium PostgreSQL 连接器只能与主服务器连接和通信。如果此服务器出现故障,连接器将停止。当集群修复后,如果原来的主服务器再次提升为主服务器,则可以重启连接器。但是,如果将具有插件和正确配置的不同 PostgreSQL 服务器提升为主服务器,则必须更改连接器配置以指向新的主服务器,然后才能重新启动连接器。

十、WAL磁盘空间消耗

在某些情况下,WAL 文件占用的 PostgreSQL 磁盘空间可能会激增或超出通常的比例。出现这种情况有几个可能的原因:

  • 服务器的 pg_replication_slots 视图的 confirmed_flush_lsn 列中提供了连接器已接收数据的 LSN。早于此 LSN 的数据不再可用,数据库负责回收磁盘空间。同样在 pg_replication_slots 视图中,restart_lsn 列包含连接器可能需要的最旧 WAL 的 LSN。如果 confirmed_flush_lsn 的值有规律地增加而 restart_lsn 的值滞后,则数据库需要回收空间。数据库通常以批块的形式回收磁盘空间。这是预期的行为,用户无需执行任何操作。
  • 正在跟踪的数据库中有许多更新,但只有极少数更新与连接器捕获更改的表和模式相关。这种情况可以通过周期性的心跳事件轻松解决。设置 heartbeat.interval.ms 连接器配置属性。
  • PostgreSQL 实例包含多个数据库,其中一个是高流量数据库。 Debezium 捕获与其他数据库相比流量较低的另一个数据库中的更改。 Debezium 然后无法确认 LSN,因为每个数据库的复制槽都在工作,并且没有调用 Debezium。由于 WAL 由所有数据库共享,因此使用的数量趋于增长,直到 Debezium 正在为其捕获更改的数据库发出事件。为了克服这个问题,有必要:
  • 使用 heartbeat.interval.ms 连接器配置属性启用定期心跳记录生成。
  • 定期从 Debezium 捕获更改的数据库发出更改事件。

然后,一个单独的进程将通过插入新行或重复更新同一行来定期更新表。 PostgreSQL 然后调用 Debezium,它确认最新的 LSN 并允许数据库回收 WAL 空间。该任务可以通过 heartbeat.action.query 连接器配置属性自动执行。

十一、部署

要部署 Debezium PostgreSQL 连接器,您需要安装 Debezium PostgreSQL 连接器存档、配置连接器,然后通过将其配置添加到 Kafka Connect 来启动连接器。

先决条件

  • 安装了 Zookeeper、Kafka 和 Kafka Connect。
  • PostgreSQL 已安装并设置为运行 Debezium 连接器。

程序

  • 下载 Debezium PostgreSQL 连接器插件存档。
  • 将文件提取到您的 Kafka Connect 环境中。
  • 将包含 JAR 文件的目录添加到 Kafka Connect 的 plugin.path 中。
  • 重新启动 Kafka Connect 进程以获取新的 JAR 文件。

十二、连接器配置示例

以下是 PostgreSQL 连接器的配置示例,该连接器连接到位于 192.168.99.100 的端口 5432 上的 PostgreSQL 服务器,其逻辑名称是 fulfillment。通常,您通过设置连接器可用的配置属性在 JSON 文件中配置 Debezium PostgreSQL 连接器。

您可以选择为数据库中的模式和表的子集生成事件。或者,您可以忽略、屏蔽或截断包含敏感数据、大于指定大小或您不需要的列。

{
  "name": "fulfillment-connector",  
  "config": {
    "connector.class": "io.debezium.connector.postgresql.PostgresConnector", 
    "database.hostname": "192.168.99.100", 
    "database.port": "5432", 
    "database.user": "postgres", 
    "database.password": "postgres", 
    "database.dbname" : "postgres", 
    "topic.prefix": "fulfillment", 
    "table.include.list": "public.inventory" 
  }
}
  • 注册到 Kafka Connect 服务时连接器的名称。
  • 此 PostgreSQL 连接器类的名称。
  • PostgreSQL 服务器的地址。
  • PostgreSQL 服务器的端口号。
  • 具有所需权限的 PostgreSQL 用户的名称。
  • 具有所需权限的 PostgreSQL 用户的密码。
  • 要连接的 PostgreSQL 数据库的名称
  • PostgreSQL 服务器/集群的主题前缀,它形成一个命名空间,用于连接器写入的所有 Kafka 主题的名称、Kafka Connect 模式名称以及 Avro 转换器时相应 Avro 模式的命名空间用过的。
  • 此连接器将监视的此服务器托管的所有表的列表。这是可选的,还有其他属性用于列出要包括或排除在监视之外的模式和表。

您可以使用 POST 命令将此配置发送到正在运行的 Kafka Connect 服务。该服务记录配置并启动一个执行以下操作的连接器任务:

  • 连接到 PostgreSQL 数据库。
  • 读取事务日志。
  • Streams 将事件记录更改为 Kafka 主题。

添加连接器配置
要运行 Debezium PostgreSQL 连接器,请创建一个连接器配置并将该配置添加到您的 Kafka Connect 集群。

先决条件

  • PostgreSQL 配置为支持逻辑复制。
  • 逻辑解码插件已安装。
  • 已安装 PostgreSQL 连接器。

程序

  • 为 PostgreSQL 连接器创建配置。
  • 使用 Kafka Connect REST API 将该连接器配置添加到您的 Kafka Connect 集群。

结果
连接器启动后,它会为连接器配置的 PostgreSQL 服务器数据库执行一致的快照。然后,连接器开始为行级操作生成数据更改事件,并将更改事件记录流式传输到 Kafka 主题。

十三、连接器属性

Debezium PostgreSQL 连接器有许多配置属性,您可以使用它们为您的应用程序实现正确的连接器行为。许多属性都有默认值。有关属性的信息组织如下:

  • 必需的配置属性
  • 高级配置属性
  • 直通配置属性

除非有默认值可用,否则以下配置属性是必需的。

表 23. 所需的连接器配置属性

属性 默认值 描述
name No default 连接器的唯一名称。尝试使用相同的名称再次注册将失败。所有 Kafka Connect 连接器都需要此属性。
connector.class No default 连接器的 Java 类的名称。对于 PostgreSQL 连接器,始终使用 io.debezium.connector.postgresql.PostgresConnector 的值。
tasks.max 1 应为此连接器创建的最大任务数。 PostgreSQL 连接器始终使用单个任务,因此不使用此值,因此默认值始终可以接受。
plugin.name decoderbufs PostgreSQL服务器上安装的PostgreSQL逻辑解码插件名称。支持的值为 decoderbufs 和 pgoutput。
slot.name debezium PostgreSQL 逻辑解码槽的名称,它是为流式传输来自特定插件的特定数据库/模式的更改而创建的。服务器使用此插槽将事件流式传输到您正在配置的 Debezium 连接器。插槽名称必须符合 PostgreSQL 复制插槽命名规则,其中规定:“每个复制插槽都有一个名称,可以包含小写字母、数字和下划线字符。”
slot.drop.on.stop false 当连接器以正常的预期方式停止时是否删除逻辑复制槽。默认行为是当连接器停止时,复制槽仍然为连接器配置。当连接器重新启动时,具有相同的复制槽使连接器能够从它停止的地方开始处理。仅在测试或开发环境中设置为 true。删除插槽允许数据库丢弃 WAL 段。当连接器重新启动时,它会执行一个新的快照,或者它可以从 Kafka Connect 偏移量主题中的持久偏移量继续。
publication.name dbz_publication 使用 pgoutput 时为流更改创建的 PostgreSQL 发布的名称。如果该发布尚不存在并且包含所有表,则在启动时创建该发布。 Debezium 然后应用自己的包含/排除列表过滤(如果已配置)以限制发布以更改感兴趣的特定表的事件。连接器用户必须具有超级用户权限才能创建此发布,因此通常最好在首次启动连接器之前创建发布。如果发布已经存在,无论是对于所有表还是配置了表的子集,Debezium 都会使用定义的发布。
database.hostname No default PostgreSQL 数据库服务器的 IP 地址或主机名。
database.port 5432 PostgreSQL 数据库服务器的整数端口号。
database.user No default 用于连接到 PostgreSQL 数据库服务器的 PostgreSQL 数据库用户的名称。
database.password No default 连接到 PostgreSQL 数据库服务器时使用的密码。
database.dbname No default 从中流式传输更改的 PostgreSQL 数据库的名称。
topic.prefix No default 为 Debezium 在其中捕获更改的特定 PostgreSQL 数据库服务器或集群提供命名空间的主题前缀。该前缀在所有其他连接器中应该是唯一的,因为它用作从该连接器接收记录的所有 Kafka 主题的主题名称前缀。在数据库服务器逻辑名称中只能使用字母数字字符、连字符、点和下划线。注意:不要更改此属性的值。如果更改名称值,则在重新启动后,连接器不会继续向原始主题发出事件,而是向名称基于新值的主题发出后续事件。
schema.include.list No default 一个可选的、以逗号分隔的正则表达式列表,匹配您要为其捕获更改的模式的名称。任何未包含在 schema.include.list 中的模式名称都被排除在捕获其更改之外。默认情况下,所有非系统模式都会捕获它们的更改。为了匹配模式的名称,Debezium 应用您指定为锚定正则表达式的正则表达式。也就是说,指定的表达式与模式的整个标识符匹配;它不匹配模式名称中可能存在的子字符串。如果您在配置中包含此属性,则不要同时设置 schema.exclude.list 属性。
schema.exclude.list No default 一个可选的、以逗号分隔的正则表达式列表,这些正则表达式匹配您不想为其捕获更改的模式的名称。任何名称未包含在 schema.exclude.list 中的模式都会捕获其更改,系统模式除外。为了匹配模式的名称,Debezium 应用您指定为锚定正则表达式的正则表达式。也就是说,指定的表达式与模式的整个标识符匹配;它不匹配模式名称中可能存在的子字符串。
如果您在配置中包含此属性,请不要设置 schema.include.list 属性。
table.include.list No default 可选的、以逗号分隔的正则表达式列表,匹配要捕获其更改的表的完全限定表标识符。设置此属性后,连接器仅捕获指定表中的更改。每个标识符的格式都是 schemaName.tableName。默认情况下,连接器会捕获正在捕获其更改的每个模式中的每个非系统表中的更改。为了匹配表的名称,Debezium 应用您指定为锚定正则表达式的正则表达式。也就是说,指定的表达式与表的整个标识符匹配;它与表名中可能存在的子字符串不匹配。
如果在配置中包含此属性,则不要同时设置 table.exclude.list 属性。
table.exclude.list No default 一个可选的、以逗号分隔的正则表达式列表,匹配您不想捕获其更改的表的完全限定表标识符。每个标识符的格式都是 schemaName.tableName。设置此属性后,连接器会捕获您未指定的每个表的更改。为了匹配表的名称,Debezium 应用您指定为锚定正则表达式的正则表达式。也就是说,指定的表达式与表的整个标识符匹配;它与表名中可能存在的子字符串不匹配。
如果在配置中包含此属性,请不要设置 table.include.list 属性。
column.include.list No default 一个可选的、以逗号分隔的正则表达式列表,匹配应包含在更改事件记录值中的列的完全限定名称。列的完全限定名称的格式为 schemaName.tableName.columnName。为了匹配列的名称,Debezium 应用您指定为锚定正则表达式的正则表达式。即表达式用于匹配列的整个名称字符串;它与列名中可能存在的子字符串不匹配。如果您在配置中包含此属性,则不要同时设置 column.exclude.list 属性。
column.exclude.list No default 一个可选的、以逗号分隔的正则表达式列表,匹配应从更改事件记录值中排除的列的完全限定名称。列的完全限定名称的格式为 schemaName.tableName.columnName。为了匹配列的名称,Debezium 应用您指定为锚定正则表达式的正则表达式。即表达式用于匹配列的整个名称字符串;它与列名中可能存在的子字符串不匹配。如果您在配置中包含此属性,请不要设置 column.include.list 属性。
skip.messages.without.change false 指定当包含的列没有变化时是否跳过发布消息。如果根据 column.include.list 或 column.exclude.list 属性包含的列没有变化,这实际上会过滤消息。注意:仅当表的 REPLICA IDENTITY 为 FULL 时才有效
time.precision.mode adaptive 时间、日期和时间戳可以用不同类型的精度表示:adaptive 根据数据库列的类型使用毫秒、微秒或纳秒精度值来捕获与数据库中完全相同的时间和时间戳值。adaptive_time_microseconds 根据数据库列的类型使用毫秒、微秒或纳秒精度值来捕获与数据库中完全相同的日期、日期时间和时间戳值。一个例外是 TIME 类型字段,它总是以微秒为单位捕获。connect 始终通过使用 Kafka Connect 的时间、日期和时间戳的内置表示来表示时间和时间戳值,无论数据库列的精度如何,它们都使用毫秒精度。
decimal.handling.mode precise 指定连接器应如何处理 DECIMAL 和 NUMERIC 列的值:precise 通过使用java.math.BigDecimal 以二进制形式表示更改事件中的值来精确表示值。double 使用double 值表示值,这可能会导致精度损失,但更易于使用。string 将值编码为格式化字符串,这些字符串易于使用,但会丢失有关真实类型的语义信息。
hstore.handling.mode map 指定连接器应如何处理 hstore 列的值:map 使用 MAP 表示值。json 通过使用 json 字符串表示值。此设置将值编码为格式化字符串,例如 {“key” : “val”}。有关详细信息,请参阅 PostgreSQL HSTORE 类型。
interval.handling.mode numeric 指定连接器应如何处理间隔列的值:numeric 表示使用近似微秒数的间隔。string 通过使用字符串模式表示 PYMDTHMS 精确地表示间隔。例如:P1Y2M3DT4H5M6.78S。
database.sslmode disable 是否使用与 PostgreSQL 服务器的加密连接。选项包括:禁用使用未加密的连接。require 使用安全(加密)连接,如果无法建立则失败。verify-ca 的行为与 require 类似,但也会根据配置的证书颁发机构 (CA) 证书验证服务器 TLS 证书,如果未找到有效的匹配 CA 证书,则会失败。verify-full 的行为类似于 verify-ca,但还会验证服务器证书是否与连接器尝试连接的主机相匹配。
database.tcpKeepAlive true 启用 TCP keep-alive 探测以验证数据库连接是否仍然有效。
tombstones.on.delete true 控制删除事件后是否跟有逻辑删除事件。true - 删除操作由删除事件和后续逻辑删除事件表示。false - 仅发出删除事件。删除源记录后,发出墓碑事件(默认行为)允许 Kafka 完全删除与已删除行的键相关的所有事件,以防为主题启用日志压缩。
message.key.columns empty string 一个表达式列表,指定连接器用于为它发布到指定表的 Kafka 主题的更改事件记录形成自定义消息键的列。默认情况下,Debezium 使用表的主键列作为它发出的记录的消息键。代替默认值,或为缺少主键的表指定键,您可以基于一个或多个列配置自定义消息键。要为表建立自定义消息键,请列出表,然后列出要用作消息键的列。每个列表条目都采用以下格式:

:,要使表键基于多个列名,请在列名之间插入逗号。每个完全限定的表名都是以下格式的正则表达式:<架构名称>.<表名称>该属性可以包含多个表的条目。使用分号分隔列表中的表条目。以下示例为表 inventory.customers 和 purchase.orders 设置消息键:inventory.customers:pk1,pk2;(.*).purchaseorders:pk3,pk4对于表 inventory.customer,列 pk1 和 pk2 被指定为消息键。对于任何模式中的采购订单表,列 pk3 和 pk4 服务器作为消息键。用于创建自定义消息键的列数没有限制。但是,最好使用指定唯一键所需的最小数量。请注意,在表上设置此属性并将 REPLICA IDENTITY 设置为 DEFAULT,如果键列不是表主键的一部分,将导致无法正确创建逻辑删除事件。将 REPLICA IDENTITY 设置为 FULL 是唯一的解决方案。 |
| publication.autocreate.mode | all_tables | 仅在使用 pgoutput 插件流式传输更改时适用。该设置决定了发布的创建方式。指定以下值之一:all_tables - 如果发布存在,连接器将使用它。如果发布不存在,则连接器会为数据库中连接器为其捕获更改的所有表创建一个发布。对于创建发布的连接器,它必须通过有权创建发布和执行复制的数据库用户帐户访问数据库。您可以使用以下 SQL 命令 CREATE PUBLICATION FOR ALL TABLES; 授予所需的权限。已禁用 - 连接器不会尝试创建发布。数据库管理员或配置为执行复制的用户必须在运行连接器之前创建发布。如果连接器找不到发布,连接器将抛出异常并停止。filtered - 如果发布存在,连接器将使用它。如果不存在发布,则连接器会为与 schema.include.list、schema.exclude.list、table.include.list 和 table.exclude.list 连接器配置指定的当前过滤器配置相匹配的表创建一个新发布特性。例如:CREATE PUBLICATION FOR TABLE 。如果发布存在,连接器会更新与当前过滤器配置匹配的表的发布。例如:ALTER PUBLICATION SET TABLE 。 |
| binary.handling.mode | bytes | 指定在更改事件中应如何表示二进制(bytea)列:bytes 将二进制数据表示为字节数组。base64 将二进制数据表示为 base64 编码的字符串。base64-url-safe 将二进制数据表示为 base64-url-safe-encoded 字符串。hex 将二进制数据表示为十六进制编码 (base16) 字符串。|
| schema.name.adjustment.mode | none | 指定应如何调整架构名称以与连接器使用的消息转换器兼容。可能的设置:none 不应用任何调整。avro 将 Avro 类型名称中不能使用的字符替换为下划线。avro_unicode 将 Avro 类型名称中不能使用的下划线或字符替换为相应的 unicode,如 uxxxx。注意: 是转义序列,类似于 Java 中的反斜杠|
| field.name.adjustment.mode | none | 指定应如何调整字段名称以与连接器使用的消息转换器兼容。可能的设置:none 不应用任何调整。avro 将 Avro 类型名称中不能使用的字符替换为下划线。avro_unicode 将 Avro 类型名称中不能使用的下划线或字符替换为相应的 unicode,如 uxxxx。注意: 是转义序列,类似于 Java 中的反斜杠|
|money.fraction.digits | 2 | 指定将 Postgres 货币类型转换为 java.math.BigDecimal 时应使用多少个小数位,它表示更改事件中的值。仅当 decimal.handling.mode 设置为 precise 时适用。 |
| message.prefix.include.list | No default |一个可选的、以逗号分隔的正则表达式列表,这些正则表达式与您希望连接器捕获的逻辑解码消息前缀的名称相匹配。默认情况下,连接器捕获所有逻辑解码消息。设置此属性后,连接器仅捕获具有该属性指定的前缀的逻辑解码消息。排除所有其他逻辑解码消息。为了匹配消息前缀的名称,Debezium 应用您指定的正则表达式作为锚定正则表达式。也就是说,指定的表达式匹配整个消息前缀字符串;该表达式与前缀中可能存在的子字符串不匹配。如果您在配置中包含此属性,则不要同时设置 message.prefix.exclude.list 属性。 |

以下高级配置属性具有适用于大多数情况的默认值,因此很少需要在连接器的配置中指定。

表 24. 高级连接器配置属性

属性 默认值 描述
converters No default 枚举连接器可以使用的自定义转换器实例的符号名称的逗号分隔列表。例如,isbn您必须设置 converters 属性以使连接器能够使用自定义转换器。对于为连接器配置的每个转换器,您还必须添加一个 .type 属性,它指定实现转换器接口的类的完全限定名称。 .type 属性使用以下格式:.type,例如,isbn.type: io.debezium.test.IsbnConverter,如果您想进一步控制已配置转换器的行为,您可以添加一个或多个配置参数以将值传递给转换器。要将任何其他配置参数与转换器相关联,请在参数名称前加上转换器的符号名称。例如,isbn.schema.name: io.debezium.postgresql.type.Isbn
snapshot.mode initial 指定连接器启动时执行快照的条件:initial - 连接器仅在没有为逻辑服务器名称记录偏移量时才执行快照。always - 连接器每次启动时都执行快照。never - 连接器从不执行快照。当以这种方式配置连接器时,其启动时的行为如下。如果 Kafka 偏移量主题中存在先前存储的 LSN,则连接器会继续从该位置流式传输更改。如果没有存储 LSN,则连接器从在服务器上创建 PostgreSQL 逻辑复制槽的时间点开始流式传输更改。只有当您知道所有感兴趣的数据仍然反映在 WAL 中时,永不快照模式才有用。initial_only - 连接器执行初始快照然后停止,不处理任何后续更改。导出 - 弃用custom - 连接器根据 snapshot.custom.class 属性的设置执行快照,这是 io.debezium.connector.postgresql.spi.Snapshotter 接口的自定义实现。
event.processing.failure.handling.mode fail 指定连接器在处理事件期间应如何对异常做出反应:fail 传播异常,指示有问题的事件的偏移量,并导致连接器停止。warn 记录有问题的事件的偏移量,跳过该事件并继续处理。skip 跳过有问题的事件并继续处理。
max.batch.size 2048 指定连接器处理的每批事件的最大大小的正整数值。
max.queue.size 8192 指定阻塞队列可以容纳的最大记录数的正整数值。当 Debezium 读取从数据库流出的事件时,它会在将事件写入 Kafka 之前将其放入阻塞队列中。在连接器接收消息的速度快于将消息写入 Kafka 的速度,或者 Kafka 变得不可用的情况下,阻塞队列可以为从数据库中读取更改事件提供背压。当连接器定期记录偏移量时,将忽略保留在队列中的事件。始终将 max.queue.size 的值设置为大于 max.batch.size 的值。
max.queue.size.in.bytes 0 一个长整数值,指定阻塞队列的最大容量(以字节为单位)。默认情况下,没有为阻塞队列指定容量限制。要指定队列可以消耗的字节数,请将此属性设置为正长值。如果还设置了 max.queue.size,则当队列的大小达到任一属性指定的限制时,写入队列将被阻止。例如设置max.queue.size=1000,max.queue.size.in.bytes=5000,当队列包含1000条记录后,或者队列中记录量达到后,写入队列被阻塞达到 5000 字节。
poll.interval.ms 500 正整数值,指定连接器在开始处理一批事件之前应等待新更改事件出现的毫秒数。默认为 500 毫秒。
include.unknown.datatypes false 指定连接器遇到数据类型未知的字段时的连接器行为。默认行为是连接器忽略更改事件中的字段并记录警告。如果您希望更改事件包含字段的不透明二进制表示,请将此属性设置为 true。这让消费者可以解码该字段。您可以通过设置二进制处理模式属性来控制精确表示。
status.update.interval.ms 10000 向服务器发送复制连接状态更新的频率,以毫秒为单位。该属性还控制在数据库关闭时检查数据库状态以检测死连接的频率。
heartbeat.interval.ms 0 控制连接器向 Kafka 主题发送心跳消息的频率。默认行为是连接器不发送心跳消息。心跳消息对于监视连接器是否正在从数据库接收更改事件很有用。心跳消息可能有助于减少连接器重新启动时需要重新发送的更改事件的数量。要发送心跳消息,请将此属性设置为正整数,表示心跳消息之间的毫秒数。当正在跟踪的数据库中有许多更新但只有极少数更新与连接器捕获更改的表和模式相关时,需要心跳消息。在这种情况下,连接器像往常一样从数据库事务日志中读取,但很少向 Kafka 发送更改记录。这意味着没有偏移量更新提交给 Kafka,并且连接器没有机会将最新检索到的 LSN 发送到数据库。数据库保留包含已由连接器处理的事件的 WAL 文件。发送心跳消息使连接器能够将最新检索到的 LSN 发送到数据库,这允许数据库回收不再需要的 WAL 文件正在使用的磁盘空间。
heartbeat.action.query No default 指定当连接器发送心跳消息时连接器在源数据库上执行的查询。这对于解决 WAL 磁盘空间消耗中描述的情况很有用,在这种情况下,从与高流量数据库相同的主机上的低流量数据库捕获更改会阻止 Debezium 处理 WAL 记录,从而通过数据库确认 WAL 位置。针对这种情况,在低流量数据库中创建一个心跳表,并将该属性设置为向该表中插入记录的语句,例如:插入 test_heartbeat_table (text) VALUES (‘test_heartbeat’)这允许连接器接收来自低流量数据库的更改并确认它们的 LSN,从而防止数据库主机上无限制的 WAL 增长。
schema.refresh.mode columns_diff 指定触发表内存模式刷新的条件。columns_diff 是最安全的模式。它确保内存中的模式始终与数据库表的模式保持同步。columns_diff_exclude_unchanged_toast 指示连接器在与从传入消息派生的模式存在差异时刷新内存中模式缓存,除非未更改的 TOATable 数据完全解释了差异。如果经常更新的表具有很少包含在更新中的 TOAST 数据,则此设置可以显着提高连接器性能。但是,如果从表中删除 TOATable 列,内存模式可能会过时。
slot.stream.params No default 以分号分隔的参数列表,以传递给已配置的逻辑解码插件。例如,add-tables=public.table,public.table2;include-lsn=true。
slot.max.retries 6 如果连接到复制槽失败,这是连续尝试连接的最大次数。
slot.retry.delay.ms 10000 (10 seconds) 当连接器无法连接到复制槽时,重试之间等待的毫秒数。
flush.lsn.source true 确定连接器是否应提交源 postgres 数据库中已处理记录的 LSN,以便可以删除 WAL 日志。如果您不希望连接器执行此操作,请指定 false。请注意,如果设置为 false,LSN 将不会被 Debezium 确认,因此 WAL 日志将不会被清除,这可能会导致磁盘空间问题。用户需要在 Debezium 之外处理 LSN 的确认。
provide.transaction.metadata false 确定连接器是否生成具有事务边界的事件并使用事务元数据丰富更改事件信封。如果您希望连接器执行此操作,请指定 true。
skipped.operations t 在流式传输期间将跳过的操作类型的逗号分隔列表。这些操作包括:c 用于插入/创建,u 用于更新,d 用于删除,t 用于截断,none 用于不跳过任何操作。默认情况下,会跳过截断操作。
signal.data.collection No default value 用于向连接器发送信号的数据集合的完全限定名称。
使用以下格式指定集合名称:<架构名称>.<表名称>
incremental.snapshot.chunk.size 1024 连接器在增量快照块期间提取并读入内存的最大行数。增加块大小可提供更高的效率,因为快照运行的快照查询数量更大。但是,更大的块大小也需要更多内存来缓冲快照数据。将块大小调整为可在您的环境中提供最佳性能的值。
xmin.fetch.interval.ms 0 从复制槽中读取 XMIN 的频率(以毫秒为单位)。 XMIN 值提供了新复制槽可以从哪里开始的下限。默认值 0 禁用跟踪 XMIN 跟踪。
topic.delimiter . 指定主题名称的分隔符,默认为 …
topic.cache.size 10000 用于在有界并发哈希映射中保存主题名称的大小。此缓存将有助于确定与给定数据集合对应的主题名称。
topic.heartbeat.prefix __debezium-heartbeat 控制连接器将心跳消息发送到的主题的名称。主题名称具有以下模式:topic.heartbeat.prefix.topic.prefix。例如,如果主题前缀是 fulfillment,则默认主题名称是 __debezium-heartbeat.fulfillment。
topic.transaction transaction 控制连接器将事务元数据消息发送到的主题的名称。主题名称具有以下模式:topic.prefix.topic.transaction例如,如果主题前缀是 fulfillment,则默认主题名称是 fulfillment.transaction。
snapshot.max.threads 1 指定连接器在执行初始快照时使用的线程数。要启用并行初始快照,请将该属性设置为大于 1 的值。在并行初始快照中,连接器同时处理多个表。此功能正在孵化。

十四、Debezium2.X接入PostgreSQL数据库实战详细总结

debezium同步postgresql数据库数据实际应用详细步骤请参考博主下面这篇博客

  • Debezium系列之:debezium同步postgresql数据库数据到kafka集群

更多Debezium实战应用可以参考博主Debezium专栏:Debezium专栏,Debezium实战应用详细总结

  • Debezium系列之第100篇文章:阶段性详细总结对Debezium使用方式的优化,详细介绍对Debezium集群和Kafka集群做的一系列优化
  • Debezium系列之:安装部署debezium详细步骤,并把debezium服务托管到systemctl
  • Debezium系列之:Debezium2.X版本Mysql数据库、Sqlserver数据库、MongoDB数据库debezium connector最新完整的参数配置,并详细介绍参数含义
  • Debezium系列之:打通Debezium2.0以上版本的使用技术
  • Debezium系列之:安装jmx导出器监控debezium指标
  • Debezium系列之:深入解读Debezium重要的jmx指标

你可能感兴趣的:(日常分享专栏,Debezium系列,Debezium2.X,PostgreSQL数据库,Debezium连接器)