Debezium 的 Oracle 连接器捕获并记录在 Oracle 服务器上的数据库中发生的行级更改,包括在连接器运行时添加的表。可以将连接器配置为针对模式和表的特定子集发出更改事件,或者忽略、屏蔽或截断特定列中的值。
Debezium 通过使用本机 LogMiner 数据库包或XStream API从 Oracle 获取更改事件。虽然该连接器可能适用于各种 Oracle 版本,但只有 Oracle EE 12 和 19 已经过测试。
要以最佳方式配置和运行 Debezium Oracle 连接器,了解连接器如何执行快照、流式传输更改事件、确定 Kafka 主题名称、使用元数据和实施事件缓冲是很有帮助的。
通常,Oracle 服务器上的重做日志配置为不保留数据库的完整历史记录。因此,Debezium Oracle 连接器无法从日志中检索数据库的完整历史记录。为了使连接器能够为数据库的当前状态建立基线,连接器第一次启动时,它会执行数据库的初始一致快照。
可以通过设置连接器配置属性的值来自定义连接器创建快照的方式snapshot.mode。默认情况下,连接器的快照模式设置为initial。
用于创建初始快照的默认连接器工作流
当快照模式设置为默认时,连接器完成以下任务来创建快照:
快照流程开始后,如果由于连接器故障、重平衡或其他原因导致流程中断,则流程会在连接器重启后重新启动。连接器完成初始快照后,它会从它在步骤 3 中读取的位置继续流式传输,这样它就不会错过任何更新。如果连接器出于任何原因再次停止,在它重新启动后,它会从之前停止的地方恢复流式传输更改。
连接器配置属性的设置
警告:如果在上次关闭连接器后将架构更改提交给数据库,请勿使用此模式执行快照。
默认情况下,连接器仅在首次启动后运行初始快照操作。在这个初始快照之后,在正常情况下,连接器不会重复快照过程。连接器捕获的任何未来更改事件数据仅通过流处理进入。
但是,在某些情况下,连接器在初始快照期间获取的数据可能会变得陈旧、丢失或不完整。为了提供一种重新捕获表数据的机制,Debezium 包含一个执行临时快照的选项。数据库中的以下更改可能会导致执行临时快照:
可以通过启动所谓的ad-hoc snapshot为您之前捕获快照的表重新运行快照。Ad hoc 快照需要使用信令表。您可以通过向 Debezium 信号表发送信号请求来启动临时快照。
当您启动现有表的临时快照时,连接器会将内容附加到表中已经存在的主题。如果删除了先前存在的主题,Debezium 可以在启用自动创建主题的情况下自动创建一个主题。
临时快照信号指定要包含在快照中的表。快照可以捕获数据库的全部内容,也可以只捕获数据库中表的一个子集。此外,快照可以捕获数据库中表内容的子集。
execute-snapshot您可以通过向信令表发送消息来指定要捕获的表。将信号类型设置execute-snapshot为incremental,并提供要包含在快照中的表的名称,如下表所述:
execute-snapshot临时信号记录示例
触发临时快照
execute-snapshot您可以通过向信令表添加具有信号类型的条目来启动临时快照。连接器处理消息后,开始快照操作。快照过程读取第一个和最后一个主键值,并将这些值用作每个表的起点和终点。根据表中的条目数和配置的块大小,Debezium 将表分成块,并继续为每个块连续快照,一次一个。
目前,execute-snapshot操作类型仅触发增量快照。
为了提供管理快照的灵活性,Debezium 包括一个补充快照机制,称为增量快照。增量快照依赖 Debezium 机制将信号发送到 Debezium 连接器。增量快照基于DDD-3设计文档。
在增量快照中,Debezium 不是像在初始快照中那样一次捕获数据库的完整状态,而是在一系列可配置的块中分阶段捕获每个表。您可以指定希望快照捕获的表以及每个块的大小。块大小决定了在对数据库执行每次提取操作期间快照收集的行数。增量快照的默认块大小为 1 KB。
随着增量快照的进行,Debezium 使用水印来跟踪其进度,维护它捕获的每个表行的记录。与标准的初始快照过程相比,这种分阶段的数据捕获方法具有以下优势:
增量快照过程
当您运行增量快照时,Debezium 按主键对每个表进行排序,然后根据配置的块大小将表拆分为块。一个块一个块地工作,然后它捕获一个块中的每个表行。对于它捕获的每一行,快照都会发出一个READ事件。该事件表示块的快照开始时行的值。
随着快照的进行,其他进程可能会继续访问数据库,从而可能修改表记录。为反映此类更改,INSERT、UPDATE或DELETE操作将照常提交到事务日志。同样,正在进行的 Debezium 流处理会继续检测这些变更事件,并向 Kafka 发出相应的变更事件记录。
Debezium 如何解决具有相同主键的记录之间的冲突
在某些情况下,流处理发出的UPDATE或DELETE事件是乱序接收的。READ也就是说,流处理可能会在快照捕获包含该行事件的块之前发出修改表行的事件。当快照最终READ为该行发出相应的事件时,它的值已经被取代。为了确保以正确的逻辑顺序处理乱序到达的增量快照事件,Debezium 采用缓冲方案来解决冲突。只有在解决快照事件和流式事件之间的冲突后,Debezium 才会向 Kafka 发出事件记录。
为了帮助解决迟到READ事件和修改同一表行的流式事件之间的冲突,Debezium 采用了所谓的快照窗口。快照窗口划分了增量快照捕获指定表块数据的时间间隔。在块的快照窗口打开之前,Debezium 遵循其通常的行为并从事务日志直接向下游发送事件到目标 Kafka 主题。但是从特定块的快照打开的那一刻起,直到它关闭,Debezium 执行重复数据删除步骤来解决具有相同主键的事件之间的冲突。
对于每个数据集合,Debezium 发出两种类型的事件,并将它们的记录存储在单个目标 Kafka 主题中。它直接从表中捕获的快照记录作为READ操作发出。同时,随着用户继续更新数据收集中的记录,事务日志也会更新以反映每次提交,Debezium 会针对每次更改发出UPDATE或DELETE操作。
当快照窗口打开并且 Debezium 开始处理快照块时,它会将快照记录传送到内存缓冲区。在快照窗口期间,READ将缓冲区中事件的主键与传入流式事件的主键进行比较。如果没有找到匹配项,流式事件记录将直接发送到 Kafka。如果 Debezium 检测到匹配项,它会丢弃缓冲READ事件,并将流式记录写入目标主题,因为流式事件在逻辑上会取代静态快照事件。块的快照窗口关闭后,缓冲区仅包含READ不存在相关事务日志事件的事件。Debezium 将这些剩余READ事件发送到表的 Kafka 主题。
连接器为每个快照块重复该过程。
警告:
用于 Oracle 的 Debezium 连接器不支持在运行增量快照时更改架构。
目前,启动增量快照的唯一方法是向源数据库上的信号表发送临时快照信号。
您将信号作为 SQLINSERT查询提交到信号表。
Debezium 检测到信号表中的更改后,它会读取信号,并运行请求的快照操作。
您提交的查询指定要包含在快照中的表,并且可以选择指定快照操作的类型。目前,快照操作的唯一有效选项是默认值incremental.
要指定要包含在快照中的表,请提供一个data-collections列出表的数组或用于匹配表的正则表达式数组,例如,
{“data-collections”: [“public.MyFirstTable”, “public.MySecondTable”]}
增量快照信号的数组data-collections没有默认值。如果data-collections数组为空,Debezium 检测到不需要任何操作并且不执行快照。
如果要包含在快照中的表的名称在数据库、模式或表的名称中包含点,要将表添加到数组中data-collections,必须将名称的每个部分用双引号转义. 例如,使用以下格式:publicMy.Table"public".“My.Table”
先决条件
程序
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 参数的值对应于信令表的字段。
如果您希望快照仅包含表中内容的子集,您可以通过将参数附加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包含以下列的表:
如果希望表的增量快照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
}
您还可以通过向源数据库上的表发送信号来停止增量快照。您通过发送 SQL 查询向表提交停止快照信号INSERT。
Debezium 检测到信号表中的更改后,它会读取信号,如果正在进行增量快照操作,则会停止。
您提交的查询指定 的快照操作incremental,以及(可选)要删除的当前运行快照的表。
先决条件
程序
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参数的值对应于信令表的字段。
向信令表发送停止增量快照信号的SQL命令字段说明:
默认情况下,Oracle 连接器将表中发生的所有INSERT、UPDATE和DELETE操作的更改事件写入特定于该表的单个 Apache Kafka 主题。连接器使用以下约定来命名更改事件主题:topicPrefix.schemaName.tableName
以下列表提供了默认名称组件的定义:
如果默认主题名称不符合您的要求,您可以配置自定义主题名称。要配置自定义主题名称,您可以在逻辑主题路由 SMT 中指定正则表达式。
您可以配置 Debezium Oracle 连接器以生成模式更改事件,这些事件描述应用于数据库中捕获的表的结构更改。连接器将架构更改事件写入名为 的 Kafka 主题,其中topicName是在配置属性中指定的命名空间topic.prefix。
每当从新表流式传输数据时,Debezium 都会向该主题发出一条新消息。
连接器发送到架构更改主题的消息包含有效负载,并且(可选)还包含更改事件消息的架构。架构更改事件消息的有效负载包括以下元素:
重要的:
切勿对数据库模式历史主题进行分区。为了使数据库模式历史主题正常运行,它必须维护连接器向其发出的事件记录的一致的全局顺序。
为确保主题不在分区之间拆分,请使用以下方法之一设置主题的分区计数:
每当 Debezium 从新表中流式传输数据或更改表的结构时,都会向该主题发出一条新消息。
示例:发送到 Oracle 连接器架构更改主题的消息
以下示例显示了 JSON 格式的典型架构更改消息。该消息包含表模式的逻辑表示。
{
"schema": {
...
},
"payload": {
"source": {
"version": "2.2.1.Final",
"connector": "oracle",
"name": "server1",
"ts_ms": 1588252618953,
"snapshot": "true",
"db": "ORCLPDB1",
"schema": "DEBEZIUM",
"table": "CUSTOMERS",
"txId" : null,
"scn" : "1513734",
"commit_scn": "1513754",
"lcr_position" : null,
"rs_id": "001234.00012345.0124",
"ssn": 1,
"redo_thread": 1,
"user_name": "user"
},
"ts_ms": 1588252618953,
"databaseName": "ORCLPDB1",
"schemaName": "DEBEZIUM", //
"ddl": "CREATE TABLE \"DEBEZIUM\".\"CUSTOMERS\" \n ( \"ID\" NUMBER(9,0) NOT NULL ENABLE, \n \"FIRST_NAME\" VARCHAR2(255), \n \"LAST_NAME" VARCHAR2(255), \n \"EMAIL\" VARCHAR2(255), \n PRIMARY KEY (\"ID\") ENABLE, \n SUPPLEMENTAL LOG DATA (ALL) COLUMNS\n ) SEGMENT CREATION IMMEDIATE \n PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 \n NOCOMPRESS LOGGING\n STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645\n PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1\n BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)\n TABLESPACE \"USERS\" ",
"tableChanges": [
{
"type": "CREATE",
"id": "\"ORCLPDB1\".\"DEBEZIUM\".\"CUSTOMERS\"",
"table": {
"defaultCharsetName": null,
"primaryKeyColumnNames": [
"ID"
],
"columns": [
{
"name": "ID",
"jdbcType": 2,
"nativeType": null,
"typeName": "NUMBER",
"typeExpression": "NUMBER",
"charsetName": null,
"length": 9,
"scale": 0,
"position": 1,
"optional": false,
"autoIncremented": false,
"generated": false
},
{
"name": "FIRST_NAME",
"jdbcType": 12,
"nativeType": null,
"typeName": "VARCHAR2",
"typeExpression": "VARCHAR2",
"charsetName": null,
"length": 255,
"scale": null,
"position": 2,
"optional": false,
"autoIncremented": false,
"generated": false
},
{
"name": "LAST_NAME",
"jdbcType": 12,
"nativeType": null,
"typeName": "VARCHAR2",
"typeExpression": "VARCHAR2",
"charsetName": null,
"length": 255,
"scale": null,
"position": 3,
"optional": false,
"autoIncremented": false,
"generated": false
},
{
"name": "EMAIL",
"jdbcType": 12,
"nativeType": null,
"typeName": "VARCHAR2",
"typeExpression": "VARCHAR2",
"charsetName": null,
"length": 255,
"scale": null,
"position": 4,
"optional": false,
"autoIncremented": false,
"generated": false
}
],
"attributes": [
{
"customAttribute": "attributeValue"
}
]
}
}
]
}
}
发送到模式更改主题的消息中的字段描述:
在连接器发送到架构更改主题的消息中,消息键是包含架构更改的数据库的名称。在以下示例中,该payload字段包含databaseName键:
{
"schema": {
"type": "struct",
"fields": [
{
"type": "string",
"optional": false,
"field": "databaseName"
}
],
"optional": false,
"name": "io.debezium.connector.oracle.SchemaChangeKey"
},
"payload": {
"databaseName": "ORCLPDB1"
}
}
Debezium 可以生成代表事务元数据边界并丰富数据更改事件消息的事件。
BEGIN数据库事务由包含在和关键字之间的语句块表示END。BEGINDebezium 为每笔交易中的和分隔符生成交易边界事件END。事务边界事件包含以下字段:
以下示例显示了典型的事务边界消息:
示例:Oracle 连接器事务边界事件
{
"status": "BEGIN",
"id": "5.6.641",
"ts_ms": 1486500577125,
"event_count": null,
"data_collections": null
}
{
"status": "END",
"id": "5.6.641",
"ts_ms": 1486500577691,
"event_count": 2,
"data_collections": [
{
"data_collection": "ORCLPDB1.DEBEZIUM.CUSTOMER",
"event_count": 1
},
{
"data_collection": "ORCLPDB1.DEBEZIUM.ORDER",
"event_count": 1
}
]
}
除非通过选项覆盖topic.transaction,否则连接器会向主题发出事务事件。
更改数据事件扩充
启用事务元数据后,数据消息Envelope会增加一个新transaction字段。该字段以字段组合的形式提供有关每个事件的信息:
id:唯一交易标识符的字符串表示。
total_order:该事件在交易产生的所有事件中的绝对位置。
data_collection_order:事件在事务发出的所有事件中的每个数据收集位置。
以下示例显示了典型的事务事件消息:
{
"before": null,
"after": {
"pk": "2",
"aa": "1"
},
"source": {
...
},
"op": "c",
"ts_ms": "1580390884335",
"transaction": {
"id": "5.6.641",
"total_order": "1",
"data_collection_order": "1"
}
}
Oracle 按照它们发生的顺序将所有更改写入重做日志,包括后来被回滚丢弃的更改。因此,来自不同事务的并发更改交织在一起。当连接器第一次读取更改流时,由于它无法立即确定哪些更改已提交或回滚,因此它会将更改事件临时存储在内部缓冲区中。提交更改后,连接器将更改事件从缓冲区写入 Kafka。连接器会丢弃被回滚丢弃的更改事件。
您可以通过设置属性来配置连接器使用的缓冲机制log.mining.buffer.type。
堆
默认缓冲区类型使用memory. 在默认memory设置下,连接器使用 JVM 进程的堆内存来分配和管理缓冲的事件记录。如果使用memory缓冲区设置,请确保分配给 Java 进程的内存量可以容纳环境中长时间运行的大型事务。
无穷大
Debezium Oracle 连接器还可以配置为使用 Infinispan 作为其缓存提供程序,以嵌入式模式在本地或远程服务器集群上支持缓存存储。为了使用 Infinispan,log.mining.buffer.type必须使用 或 进行infinispan_embedded配置infinispan_remote。
为了允许 Infinispan 缓存配置的灵活性,连接器期望在使用 Infinispan 缓冲事件数据时提供一系列缓存配置属性。查看命名空间中的配置属性log.mining.buffer.infinispan.cache。这些配置属性的内容取决于连接器是与远程 Infinispan 集群集成还是使用嵌入式引擎。
例如,下图说明了在嵌入式模式下使用 Infinispan 时,事务缓存属性的嵌入式配置是什么样的:
<local-cache name="transactions">
<persistence passivation="false">
<file-store read-only="false" preload="true" shared="false">
<data path="./data"/>
<index path="./index"/>
file-store>
persistence>
local-cache>
深入查看配置,缓存配置为持久化。如果事务正在进行中,所有缓存都应以这种方式配置,以避免在连接器重新启动时丢失事务事件。此外,保存缓存的位置由属性定义path,这应该是一个共享位置,可访问所有可能的运行时环境。
另一个示例,下图说明了使用 Infinispan 集群配置的相同缓存:
<distributed-cache name="transactions" statistics="true">
<encoding media-type="application/x-protostream" />
<persistence passivation="false">
<file-store read-only="false" preload="true" shared="false">
<data path="./data"/>
<index path="./index"/>
file-store>
persistence>
distributed-cache>
就像前面示例中的嵌入式本地缓存配置一样,此配置也被定义为持久的。如果事务正在进行中,所有缓存都应以这种方式配置,以避免在连接器重新启动时丢失事务事件。
但是,与注意有一些区别。首先,缓存被定义为分布式缓存而不是本地缓存。其次,缓存被定义为使用application/x-protostream所有 Debezium 缓存都需要的编码。最后,path文件存储定义不需要任何属性,因为 Infinispan 集群会自动处理它。
重要的:
Infinispan 缓冲区类型被认为是孵化的;缓存格式可能会在版本之间发生变化,并且可能需要重新快照。迁移说明将指出是否需要这样做。
此外,在删除使用 Infinispan 缓冲区的 Debezium Oracle 连接器时,持久缓存文件不会自动从磁盘中删除。如果新连接器部署将使用相同的缓冲区位置,则应在部署新连接器之前手动删除这些文件。
Infinispan Hotrod 客户端集成
Debezium Oracle 连接器利用 Hotrod 客户端与 Infinispan 集群进行通信。任何带有前缀的连接器属性log.mining.buffer.infinispan.client.都将使用命名空间直接传递给 Hotrod 客户端infinispan.client.,从而允许完全自定义客户端与集群交互的方式。
使用此 Infinspan 模式时,至少必须提供一个必需的配置属性:
log.mining.buffer.infinispan.client.hotrod.server_list
使用格式指定 Infinispan 服务器主机名和端口组合的列表:。
当 Debezium Oracle 连接器配置为使用 LogMiner 时,它会使用基于系统更改编号 (SCN) 的开始和结束范围从 Oracle 收集更改事件。连接器会自动管理此范围,增加或减少范围取决于连接器是否能够近乎实时地流式传输更改,或者是否必须处理由于数据库中的大量事务或批量事务而积压的更改。
在某些情况下,Oracle 数据库将 SCN 提高异常高的数量,而不是以恒定速率增加 SCN 值。由于特定集成与数据库交互的方式,或者作为热备份等事件的结果,可能会发生 SCN 值的这种跳跃。
Debezium Oracle 连接器依赖于以下配置属性来检测 SCN 差距并调整挖掘范围。
log.mining.scn.gap.detection.gap.size.min
指定最小间隙大小。
log.mining.scn.gap.detection.time.interval.max.ms
指定最大时间间隔。
连接器首先比较当前SCN和当前挖矿范围内最高SCN的变化次数的差异。如果当前 SCN 值与最高 SCN 值之间的差异大于最小间隙大小,则连接器可能检测到 SCN 间隙。为了确认是否存在间隙,连接器接下来将当前 SCN 的时间戳与先前挖掘范围末尾的 SCN 的时间戳进行比较。如果时间戳之间的差异小于最大时间间隔,则确认存在 SCN 间隙。
当出现 SCN 间隙时,Debezium 连接器会自动使用当前 SCN 作为当前挖矿会话范围的终点。这允许连接器快速赶上实时事件,而无需在两者之间挖掘更小的范围,因为 SCN 值增加了一个意想不到的大数字,所以不会返回任何更改。当连接器执行上述步骤以响应 SCN 间隙时,它会忽略log.mining.batch.size.max属性指定的值。在连接器完成挖掘会话并恢复实时事件后,它会恢复执行最大日志挖掘批处理大小。
警告:
只有在连接器运行和处理近乎实时的事件时出现大的 SCN 增量时,SCN 间隙检测才可用。
Debezium Oracle 连接器跟踪连接器偏移中的系统更改编号,以便在重新启动连接器时,它可以从停止的地方开始。这些偏移量是每个发出的更改事件的一部分;但是,当数据库更改频率较低(每隔几小时或几天)时,如果系统更改编号在事务日志中不再可用,则偏移量可能会变得陈旧并阻止连接器成功重启。
对于使用非 CDB 模式连接到 Oracle 的连接器,您可以启用heartbeat.interval.ms以强制连接器定期发出心跳事件,以便偏移量保持同步。
对于使用 CDB 模式连接 Oracle 的连接器,保持同步比较复杂。不仅要设置heartbeat.interval.ms,还要设置heartbeat.action.query。需要指定这两个属性,因为在 CDB 模式下,连接器仅专门跟踪 PDB 内部的更改。需要一种补充机制来从可插入数据库中触发更改事件。每隔一段时间,心跳操作查询会导致连接器插入一个新的表行,或更新可插入数据库中的现有行。Debezium 检测表更改并为它们发出更改事件,确保偏移量保持同步,即使在不经常处理更改的可插拔数据库中也是如此。
笔记:
要让连接器使用heartbeat.action.query不属于连接器用户帐户的表,您必须授予连接器用户权限以在这些表上运行必要的INSERT或UPDATE查询。
Oracle 连接器发出的每个数据更改事件都有一个键和一个值。键和值的结构取决于更改事件源自的表。
警告:
Debezium Oracle 连接器确保所有 Kafka Connect模式名称都是有效的 Avro 模式名称。这意味着逻辑服务器名称必须以字母字符或下划线 ([az,AZ,_]) 开头,逻辑服务器名称中的其余字符以及架构和表名称中的所有字符都必须是字母数字字符或下划线([az,AZ,0-9,_])。连接器会自动将无效字符替换为下划线字符。
当多个逻辑服务器名称、模式名称或表名称之间的唯一区分字符不是有效字符并且这些字符被下划线替换时,可能会导致意外的命名冲突。
Debezium 和 Kafka Connect 是围绕连续的事件消息流设计的。但是,这些事件的结构可能会随着时间的推移而发生变化,这对于主题消费者来说可能很难处理。为了便于处理可变事件结构,Kafka Connect 中的每个事件都是独立的。每个消息键和值都有两部分:模式和有效负载。模式描述有效载荷的结构,而有效载荷包含实际数据。
对于每个更改的表,更改事件键的结构使得在创建事件时表的主键(或唯一键约束)中的每一列都存在一个字段。
例如,customers可能具有以下更改事件键:
CREATE TABLE customers (
id NUMBER(9) GENERATED BY DEFAULT ON NULL AS IDENTITY (START WITH 1001) NOT NULL PRIMARY KEY,
first_name VARCHAR2(255) NOT NULL,
last_name VARCHAR2(255) NOT NULL,
email VARCHAR2(255) NOT NULL UNIQUE
);
如果配置属性
{
"schema": {
"type": "struct",
"fields": [
{
"type": "int32",
"optional": false,
"field": "ID"
}
],
"optional": false,
"name": "server1.INVENTORY.CUSTOMERS.Key"
},
"payload": {
"ID": 1004
}
}
更改事件消息中值的结构反映了消息中更改事件中消息键的结构,并且包含模式部分和有效负载部分。
更改事件值的负载
更改事件值的有效负载部分中的信封结构包含以下字段:
op
包含描述操作类型的字符串值的必填字段。Oracle 连接器更改事件值的负载中的字段op包含以下值之一:(c创建或插入)、u(更新)、d(删除)或r(读取,表示快照)。
before
可选字段,如果存在,则描述事件发生前行的状态。该结构由 Kafka Connect 架构描述server1.INVENTORY.CUSTOMERS.Value,server1连接器将其用于表中的所有行inventory.customers。
after
一个可选字段,如果存在,则包含发生更改后行的状态。server1.INVENTORY.CUSTOMERS.Value该结构由用于该字段的相同 Kafka Connect 模式描述before。
source
包含描述事件源元数据结构的必填字段。对于 Oracle 连接器,该结构包括以下字段:
提示:
该commit_scn字段是可选的,它描述了更改事件参与其中的事务提交的 SCN。该字段仅在使用 LogMiner 连接适配器时出现。
该user_name字段仅在使用 LogMiner 连接适配器时填充。
ts_ms
一个可选字段,如果存在,则包含连接器处理事件的时间(基于运行 Kafka Connect 任务的 JVM 中的系统时钟)。
更改事件值的架构
事件消息值的架构部分包含一个架构,该架构描述有效负载的信封结构和其中的嵌套字段。
以下示例显示了更改事件键示例中描述的表中创建事件值的值:customers
展示完整的JSON结构
{
"schema":{
"type":"struct",
"fields":Array[5],
"optional":false,
"name":"server1.DEBEZIUM.CUSTOMERS.Envelope"
},
"payload":{
"before":null,
"after":Object{...},
"source":Object{...},
"op":"c",
"ts_ms":1532592105975
}
}
{
"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": "server1.DEBEZIUM.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": "server1.DEBEZIUM.CUSTOMERS.Value",
"field": "after"
},
{
"type": "struct",
"fields": [
{
"type": "string",
"optional": true,
"field": "version"
},
{
"type": "string",
"optional": false,
"field": "name"
},
{
"type": "int64",
"optional": true,
"field": "ts_ms"
},
{
"type": "string",
"optional": true,
"field": "txId"
},
{
"type": "string",
"optional": true,
"field": "scn"
},
{
"type": "string",
"optional": true,
"field": "commit_scn"
},
{
"type": "string",
"optional": true,
"field": "rs_id"
},
{
"type": "int64",
"optional": true,
"field": "ssn"
},
{
"type": "int32",
"optional": true,
"field": "redo_thread"
},
{
"type": "string",
"optional": true,
"field": "user_name"
},
{
"type": "boolean",
"optional": true,
"field": "snapshot"
}
],
"optional": false,
"name": "io.debezium.connector.oracle.Source",
"field": "source"
},
{
"type": "string",
"optional": false,
"field": "op"
},
{
"type": "int64",
"optional": true,
"field": "ts_ms"
}
],
"optional": false,
"name": "server1.DEBEZIUM.CUSTOMERS.Envelope"
},
"payload": {
"before": null,
"after": {
"ID": 1004,
"FIRST_NAME": "Anne",
"LAST_NAME": "Kretchmar",
"EMAIL": "[email protected]"
},
"source": {
"version": "2.2.1.Final",
"name": "server1",
"ts_ms": 1520085154000,
"txId": "6.28.807",
"scn": "2122185",
"commit_scn": "2122185",
"rs_id": "001234.00012345.0124",
"ssn": 1,
"redo_thread": 1,
"user_name": "user",
"snapshot": false
},
"op": "c",
"ts_ms": 1532592105975
}
}
"schema":{
"type":"struct",
"fields":[
{
"type":"struct",
"fields":Array[4],
"optional":true,
"name":"server1.DEBEZIUM.CUSTOMERS.Value",
"field":"before"
},
{
"type":"struct",
"fields":Array[4],
"optional":true,
"name":"server1.DEBEZIUM.CUSTOMERS.Value",
"field":"after"
},
{
"type":"struct",
"fields":Array[11],
"optional":false,
"name":"io.debezium.connector.oracle.Source",
"field":"source"
},
{
"type":"string",
"optional":false,
"field":"op"
},
{
"type":"int64",
"optional":true,
"field":"ts_ms"
}
],
"optional":false,
"name":"server1.DEBEZIUM.CUSTOMERS.Envelope"
}
"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":"server1.DEBEZIUM.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":"server1.DEBEZIUM.CUSTOMERS.Value",
"field":"after"
},
{
"type":"struct",
"fields":[
{
"type":"string",
"optional":true,
"field":"version"
},
{
"type":"string",
"optional":false,
"field":"name"
},
{
"type":"int64",
"optional":true,
"field":"ts_ms"
},
{
"type":"string",
"optional":true,
"field":"txId"
},
{
"type":"string",
"optional":true,
"field":"scn"
},
{
"type":"string",
"optional":true,
"field":"commit_scn"
},
{
"type":"string",
"optional":true,
"field":"rs_id"
},
{
"type":"int64",
"optional":true,
"field":"ssn"
},
{
"type":"int32",
"optional":true,
"field":"redo_thread"
},
{
"type":"string",
"optional":true,
"field":"user_name"
},
{
"type":"boolean",
"optional":true,
"field":"snapshot"
}
],
"optional":false,
"name":"io.debezium.connector.oracle.Source",
"field":"source"
},
{
"type":"string",
"optional":false,
"field":"op"
},
{
"type":"int64",
"optional":true,
"field":"ts_ms"
}
],
"optional":false,
"name":"server1.DEBEZIUM.CUSTOMERS.Envelope"
}
"payload":{
"before":null,
"after":{
"ID":1004,
"FIRST_NAME":"Anne",
"LAST_NAME":"Kretchmar",
"EMAIL":"[email protected]"
},
"source":{
"version":"2.2.1.Final",
"name":"server1",
"ts_ms":1520085154000,
"txId":"6.28.807",
"scn":"2122185",
"commit_scn":"2122185",
"rs_id":"001234.00012345.0124",
"ssn":1,
"redo_thread":1,
"user_name":"user",
"snapshot":false
},
"op":"c",
"ts_ms":1532592105975
}
以下示例显示连接器从与前面的创建事件相同的表中捕获的更新更改事件。
{
"schema": { ... },
"payload": {
"before": {
"ID": 1004,
"FIRST_NAME": "Anne",
"LAST_NAME": "Kretchmar",
"EMAIL": "[email protected]"
},
"after": {
"ID": 1004,
"FIRST_NAME": "Anne",
"LAST_NAME": "Kretchmar",
"EMAIL": "[email protected]"
},
"source": {
"version": "2.2.1.Final",
"name": "server1",
"ts_ms": 1520085811000,
"txId": "6.9.809",
"scn": "2125544",
"commit_scn": "2125544",
"rs_id": "001234.00012345.0124",
"ssn": 1,
"redo_thread": 1,
"user_name": "user",
"snapshot": false
},
"op": "u",
"ts_ms": 1532592713485
}
}
有效负载与创建(插入)事件的有效负载具有相同的结构,但以下值不同:
注意:
更新行的主键/唯一键的列时,行键的值会更改。因此,Debezium在此类更新后发出三个事件:
以下示例显示了前面创建和更新事件示例中显示的表的删除事件。删除事件的部分与那些事件的部分相同。
{
"schema": { ... },
"payload": {
"before": {
"ID": 1004,
"FIRST_NAME": "Anne",
"LAST_NAME": "Kretchmar",
"EMAIL": "[email protected]"
},
"after": null,
"source": {
"version": "2.2.1.Final",
"name": "server1",
"ts_ms": 1520085153000,
"txId": "6.28.807",
"scn": "2122184",
"commit_scn": "2122184",
"rs_id": "001234.00012345.0124",
"ssn": 1,
"redo_thread": 1,
"user_name": "user",
"snapshot": false
},
"op": "d",
"ts_ms": 1532592105960
}
}
与create或updatepayload事件的负载相比,事件的这一部分揭示了几个差异:
截断 更改事件表示表已被截断。消息键null在这种情况下,消息值如下所示:
{
"schema": { ... },
"payload": {
"before": null,
"after": null,
"source": {
"version": "2.2.1.Final",
"connector": "oracle",
"name": "oracle_server",
"ts_ms": 1638974535000,
"snapshot": "false",
"db": "ORCLPDB1",
"sequence": null,
"schema": "DEBEZIUM",
"table": "TEST_TABLE",
"txId": "02000a0037030000",
"scn": "13234397",
"commit_scn": "13271102",
"lcr_position": null,
"rs_id": "001234.00012345.0124",
"ssn": 1,
"redo_thread": 1,
"user_name": "user"
},
"op": "t",
"ts_ms": 1638974558961,
"transaction": null
}
}
source:
描述事件源元数据的必填字段。在截断事件值中,字段结构与同一表的创建、更新和删除source事件相同,提供以下元数据:
op:描述操作类型的强制字符串。字段op值为t,表示此表已被截断。
ts_ms:
显示连接器处理事件的时间的可选字段。该时间基于运行 Kafka Connect 任务的 JVM 中的系统时钟。
在source对象中,ts_ms指示在数据库中进行更改的时间。通过将 的值payload.source.ts_ms与 的值进行比较payload.ts_ms,您可以确定源数据库更新和 Debezium 之间的滞后。
因为truncate事件表示对整个表所做的更改,并且没有消息键,所以在具有多个分区的主题中,无法保证消费者按顺序接收到表的truncate事件和更改事件(创建、更新等)。例如,当消费者从不同的分区读取事件时,它可能会在收到同一张表的截断事件后收到该表的更新事件。仅当主题使用单个分区时才能保证排序。
如果您不想捕获截断事件,请使用该skipped.operations选项将其过滤掉。
当 Debezium Oracle 连接器检测到表行的值发生变化时,它会发出一个表示变化的变化事件。每个更改事件记录的结构与原始表相同,事件记录包含每个列值的字段。表列的数据类型决定了连接器如何在更改事件字段中表示列的值,如以下部分的表中所示。
对于表中的每一列,Debezium 将源数据类型映射到相应事件字段中的文字类型,在某些情况下,映射到语义类型。
使用以下Kafka Connect模式类型之一描述值的字面表示方式:
INT8, INT16, INT32, INT64, FLOAT32, FLOAT64, BOOLEAN, STRING, BYTES, ARRAY, MAP, and STRUCT.
语义类型
通过使用字段的Kafka Connect 架构名称,描述 Kafka Connect 架构如何捕获字段的含义
对于某些 Oracle 大对象(CLOB、NCLOB 和 BLOB)和数字数据类型,您可以通过更改默认配置属性设置来操纵连接器执行类型映射的方式。
下表描述了连接器如何映射基本字符类型。
Oracle 基本字符类型的映射
CHAR[(M)]、NCHAR[(M)]、NVARCHAR2[(M)]、VARCHAR[(M)]、VARCHAR2[(M)] —— STRING
Oracle 二进制和字符 LOB 类型的映射
BLOB —— BYTES
CLOB —— STRING
NCLOB —— STRING
BINARY_FLOAT:FLOAT32
BINARY_DOUBLE:FLOAT64
DECIMAL[(P, S)]:BYTES / INT8 / INT16 / INT32 / INT64
org.apache.kafka.connect.data.Decimal如果使用BYTES
Handled 等效于NUMBER(请注意 S 默认为 0 DECIMAL)。
当该decimal.handling.mode属性设置为时double,连接器将DECIMAL值表示为double模式类型为 的 Java 值FLOAT64。
当该decimal.handling.mode属性设置为时string,连接器将 DECIMAL 值表示为其具有架构类型的格式化字符串表示形式STRING。
DOUBLE PRECISION:STRUCT
FLOAT[§]:STRUCT
INTEGER,INT:BYTES org.apache.kafka.connect.data.Decimal
INTEGER在 Oracle 中映射到 NUMBER(38,0),因此可以保存比任何类型INT可以存储的值都大的值
NUMBER[(P[, *])]:STRUCT
NUMBER(P, S <= 0):INT8// INT16/ INT32_INT64
NUMBER标度为 0 的列表示整数。负数表示在 Oracle 中四舍五入,例如,-2 表示四舍五入为百。
根据精度和比例,选择以下匹配的 Kafka Connect 整数类型之一:
如上所述,Oracle 允许在NUMBER类型中使用负标度。当数字表示为Decimal. Decimal类型包括比例信息,但Avro 规范只允许比例为正值。根据使用的模式注册表,它可能会导致 Avro 序列化失败。为避免此问题,您可以使用NumberToZeroScaleConverter,它将具有负标度的足够高的数字 (P - S >= 19) 转换为Decimal具有零标度的类型。它可以配置如下:
converters=zero_scale
zero_scale.type=io.debezium.connector.oracle.converters.NumberToZeroScaleConverter
zero_scale.decimal.mode=precise
默认情况下,数字会转换为Decimal类型 ( zero_scale.decimal.mode=precise),但为了完整起见,还支持其余两种受支持的类型 (double和)string。
Oracle 不提供对BOOLEAN数据类型的本机支持。然而,通常的做法是使用具有特定语义的其他数据类型来模拟逻辑数据类型的概念BOOLEAN。
为了使您能够将源列转换为布尔数据类型,Debezium 提供了一个NumberOneToBooleanConverter 自定义转换器,您可以通过以下方式之一使用它:
converters=boolean
boolean.type=io.debezium.connector.oracle.converters.NumberOneToBooleanConverter
boolean.selector=.*MYTABLE.FLAG,.*.IS_ARCHIVED
除了 Oracle INTERVAL、TIMESTAMP WITH TIME ZONE和TIMESTAMP WITH LOCAL TIME ZONE数据类型之外,连接器转换时态类型的方式取决于time.precision.mode配置属性的值。
当time.precision.mode配置属性设置为adaptive(默认值)时,连接器会根据列的数据类型定义确定时间类型的文字和语义类型,以便事件准确表示数据库中的值:
DATE:INT64 io.debezium.time.Timestamp表示自 UNIX 纪元以来的毫秒数,不包括时区信息。
INTERVAL DAY[(M)] TO SECOND:FLOAT64 io.debezium.time.MicroDuration
一个时间间隔的微秒数,使用365.25 / 12.0每月平均天数的公式。
io.debezium.time.Interval(当interval.handling.mode设置为时string)
模式 之后的区间值的字符串表示形式PYMDTHMS,例如 P1Y2M3DT4H5M6.78S。
当time.precision.mode配置属性设置为时connect,连接器将使用预定义的 Kafka Connect 逻辑类型。当消费者只知道内置的 Kafka Connect 逻辑类型而无法处理可变精度时间值时,这可能很有用。因为 Oracle 支持的精度级别超过了 Kafka Connect 中的逻辑类型支持的级别,如果设置为time.precision.mode,connect当数据库列的小数秒精度值大于 3 时,会导致精度损失。
根据数据库配置,重做日志的大小和数量可能不足以达到可接受的性能。在设置 Debezium Oracle 连接器之前,请确保重做日志的容量足以支持数据库。
数据库重做日志的容量必须足以存储其数据字典。通常,数据字典的大小随着数据库中表和列的数量而增加。如果重做日志容量不足,数据库和 Debezium 连接器都可能遇到性能问题。
深入理解Oracle数据库重做日志可以参考博主下面这篇博客:
要让 Debezium Oracle 连接器捕获更改事件,它必须以具有特定权限的 Oracle LogMiner 用户身份运行。以下示例显示了用于在多租户数据库模型中为连接器创建 Oracle 用户帐户的 SQL。
创建连接器的 LogMiner 用户
sqlplus sys/top_secret@//localhost:1521/ORCLCDB as sysdba
CREATE TABLESPACE logminer_tbs DATAFILE '/opt/oracle/oradata/ORCLCDB/logminer_tbs.dbf'
SIZE 25M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED;
exit;
sqlplus sys/top_secret@//localhost:1521/ORCLPDB1 as sysdba
CREATE TABLESPACE logminer_tbs DATAFILE '/opt/oracle/oradata/ORCLCDB/ORCLPDB1/logminer_tbs.dbf'
SIZE 25M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED;
exit;
sqlplus sys/top_secret@//localhost:1521/ORCLCDB as sysdba
CREATE USER c##dbzuser IDENTIFIED BY dbz
DEFAULT TABLESPACE logminer_tbs
QUOTA UNLIMITED ON logminer_tbs
CONTAINER=ALL;
GRANT CREATE SESSION TO c##dbzuser CONTAINER=ALL; 1
GRANT SET CONTAINER TO c##dbzuser CONTAINER=ALL;
GRANT SELECT ON V_$DATABASE to c##dbzuser CONTAINER=ALL;
GRANT FLASHBACK ANY TABLE TO c##dbzuser CONTAINER=ALL;
GRANT SELECT ANY TABLE TO c##dbzuser CONTAINER=ALL;
GRANT SELECT_CATALOG_ROLE TO c##dbzuser CONTAINER=ALL;
GRANT EXECUTE_CATALOG_ROLE TO c##dbzuser CONTAINER=ALL;
GRANT SELECT ANY TRANSACTION TO c##dbzuser CONTAINER=ALL;
GRANT LOGMINING TO c##dbzuser CONTAINER=ALL;
GRANT CREATE TABLE TO c##dbzuser CONTAINER=ALL;
GRANT LOCK ANY TABLE TO c##dbzuser CONTAINER=ALL;
GRANT CREATE SEQUENCE TO c##dbzuser CONTAINER=ALL;
GRANT EXECUTE ON DBMS_LOGMNR TO c##dbzuser CONTAINER=ALL;
GRANT EXECUTE ON DBMS_LOGMNR_D TO c##dbzuser CONTAINER=ALL;
GRANT SELECT ON V_$LOG TO c##dbzuser CONTAINER=ALL;
GRANT SELECT ON V_$LOG_HISTORY TO c##dbzuser CONTAINER=ALL;
GRANT SELECT ON V_$LOGMNR_LOGS TO c##dbzuser CONTAINER=ALL;
GRANT SELECT ON V_$LOGMNR_CONTENTS TO c##dbzuser CONTAINER=ALL;
GRANT SELECT ON V_$LOGMNR_PARAMETERS TO c##dbzuser CONTAINER=ALL;
GRANT SELECT ON V_$LOGFILE TO c##dbzuser CONTAINER=ALL;
GRANT SELECT ON V_$ARCHIVED_LOG TO c##dbzuser CONTAINER=ALL;
GRANT SELECT ON V_$ARCHIVE_DEST_STATUS TO c##dbzuser CONTAINER=ALL;
GRANT SELECT ON V_$TRANSACTION TO c##dbzuser CONTAINER=ALL;
GRANT SELECT ON V_$MYSTAT TO c##dbzuser CONTAINER=ALL;
GRANT SELECT ON V_$STATNAME TO c##dbzuser CONTAINER=ALL;
exit;
创建会话:使连接器能够连接到 Oracle。
设置容器:使连接器能够在可插入数据库之间切换。这仅在 Oracle 安装启用了容器数据库支持 (CDB) 时才需要。
在 V_ D A T A B A S E 上选择:使连接器能够读取表 V DATABASE 上选择:使连接器能够读取表V DATABASE上选择:使连接器能够读取表VDATABASE。
闪回任何表格:使连接器能够执行闪回查询,这是连接器执行数据初始快照的方式。
选择任何表格:使连接器能够读取任何表。
选择目录角色:使连接器能够读取 Oracle LogMiner 会话所需的数据字典。
执行目录角色:使连接器能够将数据字典写入 Oracle 重做日志,这是跟踪架构更改所必需的。
选择任何交易:使快照进程能够针对任何事务执行闪回快照查询。什么时候FLASHBACK ANY TABLE授予,这个也应该授予。
日志挖掘:此角色是在较新版本的 Oracle 中添加的,作为授予对 Oracle LogMiner 及其包的完全访问权限的一种方式。在没有此角色的旧版 Oracle 上,您可以忽略此授权。
创建表:使连接器能够在其默认表空间中创建其刷新表。刷新表允许连接器显式控制将 LGWR 内部缓冲区刷新到磁盘。
锁定任何表:使连接器能够在模式快照期间锁定表。如果通过配置显式禁用快照锁,则可以安全地忽略此授权。
创建序列:使连接器能够在其默认表空间中创建序列。
在 DBMS_LOGMNR 上执行:使连接器能够运行DBMS_LOGMNR包中的方法。这是与 Oracle LogMiner 交互所必需的。在较新版本的 Oracle 上,这是通过LOGMINING角色授予的,但在旧版本上,这必须明确授予。
在 DBMS_LOGMNR_D 上执行:使连接器能够运行DBMS_LOGMNR_D包中的方法。这是与 Oracle LogMiner 交互所必需的。在较新版本的 Oracle 上,这是通过LOGMINING角色授予的,但在旧版本上,这必须明确授予。
15 至 25 选择 V_$… 。:使连接器能够读取这些表。连接器必须能够读取有关 Oracle 重做和存档日志以及当前事务状态的信息,以准备 Oracle LogMiner 会话。没有这些授权,连接器就无法运行。
在 Oracle 生产故障的情况下,通常存在逻辑或物理备用数据库。当发生故障并将备用实例提升为生产实例时,必须打开数据库以进行读/写事务,然后 Debezium Oracle 连接器才能连接到数据库。
在物理备用的情况下,备用是生产的精确副本,这意味着 SCN 值是相同的。使用物理备用数据库时,重新配置 Debezium Oracle 连接器以在数据库打开后使用备用数据库的主机名就足够了。
在逻辑备用的情况下,备用不是生产数据库的精确副本,因此备用中的 SCN 偏移量与生产数据库中的不同。如果您使用逻辑备用,为了帮助确保 Debezium 不会错过任何更改事件,在数据库打开后,配置一个新的连接器并执行一个新的数据库快照。
通常,您通过提交指定连接器配置属性的 JSON 请求来注册 Debezium Oracle 连接器。以下示例显示了一个 JSON 请求,用于server1在端口 1521 上注册一个逻辑名称为 Debezium Oracle 连接器的实例:
您可以选择为数据库中的模式和表的子集生成事件。或者,您可以忽略、屏蔽或截断包含敏感数据、大于指定大小或您不需要的列。
{
"name": "inventory-connector",
"config": {
"connector.class" : "io.debezium.connector.oracle.OracleConnector",
"database.hostname" : "" ,
"database.port" : "1521",
"database.user" : "c##dbzuser",
"database.password" : "dbz",
"database.dbname" : "ORCLCDB",
"topic.prefix" : "server1",
"tasks.max" : "1",
"database.pdb.name" : "ORCLPDB1",
"schema.history.internal.kafka.bootstrap.servers" : "kafka:9092",
"schema.history.internal.kafka.topic": "schema-changes.inventory"
}
}
在前面的示例中,database.hostname和database.port属性用于定义与数据库主机的连接。但是,在更复杂的 Oracle 部署中,或在使用透明网络底层 (TNS) 名称的部署中,您可以使用指定 JDBC URL 的替代方法。
下面的 JSON 示例显示了与前面示例相同的配置,只是它使用 JDBC URL 连接到数据库。
示例:使用 JDBC URL 连接到数据库的 Debezium Oracle 连接器配置
{
"name": "inventory-connector",
"config": {
"connector.class" : "io.debezium.connector.oracle.OracleConnector",
"tasks.max" : "1",
"topic.prefix" : "server1",
"database.user" : "c##dbzuser",
"database.password" : "dbz",
"database.url": "jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(LOAD_BALANCE=OFF)(FAILOVER=ON)(ADDRESS=(PROTOCOL=TCP)(HOST=)(PORT=1521))(ADDRESS=(PROTOCOL=TCP)(HOST=)(PORT=1521)))(CONNECT_DATA=SERVICE_NAME=)(SERVER=DEDICATED)))" ,
"database.dbname" : "ORCLCDB",
"database.pdb.name" : "ORCLPDB1",
"schema.history.internal.kafka.bootstrap.servers" : "kafka:9092",
"schema.history.internal.kafka.topic": "schema-changes.inventory"
}
}
您可以使用命令将此配置发送POST到正在运行的 Kafka Connect 服务。该服务记录配置并启动执行以下操作的连接器任务:
要开始运行 Debezium Oracle 连接器,请创建连接器配置,并将配置添加到您的 Kafka Connect 集群。
先决条件
Oracle 数据库支持以下部署类型:
容器数据库 (CDB)
可以包含多个可插入数据库 (PDB) 的数据库。数据库客户端连接到每个 PDB,就像它是一个标准的非 CDB 数据库一样。
非容器数据库(non-CDB)
标准 Oracle 数据库,不支持创建可插入数据库。
CDB 部署的 Debezium 连接器配置
{
"config": {
"connector.class" : "io.debezium.connector.oracle.OracleConnector",
"tasks.max" : "1",
"topic.prefix" : "server1",
"database.hostname" : "" ,
"database.port" : "1521",
"database.user" : "c##dbzuser",
"database.password" : "dbz",
"database.dbname" : "ORCLCDB",
"database.pdb.name" : "ORCLPDB1",
"schema.history.internal.kafka.bootstrap.servers" : "kafka:9092",
"schema.history.internal.kafka.topic": "schema-changes.inventory"
}
}
当您配置 Debezium Oracle 连接器以与 Oracle CDB 一起使用时,您必须为属性指定一个值database.pdb.name,该值命名您希望连接器从中捕获更改的 PDB。对于非 CDB 安装,请勿指定该database.pdb.name属性。
示例:用于非 CDB 部署的 Debezium Oracle 连接器配置
{
"config": {
"connector.class" : "io.debezium.connector.oracle.OracleConnector",
"tasks.max" : "1",
"topic.prefix" : "server1",
"database.hostname" : "" ,
"database.port" : "1521",
"database.user" : "c##dbzuser",
"database.password" : "dbz",
"database.dbname" : "ORCLCDB",
"schema.history.internal.kafka.bootstrap.servers" : "kafka:9092",
"schema.history.internal.kafka.topic": "schema-changes.inventory"
}
}
Debezium Oracle 连接器具有许多配置属性,您可以使用这些属性为您的应用程序实现正确的连接器行为。许多属性都有默认值。有关属性的信息组织如下:
属性 | 默认参数 | 含义解释 |
---|---|---|
name | 连接器的唯一名称。尝试使用相同的名称再次注册将失败。(所有 Kafka Connect 连接器都需要此属性。) | |
connector.class | 连接器的 Java 类的名称。io.debezium.connector.oracle.OracleConnector对于 Oracle 连接器始终使用值。 | |
converters | 枚举连接器可以使用的自定义转换器实例的符号名称的逗号分隔列表。 | |
例如,boolean。 | ||
tasks.max | 1 | 为此连接器创建的最大任务数。Oracle 连接器始终使用单个任务,因此不使用此值,因此默认值始终可以接受。 |
database.hostname | ||
database.port | ||
database.user | ||
database.password | ||
database.dbname | 要连接的数据库的名称。使用 CDB + PDB 模型时必须是 CDB 名称。 | |
database.url | 指定原始数据库 JDBC URL。使用此属性可以灵活地定义该数据库连接。有效值包括原始 TNS 名称和 RAC 连接字符串。 | |
database.pdb.name | 要连接的 Oracle 可插拔数据库的名称。仅将此属性用于容器数据库 (CDB) 安装。 | |
topic.prefix | 为连接器从中捕获更改的 Oracle 数据库服务器提供命名空间的主题前缀。您设置的值用作连接器发出的所有 Kafka 主题名称的前缀。指定在 Debezium 环境中的所有连接器中唯一的主题前缀。以下字符有效:字母数字字符、连字符、点和下划线。 | |
database.connection.adapter | 连接器在流式传输数据库更改时使用的适配器实现。您可以设置以下值:( logminer默认):: 连接器使用本机 Oracle LogMiner API。 xstream:: 连接器使用 Oracle XStreams API。 | |
snapshot.mode | 指定连接器用于拍摄捕获表快照的模式。您可以设置以下值:always快照包括捕获表的结构和数据。指定此值以使用每个连接器启动时捕获的表中数据的完整表示来填充主题。initial快照包括捕获表的结构和数据。指定此值以使用捕获表中数据的完整表示来填充主题。如果快照成功完成,则在下一个连接器启动时不会再次执行快照。initial_only快照包括捕获表的结构和数据。连接器执行初始快照然后停止,不处理任何后续更改。schema_only快照仅包含捕获表的结构。如果您希望连接器仅捕获快照之后发生的更改的数据,请指定此值。schema_only_recovery这是已捕获更改的连接器的恢复设置。当您重新启动连接器时,此设置可以恢复损坏或丢失的数据库架构历史主题。您可以定期将其设置为“清理”意外增长的数据库模式历史主题。数据库架构历史主题需要无限保留。请注意,只有在保证自连接器之前关闭的时间点和拍摄快照的时间点以来没有发生模式更改时,才可以安全地使用此模式。快照完成后,连接器继续从数据库的重做日志中读取更改事件,除非snapshot.mode配置为initial_only. | |
snapshot.locking.mode | 控制连接器是否持有表锁以及持有表锁的时间。表锁可防止在连接器执行快照时发生某些类型的更改表操作。您可以设置以下值: | |
shared启用对表的并发访问,但阻止任何会话获取独占表锁。连接器ROW SHARE在捕获表模式时获取级别锁。none防止连接器在快照期间获取任何表锁。仅当在创建快照期间可能不会发生架构更改时才使用此设置。 | ||
snapshot.include.collection.list | 可选的、以逗号分隔的正则表达式列表,匹配要包含在快照中的表的完全限定名称 ( )。在使用 LogMiner 实现的环境中,您必须仅使用 POSIX 正则表达式。指定的项目必须在连接器的属性中命名。仅当连接器的属性设置为 以外的值时,此属性才会生效。 此属性不影响增量快照的行为。.table.include.listsnapshot.modenever | |
为了匹配表的名称,Debezium 应用您指定为锚定正则表达式的正则表达式。也就是说,指定的表达式与表的整个名称字符串匹配;它与表名中可能存在的子字符串不匹配。 | ||
schema.include.list | 一个可选的、以逗号分隔的正则表达式列表,这些正则表达式匹配您要为其捕获更改的模式的名称。在使用 LogMiner 实现的环境中,您必须仅使用 POSIX 正则表达式。任何未包含在中的模式名称都schema.include.list被排除在捕获其更改之外。默认情况下,所有非系统模式都会捕获它们的更改。为了匹配模式的名称,Debezium 应用您指定为锚定正则表达式的正则表达式。也就是说,指定的表达式与模式的整个名称字符串匹配;它不匹配模式名称中可能存在的子字符串。如果您在配置中包含此属性,则不要同时设置该schema.exclude.list属性。 | |
schema.exclude.list | 一个可选的、以逗号分隔的正则表达式列表,这些正则表达式匹配您不想为其捕获更改的模式的名称。在使用 LogMiner 实现的环境中,您必须仅使用 POSIX 正则表达式。任何名称未包含在其中的模式schema.exclude.list都会捕获其更改,系统模式除外。为了匹配模式的名称,Debezium 应用您指定为锚定正则表达式的正则表达式。也就是说,指定的表达式与模式的整个名称字符串匹配;它不匹配模式名称中可能存在的子字符串。如果在配置中包含此属性,请不要设置 schema.include.list 属性。 | |
table.include.list | 可选的以逗号分隔的正则表达式列表,匹配要捕获的表的完全限定表标识符。如果您使用 LogMiner 实现,请仅使用具有此属性的 POSIX 正则表达式。设置此属性后,连接器仅捕获指定表中的更改。每个表标识符使用以下格式: |
|
table.exclude.list | 可选的以逗号分隔的正则表达式列表,匹配要从监视中排除的表的完全限定表标识符。如果您使用 LogMiner 实现,请仅使用具有此属性的 POSIX 正则表达式。连接器捕获未在排除列表中指定的任何表的更改事件。使用以下格式指定每个表的标识符:..为了匹配表的名称,Debezium 应用您指定为锚定正则表达式的正则表达式。也就是说,指定的表达式与表的整个名称字符串匹配;它与表名中可能存在的子字符串不匹配。如果您在配置中包含此属性,则不要同时设置该table.include.list属性。 | |
column.include.list | 一个可选的、以逗号分隔的正则表达式列表,这些正则表达式与要包含在更改事件消息值中的列的完全限定名称相匹配。在使用 LogMiner 实现的环境中,您必须仅使用 POSIX 正则表达式。列的完全限定名称使用以下格式: |
|
skip.messages.without.change | 指定当包含的列没有变化时是否跳过发布消息。column.include.list如果按或属性包含的列没有变化,这实际上会过滤消息column.exclude.list。 | |
binary.handling.mode | bytes | 指定二进制 ( blob) 列在更改事件中的表示方式,包括:bytes将二进制数据表示为字节数组(默认),将base64二进制数据表示为 base64 编码的字符串,将base64-url-safe二进制数据表示为 base64-url-安全编码的字符串,hex表示二进制数据作为十六进制编码 (base16) 字符串 |
decimal.handling.mode | precise | NUMBER指定连接器应如何处理和列DECIMAL的浮点值NUMERIC。您可以设置以下选项之一:precise(默认)通过使用java.math.BigDecimal二进制形式的变化事件中表示的值来精确表示值。double用double值表示值。使用double值更容易,但会导致精度损失。string将值编码为格式化字符串。使用该string选项更容易使用,但会导致有关真实类型的语义信息丢失。有关详细信息,请参阅数值类型。 |
interval.handling.mode | numeric | 指定连接器应如何处理interval列的值:numeric使用近似微秒数表示间隔。string通过使用字符串模式表示准确地表示间隔PYMDTHMS。例如:P1Y2M3DT4H5M6.78S。 |
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(0.5 秒) | 正整数值,指定连接器在每次迭代期间应等待新更改事件出现的毫秒数。 |
tombstones.on.delete | true | 控制删除事件后是否跟有逻辑删除事件。以下值是可能的:true对于每个删除操作,连接器都会发出一个删除事件和一个后续的逻辑删除事件。false对于每个删除操作,连接器仅发出一个删除事件。删除源记录后,逻辑删除事件(默认行为)使 Kafka 能够完全删除在启用了日志压缩的主题中共享已删除行的键的所有事件。 |
message.key.columns | 一个表达式列表,指定连接器用于为它发布到指定表的 Kafka 主题的更改事件记录形成自定义消息键的列。默认情况下,Debezium 使用表的主键列作为它发出的记录的消息键。代替默认值,或为缺少主键的表指定键,您可以基于一个或多个列配置自定义消息键。要为表建立自定义消息键,请列出表,然后列出要用作消息键的列。每个列表条目都采用以下格式:: ,要使表键基于多个列名,请在列名之间插入逗号。每个完全限定的表名都是以下格式的正则表达式: 该属性可以包含多个表的条目。使用分号分隔列表中的表条目。 以下示例设置表的消息键.inventory.customers和purchase.orders:inventory.customers:pk1,pk2;(.*).purchaseorders:pk3,pk4对于表inventory.customer,列pk1和pk2被指定为消息键。对于purchaseorders任何模式中的表,列pk3和pk4服务器作为消息键。用于创建自定义消息键的列数没有限制。但是,最好使用指定唯一键所需的最小数量。 | |
heartbeat.interval.ms | 0 | |
heartbeat.action.query | ||
log.mining.strategy | redo_log_catalog | 缓冲区类型控制连接器如何管理缓冲事务数据。memory- 使用 JVM 进程的堆来缓冲所有事务数据。如果您不希望连接器处理大量长时间运行的事务或大型事务,请选择此选项。当此选项处于活动状态时,缓冲区状态不会在重新启动后保持不变。重启后,从当前偏移量的 SCN 值重新创建缓冲区。infinispan_embedded- 此选项使用嵌入式 Infinispan 缓存来缓冲交易数据并将其保存到磁盘。 infinispan_remote- 此选项使用远程 Infinispan 集群来缓冲交易数据并将其保存到磁盘。 |
log.mining.buffer.type | memory | 缓冲区类型控制连接器如何管理缓冲事务数据。memory- 使用 JVM 进程的堆来缓冲所有事务数据。如果您不希望连接器处理大量长时间运行的事务或大型事务,请选择此选项。当此选项处于活动状态时,缓冲区状态不会在重新启动后保持不变。重启后,从当前偏移量的 SCN 值重新创建缓冲区。infinispan_embedded- 此选项使用嵌入式 Infinispan 缓存来缓冲交易数据并将其保存到磁盘。infinispan_remote- 此选项使用远程 Infinispan 集群来缓冲交易数据并将其保存到磁盘。 |
signal.data.collection | 用于向连接器发送信号的数据集合的完全限定名称。当您将此属性用于 Oracle 可插拔数据库 (PDB) 时,请将其值设置为根数据库的名称。使用以下格式指定集合名称: |
|
incremental.snapshot.chunk.size | 1024 | 连接器在增量快照块期间提取并读入内存的最大行数。增加块大小可提供更高的效率,因为快照运行的快照查询数量更大。但是,更大的块大小也需要更多内存来缓冲快照数据。将块大小调整为可在您的环境中提供最佳性能的值。 |
topic.naming.strategy | io.debezium.schema.SchemaTopicNamingStrategy | 应用于确定数据更改、模式更改、事务、心跳事件等主题名称的 TopicNamingStrategy 类的名称,默认为SchemaTopicNamingStrategy. |
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 的值。在并行初始快照中,连接器同时处理多个表。此功能正在孵化。 |
Debezium 提供一组 schema.history.internal.* 属性来控制连接器如何与模式历史主题交互。
下表描述了用于配置 Debezium 连接器的 schema.history.internal 属性。
属性 | 默认参数 | 含义解释 |
---|---|---|
schema.history.internal.kafka.topic | 连接器存储数据库架构历史记录的 Kafka 主题的全名。 | |
schema.history.internal.kafka.bootstrap.servers | 连接器用于建立与 Kafka 集群的初始连接的主机/端口对列表。此连接用于检索以前由连接器存储的数据库模式历史记录,以及用于编写从源数据库读取的每个 DDL 语句。每对都应指向 Kafka Connect 进程使用的同一个 Kafka 集群。 | |
schema.history.internal.kafka.recovery.poll.interval.ms | 一个整数值,指定连接器在启动/恢复期间轮询持久数据时应等待的最大毫秒数。默认值为 100 毫秒。 | |
schema.history.internal.kafka.query.timeout.ms | 一个整数值,指定连接器在使用 Kafka 管理客户端获取集群信息时应等待的最大毫秒数 | |
schema.history.internal.kafka.create.timeout.ms | 一个整数值,指定连接器在使用 Kafka 管理客户端创建 kafka 历史主题时应等待的最大毫秒数。 | |
schema.history.internal.kafka.create.timeout.ms | 在连接器恢复因错误而失败之前,连接器应尝试读取持久历史数据的最大次数。未接收到数据后等待的最长时间为recovery.attempts× recovery.poll.interval.ms。 | |
schema.history.internal.skip.unparseable.ddl | 一个布尔值,指定连接器是应忽略格式错误或未知的数据库语句,还是应停止处理以便人工修复问题。安全默认值是false. 跳过应谨慎使用,因为它可能会在处理二进制日志时导致数据丢失或损坏。 | |
schema.history.internal.store.only.captured.tables.ddl | 一个布尔值,指定连接器是否应记录来自指定模式或数据库的所有 DDL 语句true仅记录那些与 Debezium 捕获其更改的表相关的 DDL 语句。小心设置为true,因为如果您更改捕获其更改的表,则可能需要缺少数据。 | |
安全默认值是false. | ||
schema.history.internal.store.only.captured.databases.ddl | 一个布尔值,指定连接器是否应记录所有 DDL 语句true仅记录那些与 Debezium 捕获更改的数据库/模式表相关的 DDL 语句。false将存储所有传入的 DDL 语句。 |
默认情况下,Debezium Oracle 连接器使用本机 Oracle LogMiner 获取更改。连接器可以切换为使用 Oracle XStream。要将连接器配置为使用 Oracle XStream,您必须应用不同于您使用 LogMiner 的特定数据库和连接器配置。
先决条件
Oracle XStream 所需的配置
ORACLE_SID=ORCLCDB dbz_oracle sqlplus /nolog
CONNECT sys/top_secret AS SYSDBA
alter system set db_recovery_file_dest_size = 5G;
alter system set db_recovery_file_dest = '/opt/oracle/oradata/recovery_area' scope=spfile;
alter system set enable_goldengate_replication=true;
shutdown immediate
startup mount
alter database archivelog;
alter database open;
-- Should show "Database log mode: Archive Mode"
archive log list
exit;
此外,必须为捕获的表或数据库启用补充日志记录,以便数据更改能够捕获更改的数据库行之前的状态。下面说明如何在特定表上进行配置,这是最大限度减少 Oracle 重做日志中捕获的信息量的理想选择。
ALTER TABLE inventory.customers ADD SUPPLEMENTAL LOG DATA (ALL) COLUMNS;
Debezium Oracle 连接器要求为用户帐户设置特定权限,以便连接器可以捕获更改事件。下面使用多租户数据库模型简要描述这些用户配置。
创建 XStream 管理员用户
sqlplus sys/top_secret@//localhost:1521/ORCLCDB as sysdba
CREATE TABLESPACE xstream_adm_tbs DATAFILE '/opt/oracle/oradata/ORCLCDB/xstream_adm_tbs.dbf'
SIZE 25M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED;
exit;
sqlplus sys/top_secret@//localhost:1521/ORCLPDB1 as sysdba
CREATE TABLESPACE xstream_adm_tbs DATAFILE '/opt/oracle/oradata/ORCLCDB/ORCLPDB1/xstream_adm_tbs.dbf'
SIZE 25M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED;
exit;
sqlplus sys/top_secret@//localhost:1521/ORCLCDB as sysdba
CREATE USER c##dbzadmin IDENTIFIED BY dbz
DEFAULT TABLESPACE xstream_adm_tbs
QUOTA UNLIMITED ON xstream_adm_tbs
CONTAINER=ALL;
GRANT CREATE SESSION, SET CONTAINER TO c##dbzadmin CONTAINER=ALL;
BEGIN
DBMS_XSTREAM_AUTH.GRANT_ADMIN_PRIVILEGE(
grantee => 'c##dbzadmin',
privilege_type => 'CAPTURE',
grant_select_privileges => TRUE,
container => 'ALL'
);
END;
/
exit;
创建连接器的 XStream 用户
sqlplus sys/top_secret@//localhost:1521/ORCLCDB as sysdba
CREATE TABLESPACE xstream_tbs DATAFILE '/opt/oracle/oradata/ORCLCDB/xstream_tbs.dbf'
SIZE 25M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED;
exit;
sqlplus sys/top_secret@//localhost:1521/ORCLPDB1 as sysdba
CREATE TABLESPACE xstream_tbs DATAFILE '/opt/oracle/oradata/ORCLCDB/ORCLPDB1/xstream_tbs.dbf'
SIZE 25M REUSE AUTOEXTEND ON MAXSIZE UNLIMITED;
exit;
sqlplus sys/top_secret@//localhost:1521/ORCLCDB as sysdba
CREATE USER c##dbzuser IDENTIFIED BY dbz
DEFAULT TABLESPACE xstream_tbs
QUOTA UNLIMITED ON xstream_tbs
CONTAINER=ALL;
GRANT CREATE SESSION TO c##dbzuser CONTAINER=ALL;
GRANT SET CONTAINER TO c##dbzuser CONTAINER=ALL;
GRANT SELECT ON V_$DATABASE to c##dbzuser CONTAINER=ALL;
GRANT FLASHBACK ANY TABLE TO c##dbzuser CONTAINER=ALL;
GRANT SELECT_CATALOG_ROLE TO c##dbzuser CONTAINER=ALL;
GRANT EXECUTE_CATALOG_ROLE TO c##dbzuser CONTAINER=ALL;
exit;
创建一个XStream 出站服务器 (如果有正确的权限,这可能会由连接器自动完成):
创建 XStream 出站服务器
sqlplus c##dbzadmin/dbz@//localhost:1521/ORCLCDB
DECLARE
tables DBMS_UTILITY.UNCL_ARRAY;
schemas DBMS_UTILITY.UNCL_ARRAY;
BEGIN
tables(1) := NULL;
schemas(1) := 'debezium';
DBMS_XSTREAM_ADM.CREATE_OUTBOUND(
server_name => 'dbzxout',
table_names => tables,
schema_names => schemas);
END;
/
exit;
设置 XStream 出站服务器以从可插入数据库捕获更改时,source_container_name应提供指定可插入数据库名称的参数。
配置 XStream 用户帐户以连接到 XStream 出站服务器
sqlplus sys/top_secret@//localhost:1521/ORCLCDB as sysdba
BEGIN
DBMS_XSTREAM_ADM.ALTER_OUTBOUND(
server_name => 'dbzxout',
connect_user => 'c##dbzuser');
END;
/
exit;
笔记:
单个 XStream 出站服务器不能由多个 Debezium Oracle 连接器共享。每个连接器都需要配置一个唯一的 XStream 出站连接器。
默认情况下,Debezium 使用 Oracle LogMiner 从 Oracle 获取更改事件。您可以调整连接器配置以使连接器能够使用 Oracle XStreams 适配器。
以下配置示例添加属性database.connection.adapter并使database.out.server.name连接器能够使用 XStream API 实现。
{
"name": "inventory-connector",
"config": {
"connector.class" : "io.debezium.connector.oracle.OracleConnector",
"tasks.max" : "1",
"topic.prefix" : "server1",
"database.hostname" : "" ,
"database.port" : "1521",
"database.user" : "c##dbzuser",
"database.password" : "dbz",
"database.dbname" : "ORCLCDB",
"database.pdb.name" : "ORCLPDB1",
"schema.history.internal.kafka.bootstrap.servers" : "kafka:9092",
"schema.history.internal.kafka.topic": "schema-changes.inventory",
"database.connection.adapter": "xstream",
"database.out.server.name" : "dbzxout"
}
}
Debezium Oracle 连接器需要 Oracle JDBC 驱动程序 ( ojdbc8.jar) 才能连接到 Oracle 数据库。如果连接器使用 XStream 访问数据库,您还必须拥有 XStream API ( xstreams.jar)。许可要求禁止 Debezium 将这些文件包含在 Oracle 连接器存档中。但是,所需的文件可作为 Oracle Instant Client 的一部分免费下载。以下步骤描述了如何下载 Oracle Instant Client 并提取所需的文件。
程序
instantclient_21_1/
├── adrci
├── BASIC_LITE_LICENSE
├── BASIC_LITE_README
├── genezi
├── libclntshcore.so -> libclntshcore.so.21.1
├── libclntshcore.so.12.1 -> libclntshcore.so.21.1
...
├── ojdbc8.jar
├── ucp.jar
├── uidrvci
└── xstreams.jar
3.复制ojdbc8.jar和xstreams.jar文件,并将它们添加到
4.创建一个环境变量 ,LD_LIBRARY_PATH并将其值设置为 Instant Client 目录的路径,例如:
LD_LIBRARY_PATH=/path/to/instant_client/
使用 XStreams 时需要以下配置属性,除非有默认值可用。
database.out.server.name:数据库中配置的 XStream 出站服务器的名称。