您可以使用 Datastream 将 PostgreSQL 数据库中的历史数据和持续更改复制到目标位置,以进行实时分析和数据库同步。
如需在 Datastream 中为 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
免费层级
借助 Datastream,您可以使用免费层级将数据从 AlloyDB for PostgreSQL 流式传输到 BigQuery,每月最多可免费提供 100 GiB 的变更数据捕获数据。如需了解详情,请参阅 Datastream 价格。
最佳做法
本部分介绍了有关配置 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 要将哪些数据写入 WAL 以用于 UPDATE 和 DELETE 事件,从而使 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 16 及更高版本的 PostgreSQL 读取副本实例进行复制。
如需从只读副本进行复制,您必须在主实例上执行以下设置步骤:
- 在主实例上创建发布:虽然 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。
已知限制
将 Datastream 与 PostgreSQL 数据库搭配用作来源时的已知限制包括:
- 数据流限 10,000 个表。
- PostgreSQL 严格拒绝 UTF-8 字符串列中的 NULL 字节 (
0x00)。 Datastream 不会剥离 NULL 字节。如果源字符串包含0x00null 字节,则插入批处理会失败并停止复制。我们建议您在复制之前清理或替换源数据库中的CHAR(0)字符。 - 您无法将 PostgreSQL 数据流配置为从最新位置开始。
- 除非满足以下条件,否则无法回填行数超过 5 亿的表:
- 没有主键的表必须具有 REPLICA IDENTITY。否则,只有
INSERT事件会复制到目标。 - 具有主键的表不能将 REPLICA IDENTITY 设置为
FULL或NOTHING。必须设置为DEFAULT。 - 并非所有对源架构的更改都可以自动检测到,在这种情况下可能会发生数据损坏。以下架构更改可能会导致数据损坏或无法处理下游事件:
- 删除列。
- 在表格中间添加列。
- 更改列的数据类型。
- 正在重新排列列。
- 删除表(如果随后使用添加的新数据重新创建同一表,则相关)。
- Datastream 不支持
geometric数据类型的列,例如BOX、CIRCLE、LINE、LSEG、PATH、POINT和POLYGON。此类列会复制为NULL。 - Datastream 不支持
range数据类型的列。 - Datastream 不支持不受支持的数据类型(例如空间类型)的数组、
LTREE数组、用户定义的数据类型(包括ENUM)的数组,或DATE、TIMESTAMP或TIMESTAMP WITH TIME ZONE(TIMESTAMPTZ) 的数组。Datastream 在复制期间会忽略此类列。 - 对于 2026 年 2 月 17 日之前创建的数据流:如果行中的列包含 TOAST 值,且这些列属于表的副本标识,则 Datastream 不支持复制这些行的 UPDATE 事件。此类事件会被舍弃。在该日期之后创建的数据流不适用此例外情况。
- Datastream 不支持复制包含超过 2,950 个嵌套对象的
JSON或JSONB值的行。包含此类JSON或JSONB值的事件不会复制到目标数据库。 - Datastream 不支持复制在
NUMERIC (precision, scale)列中包含NaN值的行。此类列中的值会替换为NULL值。 - Datastream 不支持复制 hstore 数据类型的列。此类列中的值会替换为
NULL值。 - Datastream 不支持从 SQL_ASCII 编码的源数据库复制非 ASCII 记录。此类记录会被舍弃。
- Datastream 不支持复制定义了行级安全性 (RLS) 政策的表。 如需了解如何绕过此限制,请参阅 PostgreSQL 来源行为和限制。
- 对于使用超大属性存储技术 (TOAST) 的可变长度数据类型的流式列:
如果在
UPDATE操作期间从 WAL 日志中丢弃了未更改的 TOAST 值,Datastream 会对源数据库执行主动查找,以尝试恢复缺失的值。 因此,在涉及快速、连续更新或插入后快速删除的场景中,可能无法捕获中间更改。请注意,DELETE操作不会触发此主动查找操作。对于使用 TOAST 的可变长度列,此限制在使用仅附加写入模式时尤为重要,因为该模式要求捕获所有中间更改。 - Datastream 不会捕获对生成的列所做的更改。
- 在数据库上执行 PostgreSQL 主要版本升级时,Datastream 可能会停止运行或无法捕获任何新事件。我们建议您在升级前删除复制槽,然后升级数据库,再重新创建复制槽。如果数据流失败,请通过指定新的复制槽名称来恢复数据流,并在需要数据一致性时执行回填。
- 使用自动数据流设置流程时,Datastream 不支持复制 PostgreSQL 系统表。如果您修改使用自动化流程创建的数据流并添加系统表,Datastream 会静默忽略这些表,并且不会复制这些表中的任何数据或更改。
后续步骤
- 了解如何配置 PostgreSQL 来源以与 Datastream 搭配使用。