跳转到主要内容

事务回滚会同步到 ClickHouse 吗?

不会。CDC (变更数据捕获) 只会复制已提交的事务。已回滚的事务绝不会发送到 ClickHouse。

我可以让数据在 ClickHouse 中的保留时间比源 Postgres 更长吗?

可以。源 Postgres 和目标端 ClickHouse 的数据保留策略彼此独立。例如,你可以在 Postgres 中只保留 3 个月的数据,同时在 ClickHouse 中保留完整历史。在 Postgres 中删除旧行会生成会复制到 ClickHouse 的 DELETE 事件,因此如果你想保留历史数据,应在 publication 中排除 DELETE,或在查询层处理这些事件。

当数据从 Postgres 流向 ClickHouse 时,如何进行富集?

在 CDC 目标端表之上使用 materialized views。ClickHouse 中的 materialized view 可充当插入触发器,因此,从 Postgres 复制过来的每一行都可以在写入最终目标表之前进行转换、与查找表关联,或添加额外的列进行富集。

我可以将多个 Postgres 实例复制到一个或多个 ClickHouse 服务吗?

可以。您可以从不同的 Postgres 实例 (包括跨 AWS 区域的实例) 分别创建 ClickPipes,并将其接入一个或多个 ClickHouse 服务。例如,您可以将某个区域的 Postgres 数据发送到本地 ClickHouse 集群,以实现低延迟分析;同时发送到另一区域的集中式 ClickHouse 集群,以便进行汇总报表。请注意,跨区域部署会产生 AWS 跨区域数据传输费用,并增加网络延迟。

空闲会如何影响我的 Postgres CDC ClickPipe?

如果你的 ClickHouse Cloud 服务处于空闲状态,Postgres CDC ClickPipe 仍会继续同步数据;服务会在下一个同步间隔到来时唤醒,以处理传入的数据。同步完成后,达到空闲时长后,服务会重新进入空闲状态。 例如,如果同步间隔设置为 30 分钟,而服务空闲时长设置为 10 分钟,那么服务将每 30 分钟唤醒一次并保持活动 10 分钟,然后重新进入空闲状态。

ClickPipes for Postgres 如何处理 TOAST 列?

更多信息,请参阅TOAST 列处理页面。

ClickPipes for Postgres 如何处理生成列?

更多信息,请参阅 Postgres 生成列:注意事项与最佳实践 页面。

表要作为 Postgres CDC 的一部分,是否必须有主键?

要通过 ClickPipes for Postgres 复制表,该表必须定义主键或 REPLICA IDENTITY
  • 主键:最直接的方法是在表上定义主键。主键可为每一行提供唯一标识,这对于跟踪更新和删除至关重要。在这种情况下,可以将 REPLICA IDENTITY 设为 DEFAULT (默认行为) 。
  • 副本标识:如果表没有主键,也可以设置副本标识。副本标识可设为 FULL,表示使用整行来标识变更。或者,如果表上存在唯一索引,也可以将其设为使用该索引,然后将 REPLICA IDENTITY 设为 USING INDEX index_name。 要将副本标识设为 FULL,可以使用以下 SQL 命令:
ALTER TABLE your_table_name REPLICA IDENTITY FULL;
REPLICA IDENTITY FULL 还支持复制未发生变化的 TOAST 列。更多信息请参见此处 请注意,使用 REPLICA IDENTITY FULL 可能会影响性能,并导致 WAL 增长更快,尤其是对于没有主键且频繁更新或删除的表,因为它需要为每次变更记录更多数据。如果你对为表设置主键或副本标识有任何疑问,或需要相关帮助,请联系我们的支持团队获取指导。 还需注意,如果既未定义主键,也未定义副本标识,ClickPipes 将无法复制该表的变更,并且你可能会在复制过程中遇到错误。因此,建议你在设置 ClickPipe 之前检查表 schema,并确保其满足这些要求。

是否支持 Postgres CDC 中的分区表?

是的,支持分区表,开箱即用;前提是已定义 PRIMARY KEY 或 REPLICA IDENTITY。父表及其各个分区都必须包含 PRIMARY KEY 和 REPLICA IDENTITY。你可以在这里了解更多。

我可以连接没有公网 IP 或位于私有网络中的 Postgres 数据库吗?

