事务回滚会同步到 ClickHouse 吗?
我可以让数据在 ClickHouse 中的保留时间比源 Postgres 更长吗?
当数据从 Postgres 流向 ClickHouse 时,如何进行富集?
我可以将多个 Postgres 实例复制到一个或多个 ClickHouse 服务吗?
空闲会如何影响我的 Postgres CDC ClickPipe?
ClickPipes for Postgres 如何处理 TOAST 列?
ClickPipes for Postgres 如何处理生成列?
表要作为 Postgres CDC 的一部分,是否必须有主键?
- 主键:最直接的方法是在表上定义主键。主键可为每一行提供唯一标识,这对于跟踪更新和删除至关重要。在这种情况下,可以将 REPLICA IDENTITY 设为
DEFAULT(默认行为) 。 - 副本标识:如果表没有主键,也可以设置副本标识。副本标识可设为
FULL,表示使用整行来标识变更。或者,如果表上存在唯一索引,也可以将其设为使用该索引,然后将 REPLICA IDENTITY 设为USING INDEX index_name。 要将副本标识设为 FULL,可以使用以下 SQL 命令:
REPLICA IDENTITY FULL 还支持复制未发生变化的 TOAST 列。更多信息请参见此处。
请注意,使用 REPLICA IDENTITY FULL 可能会影响性能,并导致 WAL 增长更快,尤其是对于没有主键且频繁更新或删除的表,因为它需要为每次变更记录更多数据。如果你对为表设置主键或副本标识有任何疑问,或需要相关帮助,请联系我们的支持团队获取指导。
还需注意,如果既未定义主键,也未定义副本标识,ClickPipes 将无法复制该表的变更,并且你可能会在复制过程中遇到错误。因此,建议你在设置 ClickPipe 之前检查表 schema,并确保其满足这些要求。
是否支持 Postgres CDC 中的分区表?
我可以连接没有公网 IP 或位于私有网络中的 Postgres 数据库吗?
如何处理 UPDATE 和 DELETE?
_peerdb_ 版本列) 。ReplacingMergeTree 表引擎会基于排序键 (ORDER BY 列) 定期在后台执行去重,仅保留 _peerdb_ 版本最新的那一行。
来自 Postgres 的 DELETE 会以标记为已删除的新行形式同步过来 (使用 _peerdb_is_deleted 列) 。由于去重过程是异步的,你可能会暂时看到重复数据。为此,你需要在查询层处理去重。
另请注意,默认情况下,Postgres 在执行 DELETE 操作时,不会发送不属于主键或副本标识的列值。如果你希望在 DELETE 时捕获完整的行数据,可以将 REPLICA IDENTITY 设置为 FULL。
更多详情,请参阅:
我可以在 PostgreSQL 中更新主键列吗?
是否支持 schema 变更?
ClickPipes for Postgres CDC 的费用是多少?
我的 replication slot 大小持续增长或迟迟不下降;可能是什么问题?
-
数据库活动突然激增
- 大批量更新、批量插入或重大的 schema 变更,都可能在短时间内生成大量 WAL 数据。
- replication slot 会一直保留这些 WAL 记录,直到它们被消费,因此会导致大小暂时激增。
-
长时间运行的事务
- 一个未结束的事务会迫使 Postgres 保留自该事务开始以来生成的所有 WAL 分段,这可能会显著增大 slot 的大小。
- 将
statement_timeout和idle_in_transaction_session_timeout设置为合理的值,以防止事务无限期保持开启状态:使用此查询可识别运行时间异常长的事务。
-
维护或实用工具操作 (例如
pg_repack)- 像
pg_repack这样的工具可能会重写整张表,在短时间内生成大量 WAL 数据。 - 建议在流量较低的时段安排这类操作,或在其运行期间密切监控 WAL 使用情况。
- 像
-
VACUUM 和 VACUUM ANALYZE
- 虽然这些操作对数据库健康必不可少,但它们也会产生额外的 WAL 流量,尤其是在扫描大表时。
- 可以考虑调整 autovacuum 参数,或将手动执行的 VACUUM 操作安排在低峰时段。
-
复制消费者未主动读取该 slot
- 如果你的 CDC 管道 (例如 ClickPipes) 或其他复制消费者停止、暂停或崩溃,WAL 数据就会在 slot 中不断积累。
- 请确保你的管道持续运行,并检查日志中是否存在连接或身份验证错误。
Postgres 数据类型如何映射到 ClickHouse?
在将数据从 Postgres 复制到 ClickHouse 时,我可以自定义数据类型映射吗?
如何从 Postgres 复制 json 和 jsonb 列?
json 和 jsonb 列在 ClickHouse 中会以 String 类型复制。例如:
- PostgreSQL 允许顶层为任何有效的 JSON 值 (字符串、数字、数组) ,而 ClickHouse 的 JSON 类型仅支持对象。
- 包含点号的键 (例如
"app.kubernetes.io/name") 也会被 ClickHouse 的 JSON 类型解释为嵌套路径,这可能会改变数据结构。
当 mirror 暂停时,insert 会发生什么?
- 对于 sync,如果在中途被取消,Postgres 中的 confirmed_flush_lsn 不会前移,因此下一次 sync 会从与已中止任务相同的位置开始,从而确保数据一致性。
- 对于 normalize,ReplacingMergeTree 的 insert 顺序会处理 deduplication。
是否可以自动化创建 ClickPipe,或通过 API 或 CLI 创建?
如何加快初始加载?
snapshot number of tables in parallel,或者为大表指定一个自定义且带索引的分区列。
设置复制时,应如何界定 publication 的范围?
REPLICA IDENTITY FULL。如果某些表没有主键,为所有表创建 publication 会导致这些表上的 DELETE 和 UPDATE 操作失败。
要找出数据库中没有主键的表,可以使用以下查询:
-
将没有主键的表排除在 ClickPipes 之外:
创建 publication 时仅包含带有主键的表:
-
将没有主键的表纳入 ClickPipes:
如果你想纳入没有主键的表,需要将其副本标识更改为
FULL。这样可确保 UPDATE 和 DELETE 操作正常进行:
推荐的 max_slot_wal_keep_size 设置
- 最低建议: 将
max_slot_wal_keep_size设置为至少保留 两天的 WAL 数据。 - 对于大型数据库 (高事务量) : 至少保留相当于每日 WAL 峰值生成量 2-3 倍 的容量。
- 对于存储受限的环境: 请谨慎调优该值,在确保复制稳定性的同时避免磁盘空间耗尽。
如何计算合适的取值
对于 PostgreSQL 10 及以上版本
对于 PostgreSQL 9.6 及更低版本:
- 在一天中的不同时间运行上述查询,尤其是在事务量较高的时段。
- 计算每 24 小时产生的 WAL 量。
- 将该数值乘以 2 或 3,以确保有足够的保留空间。
- 将
max_slot_wal_keep_size设置为计算结果对应的 MB 或 GB 数值。
示例
我在日志中看到 ReceiveMessage EOF 错误。这是什么意思?
ReceiveMessage 是 Postgres logical decoding 协议中的一个函数,用于从复制 stream 读取消息。EOF (文件结束) 错误表示,在尝试从复制 stream 读取数据时,与 Postgres server 的连接被意外关闭。
这是一个可恢复、完全非致命的错误。ClickPipes 会自动尝试重新连接并继续复制过程。
这可能由以下几种原因导致:
- 网络问题: 临时性网络中断可能会导致连接断开。
- Postgres server 重启: 如果 Postgres server 重启或崩溃,连接就会丢失。
我的 replication slot 已失效,该怎么办?
max_slot_wal_keep_size 设置过低 (例如仅有几 GB) 。我们建议增大该值。关于如何调优 max_slot_wal_keep_size,请参阅本节。理想情况下,应将其至少设置为 200GB,以避免 replication slot 失效。
在极少数情况下,我们发现即使未配置 max_slot_wal_keep_size,也会出现此问题。这可能是 PostgreSQL 中某个复杂且罕见的 bug 所致,但具体原因仍不明确。
当 ClickPipe 正在摄取数据时,我发现 ClickHouse 出现内存不足 (OOM) 。你们能帮忙吗?
-
一种常见的
JOIN优化技巧是:如果你使用了LEFT JOIN,且右侧表非常大,那么可以将查询改写为RIGHT JOIN,并把更大的表移到左侧。这样可以让查询规划器在内存使用上更高效。 -
另一种
JOIN优化方法是,先通过subqueries或CTEs显式过滤这些表,再在这些子查询之间执行JOIN。这能为规划器提供提示,从而更高效地过滤行并执行JOIN。
在初始加载期间看到 invalid snapshot identifier 错误,该怎么办?
invalid snapshot identifier 错误。这可能是由网关超时、数据库重启或其他暂时性问题导致的。
建议您在初始加载过程中,不要对 Postgres 数据库执行升级、重启等可能造成干扰的操作,并确保与数据库之间的网络连接稳定。
要解决此问题,您可以在 ClickPipes UI 中触发重新同步。这会从头开始重新执行初始加载过程。
如果我在 Postgres 中删除了 publication,会发生什么?
- 在 Postgres 中重新创建一个同名且包含所需表的 publication
- 点击 ClickPipe 的 Settings 选项卡中的 ‘Resync tables’ 按钮
如果我看到 Unexpected Datatype 错误或 Cannot parse type XX ...
在复制/slot 创建期间出现类似 invalid memory alloc request size <XXX> 的错误
我需要在 ClickHouse 中保留完整的历史记录,即使数据已从源 Postgres 数据库中删除也是如此。我可以在 ClickPipes 中完全忽略来自 Postgres 的 DELETE 和 TRUNCATE 操作吗?
为什么我的表名里有点号就无法复制?
初始加载已完成,但 ClickHouse 中没有数据或数据缺失。可能是什么问题?
- 该用户是否具有读取源表的足够权限。
- ClickHouse 端是否存在可能过滤掉某些行的行策略。
我可以让 ClickPipe 创建启用了故障转移的 replication slot 吗?
Advanced Settings 部分打开下方开关,让 ClickPipes 创建启用了故障转移的 replication slot。请注意,使用此功能要求 Postgres 版本为 17 或更高。
如果来源端已完成相应配置,那么在故障转移到 Postgres 只读副本后,该 slot 仍会被保留,从而确保数据复制持续进行。更多信息请参见这里。
我遇到了类似 Internal error encountered during logical decoding of aborted sub-transaction 的错误
ReorderBufferPreserveLastSpilledSnapshot routine,这说明 logical decoding 无法读取已落盘的快照。可以尝试将 logical_decoding_work_mem 调高一些。
我在 CDC 复制期间看到诸如 error converting new tuple to map 或 error parsing logical message 之类的错误
我可以纳入最初在复制时排除的列吗?
我注意到我的 ClickPipe 已进入 Snapshot,但数据没有流入,可能是什么原因?
并行快照获取分区耗时较长
Replication slot 创建被事务锁住
CREATE_REPLICATION_SLOT 查询卡在 Lock 状态。这可能是因为另一个事务持有了 Postgres 在创建 replication slot 时使用的对象锁。
要查看造成阻塞的查询,你可以在 Postgres 源上运行以下查询: