从 PostgreSQL 数据库中流式传输数据

本部分包含有关以下内容的信息:

  • 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

免费层级

Datastream 允许您使用免费层级从 AlloyDB for PostgreSQL 流式传输到 BigQuery,每月免费提供高达 100 GiB 的变更数据捕获数据。如需了解详情,请参阅 Datastream 价格

最佳实践

本部分介绍了配置 PostgreSQL 来源以与 Datastream 搭配使用的建议最佳实践。

使用多个数据流来防止队头阻塞

对于 PostgreSQL 来源,Datastream 会为整个数据流使用单个逻辑复制槽。如果一个高容量表上发生大型事务或多次更新,可能会延迟同一数据流中所有其他表的数据复制。

如需防止队头阻塞,请为不同的表集创建单独的数据流。例如,您可以为高容量表创建一个数据流,为低容量表创建另一个数据流。这样可以隔离高流失率表,并防止它们延迟其他表的复制。

建议: 识别写入 (INSERT/UPDATE/DELETE) 速率异常高的表,并将它们放置在自己的专用 Datastream 数据流中,并使用单独的复制槽。

避免长时间运行的事务

长时间运行的事务可能会导致预写式日志 (WAL) 累积。由于 WAL 是顺序的,因此在长时间运行的事务完成之前,PostgreSQL 无法移除复制槽所需的旧 WAL 文件。这会增加 WAL 磁盘用量。

此外,这还会降低逻辑解码速度。速度降低的原因是大型事务将更改溢出到磁盘,这需要在提交时进行缓慢的 I/O 密集型重新组装,从而阻止所有后续事务的复制。 建议: 在源数据库中,配置 statement_timeoutidle_in_transaction_session_timeout 参数,以避免长时间运行的事务。如需了解详情,请参阅 PostgreSQL 文档

创建发布内容时使用表过滤

如果您仅复制几个表中的更改,请确保您创建的 PUBLICATION 仅包含这些表。当发布内容限定为特定表时,PostgreSQL 会高效地仅为复制槽中的这些表保留更改。这有助于减小复制槽的大小并提高逻辑解码性能。

主动管理复制槽

Datastream 在 PostgreSQL 主实例上使用逻辑复制槽,这可确保 WAL 文件在 Datastream 确认已处理之前保留。如果数据流失败、暂停或删除,但未删除复制槽,PostgreSQL 会无限期地保留 WAL 文件。这可能会填满数据库服务器磁盘,并导致生产中断。

建议: 设置高效的提醒,并监控源 PostgreSQL 服务器上的 WAL 磁盘用量。

正确配置副本身份

REPLICA IDENTITY 设置会告知 PostgreSQL 将哪些数据写入 UPDATEDELETE 事件的 WAL,从而让 Datastream 能够识别哪些行发生了更改。

如果您使用 BigQuery 作为目标位置,请避免将 REPLICA IDENTITY 设置为 FULL。Datastream 使用已记录的列作为 BigQuery MERGE 操作的逻辑键。 如果 REPLICA IDENTITY 设置为 FULL,并且表包含超过 16 列,则会超出 BigQuery 在 MERGE 操作中对主键的 16 列限制,并中断数据流。

建议 (按偏好顺序):

  1. 最佳: 使用主键。REPLICA IDENTITY DEFAULT 的默认设置会自动高效地使用现有主键。
  2. 良好: 如果不存在主键,请创建 UNIQUE NOT NULL 索引并设置 REPLICA IDENTITY USING INDEX INDEX_NAME
  3. 最不推荐: 仅在没有唯一标识符的表上使用 REPLICA IDENTITY FULL 设置。如果复制到 BigQuery,请注意性能影响、16 列限制以及对主键支持的数据类型的限制。

从读取副本进行复制

Datastream 支持从 PostgreSQL 16 及更高版本的 PostgreSQL 读取副本实例进行复制。

如需从读取副本进行复制,您必须在主实例上执行以下设置步骤:

  1. 在主实例上创建发布内容:当 Datastream 连接到读取副本时,必须在主实例上创建定义要复制的数据的发布内容。
  2. 配置 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 个表。
  • 如果表超过 5 亿行,则无法回填,除非满足以下条件:
    1. 该表具有唯一的 B 树索引。
    2. 该索引不包含以下类型的列: DOUBLEFLOATMONEYREALJSONJSONBBYTEATXIDXML复合数据类型几何数据类型
    3. 索引的任何列都不可为 null。
    4. 索引的所有列都按升序排列,或者索引的所有列都按降序排列。
    5. 索引的所有列都包含在数据流中。
  • 没有主键的表必须具有 REPLICA IDENTITY。否则,只有 INSERT 事件会复制到目标位置。
  • 具有主键的表不能将 REPLICA IDENTITY 设置为 FULLNOTHING。必须将其设置为 DEFAULT
  • 并非所有对源架构的更改都可以自动检测到,在这种情况下可能会发生数据损坏。以下架构更改可能会导致数据损坏或无法处理下游事件:
    • 删除列。
    • 在表中间添加列。
    • 更改列的数据类型。
    • 对列重新排序。
    • 删除表(如果同一表被重新创建并添加了新的数据,则与此相关)。
  • Datastream 不支持 geometric 数据类型的列。
  • Datastream 不支持 range 数据类型的列。
  • Datastream 不支持不受支持的数据类型的数组、用户定义的数据类型的数组(包括 ENUM)或 DATETIMESTAMPTIMESTAMP WITH TIME ZONE 数据类型的数组。系统会忽略此类列。
  • 对于在 2026 年 2 月 17 日之前创建的数据流:Datastream 不支持复制包含 TOAST 值的行的 UPDATE 事件,这些行位于属于表副本身份的列中。此类事件会被舍弃。在此日期之后创建的数据流不受此例外情况的限制。
  • Datastream 不支持复制包含超过 2950 个嵌套对象的 JSONJSONB 值的行。包含此类 JSONJSONB 值的事件不会复制到目标数据库。
  • Datastream 不支持复制在 NUMERIC (precision, scale) 列中包含 NaN 值的行。此类列中的值将替换为 NULL 值。
  • Datastream 不支持复制 hstore 数据类型的列。此类列中的值将替换为 NULL 值。
  • Datastream 不支持从 SQL_ASCII 编码的源数据库复制非 ASCII 记录。此类记录会被舍弃。
  • Datastream 不支持复制定义了行级安全性 (RLS) 政策的表。 如需了解如何绕过此限制,请参阅 PostgreSQL 来源行为和限制
  • Datastream 不会捕获对 生成的列所做的更改。
  • 在数据库上执行 PostgreSQL 主要版本升级时,Datastream 可能会停止工作或不捕获任何新事件。我们建议您在升级之前删除复制槽,然后升级数据库,再重新创建复制槽。如果数据流失败,请通过指定新的复制槽名称来恢复数据流,并在需要数据一致性时执行回填。
  • 使用自动数据流设置流程时,Datastream 不支持复制 PostgreSQL 系统表。如果您修改使用自动流程创建的数据流并添加系统表,Datastream 会以静默方式忽略这些表,并且不会复制其中的任何数据或更改。

后续步骤