可以!ClickPipes for Postgres 提供了两种连接私有网络中数据库的方式:
  1. SSH 隧道
    • 适用于大多数场景
    • 请在此处查看设置说明
    • 适用于所有区域
  2. AWS PrivateLink
    • 支持以下三个 AWS 区域:
      • us-east-1
      • us-east-2
      • eu-central-1
    • 详细设置说明请参阅我们的 PrivateLink 文档
    • 如果所在区域不支持 PrivateLink,请使用 SSH 隧道

如何处理 UPDATE 和 DELETE?

ClickPipes for Postgres 会将来自 Postgres 的 INSERT 和 UPDATE 捕获为 ClickHouse 中带有不同版本的新行 (使用 _peerdb_ 版本列) 。ReplacingMergeTree 表引擎会基于排序键 (ORDER BY 列) 定期在后台执行去重,仅保留 _peerdb_ 版本最新的那一行。 来自 Postgres 的 DELETE 会以标记为已删除的新行形式同步过来 (使用 _peerdb_is_deleted 列) 。由于去重过程是异步的,你可能会暂时看到重复数据。为此,你需要在查询层处理去重。 另请注意,默认情况下,Postgres 在执行 DELETE 操作时,不会发送不属于主键或副本标识的列值。如果你希望在 DELETE 时捕获完整的行数据,可以将 REPLICA IDENTITY 设置为 FULL。 更多详情,请参阅:

我可以在 PostgreSQL 中更新主键列吗?

默认情况下,PostgreSQL 中对主键的更新无法在 ClickHouse 中被正确回放。之所以存在这一限制,是因为 ReplacingMergeTree 的去重机制基于 ORDER BY 列 (这些列通常对应主键) 。当 PostgreSQL 中的主键发生更新时,在 ClickHouse 中它会表现为一条具有不同键的新行,而不是对现有行的更新。这可能导致旧的和新的主键值同时存在于您的 ClickHouse 表中。
请注意,在 PostgreSQL 数据库设计中,更新主键列并不是常见做法,因为主键本就是为充当不可变标识符而设计的。大多数应用在设计上都会避免更新主键,因此在典型使用场景中很少会遇到这一限制。 有一个 Experimental 设置可用于启用对主键更新的处理,但它会带来显著的性能影响,因此若未经充分评估,不建议在生产环境中使用。 如果您的使用场景需要在 PostgreSQL 中更新主键列,并希望这些变更能够正确反映到 ClickHouse 中,请通过 db-integrations-support@clickhouse.com 联系我们的支持团队,以讨论您的具体需求和可能的解决方案。

是否支持 schema 变更?

如需了解更多信息,请参阅 ClickPipes for Postgres:schema 变更传播支持 页面。

ClickPipes for Postgres CDC 的费用是多少?

如需了解详细定价信息,请参阅主计费概览页面中的 ClickPipes for Postgres CDC 定价部分

我的 replication slot 大小持续增长或迟迟不下降;可能是什么问题?

如果你发现 Postgres 的 replication slot 大小持续增加,或始终没有回落,通常意味着WAL (预写日志,Write-Ahead Log) 记录没有被你的 CDC 管道或复制过程及时消费 (或“重放”) 。下面列出了最常见的原因以及对应的处理方法。
  1. 数据库活动突然激增
    • 大批量更新、批量插入或重大的 schema 变更,都可能在短时间内生成大量 WAL 数据。
    • replication slot 会一直保留这些 WAL 记录,直到它们被消费,因此会导致大小暂时激增。
  2. 长时间运行的事务
    • 一个未结束的事务会迫使 Postgres 保留自该事务开始以来生成的所有 WAL 分段,这可能会显著增大 slot 的大小。
    • statement_timeoutidle_in_transaction_session_timeout 设置为合理的值,以防止事务无限期保持开启状态:
      SELECT
          pid,
          state,
          age(now(), xact_start) AS transaction_duration,
          query AS current_query
      FROM
          pg_stat_activity
      WHERE
          xact_start IS NOT NULL
      ORDER BY
          age(now(), xact_start) DESC;
      
      使用此查询可识别运行时间异常长的事务。
  3. 维护或实用工具操作 (例如 pg_repack)
    • pg_repack 这样的工具可能会重写整张表,在短时间内生成大量 WAL 数据。
    • 建议在流量较低的时段安排这类操作,或在其运行期间密切监控 WAL 使用情况。
  4. VACUUM 和 VACUUM ANALYZE
    • 虽然这些操作对数据库健康必不可少,但它们也会产生额外的 WAL 流量,尤其是在扫描大表时。
    • 可以考虑调整 autovacuum 参数,或将手动执行的 VACUUM 操作安排在低峰时段。
  5. 复制消费者未主动读取该 slot
    • 如果你的 CDC 管道 (例如 ClickPipes) 或其他复制消费者停止、暂停或崩溃,WAL 数据就会在 slot 中不断积累。
    • 请确保你的管道持续运行,并检查日志中是否存在连接或身份验证错误。
