7.4. Debezium PostgreSQL 连接器如何映射数据类型
PostgreSQL 连接器代表对带有结构的事件的更改,这些事件与行存在的表类似。事件包含每个列值的一个字段。在事件中如何代表该值取决于列的 PostgreSQL 数据类型。以下小节描述了连接器如何将 PostgreSQL 数据类型映射到 字面类型以及 事件字段中 的语义类型。
-
literal type 代表值如何被代表,使用 Kafka Connect schema 类型:
INT8
,INT16
,INT32
,INT64
,FLOAT32
,FLOAT64
,BOOLEAN
,STRING
,BYTES
,ARRAY
,MAP
, 和STRUCT
。 - 语义类型 描述了 Kafka Connect 模式如何使用字段名称来捕获字段 的含义。
如果默认数据类型转换不满足您的需要,您可以为连接器 创建自定义转换器。
以下部分详情:
基本类型
下表描述了连接器如何映射基本类型。
PostgreSQL 数据类型 | 字面类型(schema 类型) | 语义类型(模式名称)和备注 |
---|---|---|
|
| 不适用 |
|
| 不适用 |
|
|
|
|
|
|
|
| 不适用 |
|
| 不适用 |
|
| 不适用 |
|
| 不适用 |
|
| 不适用 |
|
| 不适用 |
|
| 不适用 |
|
| 不适用 |
|
| 不适用 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
N/a |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 不适用 |
|
| 不适用 |
|
|
N/a |
|
|
N/A |
|
|
N/A |
|
|
n/a |
|
|
n/a |
|
|
n/a |
|
|
|
时序类型
除 PostgreSQL 的 TIMESTAMPTZ
和 TIMETZ
数据类型外,包含时区信息,临时类型是如何映射的,具体类型取决于 time.precision.mode
连接器配置属性的值。以下小节描述了这些映射:
time.precision.mode=adaptive
当将 time.precision.mode
属性设置为 adaptive
时,连接器会根据列的数据类型定义确定字面类型和语义类型。这样可确保事件 完全 代表数据库中的值。
PostgreSQL 数据类型 | 字面类型(schema 类型) | 语义类型(模式名称)和备注 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
time.precision.mode=adaptive_time_microseconds
当将 time.precision.mode
配置属性设置为 adaptive_time_microseconds
时,连接器会根据列的数据类型确定 temporal 类型的字面类型和 semantic 类型。这样可确保事件 准确 代表数据库中的值,但所有 TIME
字段都捕获为微秒。
PostgreSQL 数据类型 | 字面类型(schema 类型) | 语义类型(模式名称)和备注 |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
time.precision.mode=connect
当将 time.precision.mode
配置属性设为 connect
时,连接器会使用 Kafka Connect 逻辑类型。当消费者只能处理内置的 Kafka Connect 逻辑类型,且无法处理变量-precision 时间值时,这非常有用。但是,由于 PostgreSQL 支持 microsecond 精度,因此当数据库列具有大于 3 的 fractional second precision 值时,带有 connect
时间精度的连接器会导致 精度丢失。
PostgreSQL 数据类型 | 字面类型(schema 类型) | 语义类型(模式名称)和备注 |
---|---|---|
|
|
|
|
|
|
|
|
|
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
列中使用 +/-infinite
值。这些特殊的值转换为时间戳,在正无限循环的情况下值为 9223372036825200000
,在负无限循环的情况值为 -9223372036832400000
。这个行为模拟 PostgreSQL JDBC 驱动程序的标准行为。如需更多信息,请参阅 org.postgresql.PGStatement
接口。
十进制类型
PostgreSQL 连接器配置属性 decimal.handling.mode
的设置决定了连接器如何映射十进制类型。
当将 decimal.handling.mode
属性设置为 precise
时,连接器使用 Kafka Connect org.apache.kafka.connect.data.Decimal
logical type for all DECIMAL
,NUMERIC
和 MONEY
列。这是默认的模式。
PostgreSQL 数据类型 | 字面类型(schema 类型) | 语义类型(模式名称)和备注 |
---|---|---|
|
|
|
|
|
|
|
|
|
此规则例外。当在没有扩展限制的情况下使用 NUMERIC
或 DECIMAL
类型时,来自数据库的值会为每个值有不同的(变量)扩展。在这种情况下,连接器使用 io.debezium.data.VariableScaleDecimal
,其中包含传输的值和扩展。
PostgreSQL 数据类型 | 字面类型(schema 类型) | 语义类型(模式名称)和备注 |
---|---|---|
|
|
|
|
|
|
当将 decimal.handling.mode
属性设置为 double
时,连接器代表所有 DECIMAL
、NUMERIC
和 MONEY
值作为 Java 双值,并对它们进行编码,如下表所示。
PostgreSQL 数据类型 | 字面类型(schema 类型) | 语义类型(schema name) |
---|---|---|
|
| |
|
| |
|
|
decimal.handling.mode
配置属性的最后可能设置为 字符串
。在这种情况下,连接器代表 DECIMAL
、NUMERIC
和 MONEY
值作为其格式化的字符串表示,并对它们进行编码,如下表所示。
PostgreSQL 数据类型 | 字面类型(schema 类型) | 语义类型(schema name) |
---|---|---|
|
| |
|
| |
|
|
当将 decimal.handling.mode
为 字符串
或 双
时,PostgreSQL 支持 NaN
(不是数字)作为存储在 DECIMAL
/NUMERIC
值中的特殊值。在这种情况下,连接器将 NaN
编码为 Double.NaN
或字符串常量 NAN
。
HSTORE 类型
PostgreSQL 连接器配置属性 hstore.handling.mode
的设置决定了连接器如何映射 HSTORE
值。
当 dhstore.handling.mode
属性设置为 json
(默认值)时,连接器将 HSTORE
值表示为 JSON 值的字符串表示,如下表所示。当 hstore.handling.mode
属性设置为 map
时,连接器使用 HSTORE
值的 MAP
模式类型。
PostgreSQL 数据类型 | 字面类型(schema 类型) | 语义类型(模式名称)和备注 |
---|---|---|
|
|
|
|
|
n/a |
域类型
PostgreSQL 支持基于其他底层类型的用户定义的类型。使用此类列类型时,Debezium 会根据完整的类型层次结构公开列的表示。
捕获使用 PostgreSQL 域类型的列的更改需要特别考虑。当定义列以包含扩展默认数据库类型的域类型,并且域类型定义了自定义长度或规模时,生成的模式将继承该定义长度或规模的模式。
当定义列包含扩展自定义长度或规模的另一个域类型的域类型时,生成的模式 不会继承 定义的长度或扩展,因为 PostgreSQL 驱动程序的列元数据中没有这些信息。
网络地址类型
PostgreSQL 具有可以存储 IPv4、IPv6 和 MAC 地址的数据类型。最好使用这些类型而不是纯文本类型来存储网络地址。网络地址类型提供输入错误检查和专用操作器和功能。
PostgreSQL 数据类型 | 字面类型(schema 类型) | 语义类型(模式名称)和备注 |
---|---|---|
|
|
N/a |
|
|
N/a |
|
|
N/A |
|
|
N/a |
PostGIS 类型
PostgreSQL 连接器支持所有 PostGIS 数据类型。
PostGIS 数据类型 | 字面类型(schema 类型) | 语义类型(模式名称)和备注 |
---|---|---|
|
|
有关格式详情,请参阅 Open Geospatial Consortium Simple Features Access specification。 |
|
|
有关格式详情,请参阅 Open Geospatial Consortium Simple Features Access specification。 |
要粘贴的值
PostgreSQL 对页面大小具有硬限制。这意味着,大于 8 KB 的值需要使用 TOAST 存储来存储。这会影响来自数据库的复制消息。使用 TOAST 机制存储的值且尚未更改的值不会包含在消息中,除非它们是表的副本身份的一部分。Debezium 无法安全地从数据库读取缺少的值,因为这可能导致竞争条件。因此,Debezium 遵循这些规则来处理粘贴值:
-
具有
REPLICA IDENTITY FULL
的表 - TOAST 列值是更改事件的before
和after
字段的一部分,就像任何其他列一样。 -
带有
REPLICA IDENTITY DEFAULT
的表 - 从数据库接收UPDATE
事件时,任何没有包括在事件中的 TOAST 列值。同样,在收到DELETE
事件时,如果是 TOAST,则没有 TOAST 列(若有)。因为 Debezium 无法安全地提供列值,因此连接器会返回一个占位符值,如连接器配置属性
unavailable.value.placeholder
定义。
默认值
如果为数据库模式中的列指定了默认值,PostgreSQL 连接器将尽可能尝试将此值传播到 Kafka 模式。最常见的数据类型受到支持,包括:
-
布尔值
-
数字类型(
INT
、FLOAT
、NUMERIC
等) -
文本类型(
CHAR
、VARCHAR
、TEXT
等) -
时序类型(
DATE
,TIME
,INTERVAL
,TIMESTAMP
,TIMESTAMPTZ
) -
JSON
,JSONB
,XML
-
UUID
请注意,对于临时类型,对默认值的解析由 PostgreSQL 库提供;因此,PostgreSQL 通常支持的任何字符串表示也应该被连接器支持。
如果默认值由函数生成,而不是直接指定,则连接器将为给定的数据类型导出等效的 0
。这些值包括:
-
FALSE
forBOOLEAN
-
0
带有适当的精度,用于数字类型 - text/XML 类型的空字符串
-
JSON 类型的
{}
-
1970-01-01
forDATE
,TIMESTAMP
,TIMESTAMPTZ
类型 -
TIME
的00:00
-
INTERVAL
为EPOCH
-
00000000-0000-0000-0000-000000000000
用于UUID
目前,这个支持只扩展到明确使用功能。例如,CURRENT_TIMESTAMP (6)
支持括号,但 CURRENT_TIMESTAMP
不支持。
当将 PostgreSQL 连接器与强制实施模式版本间兼容的模式 registry 时,支持对默认值的传播主要允许安全模式演进。由于这个主要关注,以及不同插件的刷新行为,Kafka 模式中存在的默认值无法保证始终与数据库模式中的默认值同步。
- 默认值可能会在 Kafka 模式中显示"late",具体取决于给定插件触发刷新内存模式的时间/方式。如果默认更改多次更改,则值永远不会在 Kafka 模式中显示/被跳过
- 如果在连接器等待处理记录时触发模式刷新,则默认值可能会在 Kafka 模式中出现 'early'。这是因为列元数据在刷新时从数据库读取,而不是在复制消息中存在。如果连接器后端并出现刷新,或者如果连接器在更新继续写入源数据库时停止了连接器,则可能会发生这种情况。
此行为可能是意外的,但它仍然是安全的。只有架构定义会受到影响,而消息中存在的实际值将与写入源数据库的实际值保持一致。