ClickPipes for Postgres:处理 TOAST 列
当从 PostgreSQL 复制数据到 ClickHouse 时,理解 TOAST(超尺寸属性存储技术)列的局限性和特殊注意事项非常重要。本指南将帮助您识别并正确处理复制过程中的 TOAST 列。
PostgreSQL 中的 TOAST 列是什么?
TOAST(超尺寸属性存储技术)是 PostgreSQL 用于处理大型字段值的机制。当一行数据超过最大行大小时(通常为 2KB,但这可能会因 PostgreSQL 版本和具体设置而异),PostgreSQL 会自动将大型字段值移动到单独的 TOAST 表中,仅在主表中存储一个指针。
重要的是要注意,在变更数据捕获 (CDC) 期间,未更改的 TOAST 列不会包含在复制流中。如果处理不当,这可能会导致不完整的数据复制。
在初始加载(快照)期间,所有列值(包括 TOAST 列)都将被正确复制,而与其大小无关。本指南中描述的限制主要影响初始加载之后的持续 CDC 过程。
您可以在此处阅读更多关于 TOAST 及其在 PostgreSQL 中的实现的信息:https://postgresql.ac.cn/docs/current/storage-toast.html
识别表中的 TOAST 列
要识别表是否具有 TOAST 列,您可以使用以下 SQL 查询
SELECT a.attname, pg_catalog.format_type(a.atttypid, a.atttypmod) as data_type
FROM pg_attribute a
JOIN pg_class c ON a.attrelid = c.oid
WHERE c.relname = 'your_table_name'
AND a.attlen = -1
AND a.attstorage != 'p'
AND a.attnum > 0;
此查询将返回可能被 TOAST 化的列的名称和数据类型。但是,重要的是要注意,此查询仅识别基于其数据类型和存储属性而符合 TOAST 存储条件的列。要确定这些列是否实际包含 TOAST 化数据,您需要考虑这些列中的值是否超过大小。数据的实际 TOAST 化取决于存储在这些列中的具体内容。
确保正确处理 TOAST 列
为了确保在复制期间正确处理 TOAST 列,您应该将表的 REPLICA IDENTITY
设置为 FULL
。这会告知 PostgreSQL 在 WAL 中包含 UPDATE 和 DELETE 操作的完整旧行,从而确保所有列值(包括 TOAST 列)都可用于复制。
您可以使用以下 SQL 命令将 REPLICA IDENTITY
设置为 FULL
ALTER TABLE your_table_name REPLICA IDENTITY FULL;
有关设置 REPLICA IDENTITY FULL
时的性能注意事项,请参阅这篇博客文章。
当未设置 REPLICA IDENTITY FULL 时的复制行为
如果未为具有 TOAST 列的表设置 REPLICA IDENTITY FULL
,则在复制到 ClickHouse 时,您可能会遇到以下问题
-
对于 INSERT 操作,所有列(包括 TOAST 列)都将正确复制。
-
对于 UPDATE 操作
- 如果未修改 TOAST 列,则其值在 ClickHouse 中将显示为 NULL 或空。
- 如果修改了 TOAST 列,则会正确复制。
-
对于 DELETE 操作,TOAST 列值在 ClickHouse 中将显示为 NULL 或空。
这些行为可能导致 PostgreSQL 源和 ClickHouse 目标之间的数据不一致。因此,对于具有 TOAST 列的表,至关重要的是设置 REPLICA IDENTITY FULL
,以确保准确和完整的数据复制。
结论
正确处理 TOAST 列对于在从 PostgreSQL 复制到 ClickHouse 时保持数据完整性至关重要。通过识别 TOAST 列并设置适当的 REPLICA IDENTITY
,您可以确保数据被准确且完整地复制。