如果你想深入了解这个主题,推荐阅读我们的博客文章:Overcoming Pitfalls of Postgres Logical Decoding

Postgres 数据类型如何映射到 ClickHouse?

ClickPipes for Postgres 致力于在 ClickHouse 端尽可能以原生方式映射 Postgres 数据类型。本文档提供了各类数据类型及其映射关系的完整列表:Data Type Matrix

在将数据从 Postgres 复制到 ClickHouse 时,我可以自定义数据类型映射吗?

目前,我们还不支持在管道中自定义数据类型映射。不过需要注意的是,ClickPipes 使用的默认数据类型映射与原生类型高度贴合。Postgres 中的大多数列类型都会尽可能复制为 ClickHouse 中对应的原生类型。例如,Postgres 中的整数数组类型会复制为 ClickHouse 中的整数数组类型。

Postgres 中的 JSON 和 JSONB 列是如何复制过来的?

JSON 和 JSONB 列会以 ClickHouse 中的 String 类型进行复制。由于 ClickHouse 原生支持 JSON 类型,因此在需要时,您可以基于 ClickPipes 表创建 materialized view 来进行转换。或者,也可以直接对 String 列使用 JSON 函数。我们正在积极开发一项功能,可将 JSON 和 JSONB 列直接复制为 ClickHouse 的 JSON 类型,预计会在几个月内推出。

当 mirror 暂停时,insert 会发生什么?

当你暂停 mirror 时,消息会在源端 Postgres 的 replication slot 中排队,从而确保它们会被缓冲,不会丢失。不过,暂停并恢复 mirror 会重新建立 connection,这可能需要一些时间,具体取决于源端情况。 在此过程中,sync (从 Postgres 拉取数据并将其流式传输到 ClickHouse 原始表) 和 normalize (从原始表到目标表) 操作都会中止。不过,它们会保留可靠恢复所需的状态。
  • 对于 sync,如果在中途被取消,Postgres 中的 confirmed_flush_lsn 不会前移,因此下一次 sync 会从与已中止任务相同的位置开始,从而确保数据一致性。
  • 对于 normalize,ReplacingMergeTree 的 insert 顺序会处理 deduplication。
总之,虽然 sync 和 normalize 进程在暂停期间会终止,但这样做是安全的,因为它们可以在不丢失数据、也不造成不一致的情况下恢复。

是否可以自动化创建 ClickPipe,或通过 API 或 CLI 创建?

也可以通过 OpenAPI 端点来创建和管理 Postgres ClickPipe。此功能目前处于 Beta 阶段,API 参考文档可在此处查看。我们也在积极开发 Terraform 支持,以便创建 Postgres ClickPipes。

如何加快初始加载?

你无法加快已经在运行的初始加载。不过,可以通过调整某些设置来优化后续的初始加载。默认情况下,系统使用 4 个并行线程,并将每个分区的快照行数设为 100,000。这些属于高级设置,通常已足以满足大多数使用场景。 对于 Postgres 13 及更低版本,CTID 范围扫描速度很慢,因此 ClickPipes 不会使用这种方式。我们会改为将整个表作为单个分区读取,这实际上会变成单线程 (因此会忽略“每个分区的行数”和“并行线程数”这两项设置) 。在这种情况下,如需加快初始加载,你可以增大 snapshot number of tables in parallel,或者为大表指定一个自定义且带索引的分区列。

设置复制时,应如何界定 publication 的范围?

你可以让 ClickPipes 管理 publication (需要额外权限) ,也可以自行创建。使用 ClickPipes 管理的 publication 时,当你编辑管道时,我们会自动处理表的新增和移除。如果选择自行管理,请谨慎界定 publication 的范围,只包含需要复制的表——纳入不必要的表会拖慢 Postgres 的 WAL 解码。 如果在 publication 中包含某张表,请确保该表具有主键或已设置 REPLICA IDENTITY FULL。如果某些表没有主键,为所有表创建 publication 会导致这些表上的 DELETE 和 UPDATE 操作失败。 要找出数据库中没有主键的表,可以使用以下查询:
SELECT table_schema, table_name
FROM information_schema.tables
WHERE
    (table_catalog, table_schema, table_name) NOT IN (
        SELECT table_catalog, table_schema, table_name
        FROM information_schema.table_constraints
        WHERE constraint_type = 'PRIMARY KEY') AND
    table_schema NOT IN ('information_schema', 'pg_catalog', 'pgq', 'londiste');
