本部分包含有关以下内容的信息:
- Datastream 如何处理从来源 PostgreSQL 数据库中拉取的数据的行为
- Datastream 支持的 PostgreSQL 数据库版本
- 如何设置来源 PostgreSQL 数据库以便将数据从该数据库流式传输到目标位置的概述
- 将 PostgreSQL 数据库用作来源的已知限制
行为
源 PostgreSQL 数据库依赖其逻辑解码功能。逻辑解码会公开提交到数据库的所有更改,并允许使用输出插件以用户友好的格式使用和处理这些更改。Datastream 使用 pgoutput 插件,这是适用于 PostgreSQL 10 及更高版本的标准 PostgreSQL 逻辑解码插件。
- 可以选择给定 PostgreSQL 来源中的所有架构或特定架构,以及架构或特定表中的所有表。
- 复制所有历史数据。
- 复制所有数据操纵语言 (DML) 变更,例如从指定数据库和表插入、更新和删除。
- 仅复制已提交的更改。
- 如果您在表上定义了 REPLICA IDENTITY,Datastream 会将指定的列视为主键。
- 当 Datastream 连接到主实例时,会定期向源数据库发送检测信号消息。因此,逻辑解码消息事件 (
op:"m") 会直接插入到 WAL 文件中。Datastream 需要这些消息来确保源可用性并计算新鲜度。当您使用读取副本作为来源时,必须在外部配置心跳消息。如需了解详情,请参阅从读取副本进行复制。如果其他复制设置从同一源数据库读取数据,建议您考虑这一点。
版本
Datastream 支持 PostgreSQL 10 及更高版本。
Datastream 支持以下类型的 PostgreSQL 数据库:
- 自托管的 PostgreSQL
- Cloud SQL for PostgreSQL
- AlloyDB for PostgreSQL
- AlloyDB Omni
- Amazon RDS for PostgreSQL
- Amazon Aurora PostgreSQL
最佳做法
本部分介绍了有关配置 PostgreSQL 源以搭配 Datastream 使用的建议最佳实践。
使用多个流来防止队头阻塞
对于 PostgreSQL 源,Datastream 会为整个数据流使用单个逻辑复制槽。如果事务较大,或者对一个高容量表进行多次更新,可能会延迟同一数据流中所有其他表的数据复制。
为防止出现队首阻塞,请为不同的表集创建单独的流。例如,您可以为高容量表创建一个流,为低容量表创建另一个流。这样可以隔离高变动表,防止它们延迟其他表的复制。
建议:找出写入速率极高(INSERT/UPDATE/DELETE)的表,并将它们放置在具有单独复制槽的专用 Datastream 流中。
避免长时间运行的事务
长时间运行的事务可能会导致预写式日志 (WAL) 积压。由于 WAL 是按顺序记录的,因此在长时间运行的事务完成之前,PostgreSQL 无法移除复制槽所需的旧 WAL 文件。这会增加 WAL 磁盘用量。
此外,这还会降低逻辑解码速度。这种减速是由大型事务将更改溢出到磁盘引起的,这需要在提交时进行缓慢的 I/O 密集型重新组装,从而阻止所有后续事务的复制。建议:在源数据库上,配置 statement_timeout 和 idle_in_transaction_session_timeout 参数,以避免长时间运行的事务。如需了解详情,请参阅 PostgreSQL 文档。
创建出版物时使用表格过滤功能
如果您仅复制少数几个表中的更改,请确保您创建的 PUBLICATION 仅包含这些表。当发布限定为特定表时,PostgreSQL 会高效地仅将这些表中的更改持久保存到复制槽中。这有助于减小复制槽的大小并提高逻辑解码性能。
主动管理复制槽
Datastream 在 PostgreSQL 主实例上使用逻辑复制槽,这可确保 WAL 文件在 Datastream 确认已处理完毕之前一直保留。如果某个流失败、暂停或被删除,但未舍弃复制槽,PostgreSQL 会继续无限期保留 WAL 文件。这可能会导致数据库服务器磁盘空间不足,进而导致生产中断。
建议:在源 PostgreSQL 服务器上设置高效的提醒并监控 WAL 磁盘使用情况。
正确配置副本身份
REPLICA IDENTITY 设置会告知 PostgreSQL 要将哪些数据写入 UPDATE 和 DELETE 事件的 WAL,从而使 Datastream 能够识别哪些行发生了更改。
如果您使用 BigQuery 作为目标,请避免将 REPLICA IDENTITY 设置为 FULL。Datastream 使用记录的列作为 BigQuery MERGE 操作的逻辑键。如果 REPLICA IDENTITY 设置为 FULL,且某个表包含超过 16 列,则会超出 BigQuery 在 MERGE 操作中对主键的 16 列限制,并导致数据流中断。
建议(按优先顺序排列):
- 最佳做法:使用主键。
REPLICA IDENTITY DEFAULT的默认设置会自动高效地使用现有的主键。 - 良好:如果不存在主键,则创建
UNIQUE NOT NULL索引并设置REPLICA IDENTITY USING INDEX INDEX_NAME。 - 最不推荐:仅在没有唯一标识符的表格中使用
REPLICA IDENTITY FULL设置。如果复制到 BigQuery,请注意性能影响、16 列的限制以及对主键支持的数据类型的限制。
从读取副本进行复制
Datastream 支持从 PostgreSQL 读取副本实例进行复制,但仅限 PostgreSQL 16 及更高版本。
如需从只读副本复制数据,您必须在主实例上执行以下设置步骤:
- 在主实例上创建发布:虽然 Datastream 连接到读取副本,但必须在主实例上创建用于定义要复制的数据的发布。
- 配置 WAL 心跳:Datastream 依赖于定期 WAL 心跳消息来实现其检查点机制。连接到主实例时,Datastream 会处理这些心跳的生成。不过,对于读取副本,这些心跳必须在外部生成。
设置定期检测信号的一种方法是使用 pg_cron 扩展程序在 PostgreSQL 中创建 cron 任务:
SELECT cron.schedule_in_database(
'datastream-heartbeat', -- Job name
'* * * * *', -- Every minute
$$SELECT pg_logical_emit_message(true, 'datastream', 'cdc heartbeat')$$,
'DATABASE_NAME', -- Change this to your database name
'USERNAME', -- Username to run as
true -- Enabled
);
替换以下内容:
- DATABASE_NAME:要为其生成心跳信号的数据库的名称。
- USERNAME:要以哪个用户的身份运行任务。一般价格为
postgres。
已知限制
将 PostgreSQL 数据库用作来源时,使用 Datastream 的已知限制包括:
- 数据流限 10,000 个表。
- 如果表中的行数超过 5 亿,则无法回填,除非满足以下条件:
- 没有主键的表必须具有副本标识。否则,只有
INSERT事件会被复制到目标。 - 具有主键的表不能将 REPLICA IDENTITY 设置为
FULL或NOTHING。必须将其设置为DEFAULT。 - 并非所有对源架构的更改都可以自动检测到,在这种情况下可能会发生数据损坏。以下架构更改可能会导致数据损坏或无法处理下游事件:
- 删除列。
- 在表中间添加列。
- 更改列的数据类型。
- 对列重新排序。
- 删除表(如果同一表被重新创建并添加了新的数据,则与此相关)。
- Datastream 不支持
geometric数据类型的列。 - Datastream 不支持
range数据类型的列。 - Datastream 不支持以下类型的数组:不支持的数据类型的数组、用户定义的数据类型的数组(包括
ENUM)或DATE、TIMESTAMP或TIMESTAMP WITH TIME ZONE数据类型的数组。系统会忽略此类列。 - 对于 2026 年 2 月 17 日之前创建的数据流:Datastream 不支持复制以下行的 UPDATE 事件:这些行的列(属于表的复制身份)中包含 TOAST 值。此类事件会被舍弃。在该日期之后创建的媒体资源流不受此例外情况的约束。
- Datastream 不支持复制包含超过 2950 个嵌套对象的
JSON或JSONB值的行。包含此类JSON或JSONB值的事件不会复制到目标数据库。 - Datastream 不支持复制在
NUMERIC (precision, scale)列中包含NaN值的行。相应列中的值将替换为NULL值。 - Datastream 不支持复制 hstore 数据类型的列。相应列中的值将替换为
NULL值。 - Datastream 不支持从 SQL_ASCII 编码的源数据库复制非 ASCII 记录。此类记录会被舍弃。
- Datastream 不支持复制定义了行级安全性 (RLS) 政策的表。如需了解如何绕过此限制,请参阅 PostgreSQL 来源行为和限制。
- Datastream 不会捕获对生成列所做的更改。
- 在数据库上执行 PostgreSQL 主要版本升级时,Datastream 可能会停止工作或无法捕获任何新事件。我们建议您在升级之前删除复制槽,然后升级数据库,最后重新创建复制槽。如果数据流失败,请指定新的复制槽名称来恢复数据流,并在需要数据一致性的情况下执行回填。
- 使用自动数据流设置流程时,Datastream 不支持复制 PostgreSQL 系统表。如果您修改了使用自动化流程创建的数据流并添加了系统表,Datastream 会默默忽略这些表,并且不会复制其中的任何数据或变更。
后续步骤
- 了解如何配置 PostgreSQL 源以与 Datastream 搭配使用。