处理没有主键的表时,你有两种选择:
  1. 将没有主键的表排除在 ClickPipes 之外: 创建 publication 时仅包含带有主键的表:
    CREATE PUBLICATION clickpipes_publication FOR TABLE table_with_primary_key1, table_with_primary_key2, ...;
    
  2. 将没有主键的表纳入 ClickPipes: 如果你想纳入没有主键的表,需要将其副本标识更改为 FULL。这样可确保 UPDATE 和 DELETE 操作正常进行:
    ALTER TABLE table_without_primary_key1 REPLICA IDENTITY FULL;
    ALTER TABLE table_without_primary_key2 REPLICA IDENTITY FULL;
    CREATE PUBLICATION clickpipes_publication FOR TABLE <...>, <...>;
    
如果你是手动创建 publication,而不是让 ClickPipes 自动管理,我们不建议创建 FOR ALL TABLES 的 publication,因为这会增加从 Postgres 到 ClickPipes 的流量 (会发送管道中未包含的其他表的变更) ,并降低整体效率。对于手动创建的 publication,请先将你希望包含的表添加到 publication 中,再将它们添加到管道中。
如果你是从 Postgres 只读副本/热备库进行复制,则需要自行在主实例上创建 publication,它会自动传播到备用实例。在这种情况下,ClickPipe 无法管理该 publication,因为你不能在备用实例上创建 publication。
  • 最低建议:max_slot_wal_keep_size 设置为至少保留 两天的 WAL 数据。
  • 对于大型数据库 (高事务量) : 至少保留相当于每日 WAL 峰值生成量 2-3 倍 的容量。
  • 对于存储受限的环境: 请谨慎调优该值,在确保复制稳定性的同时避免磁盘空间耗尽

如何计算合适的取值

要确定合适的设置值,请测量 WAL 生成速率:
对于 PostgreSQL 10 及以上版本
SELECT pg_wal_lsn_diff(pg_current_wal_insert_lsn(), '0/0') / 1024 / 1024 AS wal_generated_mb;
对于 PostgreSQL 9.6 及更低版本:
SELECT pg_xlog_location_diff(pg_current_xlog_insert_location(), '0/0') / 1024 / 1024 AS wal_generated_mb;
  • 在一天中的不同时间运行上述查询,尤其是在事务量较高的时段。
  • 计算每 24 小时产生的 WAL 量。
  • 将该数值乘以 2 或 3,以确保有足够的保留空间。
  • max_slot_wal_keep_size 设置为计算结果对应的 MB 或 GB 数值。
示例
如果你的数据库每天生成 100 GB WAL,请设置:
max_slot_wal_keep_size = 200GB

我在日志中看到 ReceiveMessage EOF 错误。这是什么意思?

ReceiveMessage 是 Postgres logical decoding 协议中的一个函数,用于从复制 stream 读取消息。EOF (文件结束) 错误表示,在尝试从复制 stream 读取数据时,与 Postgres server 的连接被意外关闭。 这是一个可恢复、完全非致命的错误。ClickPipes 会自动尝试重新连接并继续复制过程。 这可能由以下几种原因导致:
  • 网络问题: 临时性网络中断可能会导致连接断开。
  • Postgres server 重启: 如果 Postgres server 重启或崩溃,连接就会丢失。

我的 replication slot 已失效,该怎么办?

恢复 ClickPipe 的唯一方法是触发重新同步,你可以在“设置”页面中执行此操作。 replication slot 失效最常见的原因是 PostgreSQL 数据库中的 max_slot_wal_keep_size 设置过低 (例如仅有几 GB) 。我们建议增大该值。关于如何调优 max_slot_wal_keep_size,请参阅本节。理想情况下,应将其至少设置为 200GB,以避免 replication slot 失效。 在极少数情况下,我们发现即使未配置 max_slot_wal_keep_size,也会出现此问题。这可能是 PostgreSQL 中某个复杂且罕见的 bug 所致,但具体原因仍不明确。

当 ClickPipe 正在摄取数据时,我发现 ClickHouse 出现内存不足 (OOM) 。你们能帮忙吗?

ClickHouse 出现 OOM 的一个常见原因是你的服务规格过小。这意味着你当前的服务配置没有足够的资源 (例如内存或 CPU) 来有效处理摄取负载。我们强烈建议对服务进行扩容,以满足 ClickPipe 数据摄取的需求。 我们观察到的另一个原因,是存在可能包含未优化 JOIN 的下游 materialized views:
  • 一种常见的 JOIN 优化技巧是:如果你使用了 LEFT JOIN,且右侧表非常大,那么可以将查询改写为 RIGHT JOIN,并把更大的表移到左侧。这样可以让查询规划器在内存使用上更高效。
  • 另一种 JOIN 优化方法是,先通过 subqueriesCTEs 显式过滤这些表,再在这些子查询之间执行 JOIN。这能为规划器提供提示,从而更高效地过滤行并执行 JOIN

在初始加载期间看到 invalid snapshot identifier 错误,该怎么办?

当 ClickPipes 与您的 Postgres 数据库之间的连接中断时,就会出现 invalid snapshot identifier 错误。这可能是由网关超时、数据库重启或其他暂时性问题导致的。 建议您在初始加载过程中,不要对 Postgres 数据库执行升级、重启等可能造成干扰的操作,并确保与数据库之间的网络连接稳定。 要解决此问题,您可以在 ClickPipes UI 中触发重新同步。这会从头开始重新执行初始加载过程。

如果我在 Postgres 中删除了 publication,会发生什么?

在 Postgres 中删除 publication 会导致你的 ClickPipe 连接中断,因为 ClickPipe 需要依赖该 publication 从源端拉取变更。发生这种情况时,你通常会收到一条错误警报,提示该 publication 已不存在。 要在删除 publication 后恢复 ClickPipe:
  1. 在 Postgres 中重新创建一个同名且包含所需表的 publication
  2. 点击 ClickPipe 的 Settings 选项卡中的 ‘Resync tables’ 按钮
之所以必须执行这次重新同步,是因为重新创建的 publication 即使名称相同,在 Postgres 中也会拥有不同的对象标识符 (OID) 。重新同步过程会刷新你的目标端表并恢复连接。 或者,如果你愿意,也可以直接新建一个管道。 请注意,如果你处理的是分区表,请务必使用适当的设置来创建 publication:
CREATE PUBLICATION clickpipes_publication
FOR TABLE <...>, <...>
WITH (publish_via_partition_root = true);

如果我看到 Unexpected Datatype 错误或 Cannot parse type XX ...

当源 Postgres 数据库中存在某种在摄取过程中无法映射的数据类型时,通常会出现此错误。 如需进一步排查,请参阅下面几种可能的情况。

在复制/slot 创建期间出现类似 invalid memory alloc request size <XXX> 的错误

Postgres 的 17.5/16.9/15.13/14.18/13.21 补丁版本中引入了一个缺陷,某些工作负载可能会导致内存使用量呈指数级增长,进而触发一个超过 1GB 的内存分配请求,而 Postgres 会将其视为无效。该缺陷已修复,并将在下一个 Postgres 补丁系列 (17.6…) 中发布。请向你的 Postgres 提供商确认该补丁版本何时可供升级。如果暂时无法立即升级,则在管道触发此错误时,需要对其执行重新同步。

我需要在 ClickHouse 中保留完整的历史记录,即使数据已从源 Postgres 数据库中删除也是如此。我可以在 ClickPipes 中完全忽略来自 Postgres 的 DELETE 和 TRUNCATE 操作吗?

可以!在创建 Postgres ClickPipe 之前,请先创建一个不包含 DELETE 操作的 publication。例如:
CREATE PUBLICATION <pub_name> FOR TABLES IN SCHEMA <schema_name> WITH (publish = 'insert,update');
然后,在为你的 Postgres ClickPipe 进行设置时,请确保选择了此 publication 名称。 请注意,ClickPipes 会忽略 TRUNCATE 操作,因此这些操作不会复制到 ClickHouse。

为什么我的表名里有点号就无法复制?

PeerDB 目前有一个限制:如果 source table 标识符中包含点号——也就是 schema 名称或表名称里带有点号——则不支持复制。因为 PeerDB 会按点号拆分,在这种情况下无法判断哪部分是 schema、哪部分是表。 目前正在尝试通过支持分别输入 schema 和表来规避这一限制。

初始加载已完成,但 ClickHouse 中没有数据或数据缺失。可能是什么问题?

如果初始加载已完成且没有报错,但您的目标端 ClickHouse 表中仍有数据缺失,可能是因为源 Postgres 表启用了 RLS (行级安全) 策略。 还建议检查:
  • 该用户是否具有读取源表的足够权限。
  • ClickHouse 端是否存在可能过滤掉某些行的行策略。

我可以让 ClickPipe 创建启用了故障转移的 replication slot 吗?

可以。对于复制模式为 CDC 或 Snapshot + CDC 的 Postgres ClickPipe,你可以在创建 ClickPipe 时,在 Advanced Settings 部分打开下方开关,让 ClickPipes 创建启用了故障转移的 replication slot。请注意,使用此功能要求 Postgres 版本为 17 或更高。 如果来源端已完成相应配置,那么在故障转移到 Postgres 只读副本后,该 slot 仍会被保留,从而确保数据复制持续进行。更多信息请参见这里

我遇到了类似 Internal error encountered during logical decoding of aborted sub-transaction 的错误

此错误表明,在对已中止的子事务进行 logical decoding 时出现了暂时性问题,而且这是 Aurora Postgres 自定义实现特有的问题。鉴于错误来自 ReorderBufferPreserveLastSpilledSnapshot routine,这说明 logical decoding 无法读取已落盘的快照。可以尝试将 logical_decoding_work_mem 调高一些。

我在 CDC 复制期间看到诸如 error converting new tuple to maperror parsing logical message 之类的错误

Postgres 会按照固定协议,以消息形式发送变更信息。当 ClickPipe 收到无法解析的消息时,就会出现这类错误,原因可能是传输过程中发生损坏,或发送了无效消息。虽然具体原因各不相同,但我们已经在一些 Neon Postgres 来源中见过多种类似情况。如果你在使用 Neon 时也遇到了这个问题,请向他们提交支持工单。其他情况下,请联系他们的支持团队以获取指导。

我可以纳入最初在复制时排除的列吗?

目前还不支持此功能。另一种做法是对你想纳入这些列的表重新同步

我注意到我的 ClickPipe 已进入 Snapshot,但数据没有流入,可能是什么原因?

这可能由多种原因导致,主要是执行快照所需的某些前置条件比平时花费更长时间。更多信息,请参阅我们关于并行快照的文档:见此处

并行快照获取分区耗时较长

并行快照在开始时需要经过几个步骤,以获取表的逻辑分区。如果你的表较小,这一过程通常几秒钟即可完成;但对于非常大的表 (TB 级别) ,则可能需要更长时间。你可以在 Source 选项卡中监控 Postgres 源上正在运行的查询,查看是否有与快照获取分区相关的长时间运行查询。分区获取完成后,数据就会开始流入。

Replication slot 创建被事务锁住

在 Activity 部分下的 Source 选项卡中,你会看到 CREATE_REPLICATION_SLOT 查询卡在 Lock 状态。这可能是因为另一个事务持有了 Postgres 在创建 replication slot 时使用的对象锁。 要查看造成阻塞的查询,你可以在 Postgres 源上运行以下查询:
SELECT
  blocked.pid AS blocked_pid,
  blocked.query AS blocked_query,
  blocking.pid AS blocking_pid,
  blocking.query AS blocking_query,
  blocking.state AS blocking_state
FROM pg_locks blocked_lock
JOIN pg_stat_activity blocked
  ON blocked_lock.pid = blocked.pid
JOIN pg_locks blocking_lock
  ON blocking_lock.locktype = blocked_lock.locktype
  AND blocking_lock.database IS NOT DISTINCT FROM blocked_lock.database
  AND blocking_lock.relation IS NOT DISTINCT FROM blocked_lock.relation
  AND blocking_lock.page IS NOT DISTINCT FROM blocked_lock.page
  AND blocking_lock.tuple IS NOT DISTINCT FROM blocked_lock.tuple
  AND blocking_lock.virtualxid IS NOT DISTINCT FROM blocked_lock.virtualxid
  AND blocking_lock.transactionid IS NOT DISTINCT FROM blocked_lock.transactionid
  AND blocking_lock.classid IS NOT DISTINCT FROM blocked_lock.classid
  AND blocking_lock.objid IS NOT DISTINCT FROM blocked_lock.objid
  AND blocking_lock.objsubid IS NOT DISTINCT FROM blocked_lock.objsubid
  AND blocking_lock.pid != blocked_lock.pid
JOIN pg_stat_activity blocking
  ON blocking_lock.pid = blocking.pid
WHERE NOT blocked_lock.granted;
一旦定位到阻塞查询,你可以选择等待其完成;如果它不重要,也可以将其取消。阻塞查询解除后,replication slot 的创建应会继续,这样 snapshot 就能开始,数据也会流入。
最后修改于 2026年6月10日