通常,订阅者上的表会与发布者表定义相同,因此如果发布者表具有GENERATED 列
,则订阅者表也会有一个匹配的生成列。在这种情况下,始终使用订阅者表的生成列值。
例如,请注意下面订阅者表中的生成列值来自订阅者列的计算。
/* pub # */ CREATE TABLE tab_gen_to_gen (a int, b int GENERATED ALWAYS AS (a + 1) STORED); /* pub # */ INSERT INTO tab_gen_to_gen VALUES (1),(2),(3); /* pub # */ CREATE PUBLICATION pub1 FOR TABLE tab_gen_to_gen; /* pub # */ SELECT * FROM tab_gen_to_gen; a | b ---+--- 1 | 2 2 | 3 3 | 4 (3 rows) /* sub # */ CREATE TABLE tab_gen_to_gen (a int, b int GENERATED ALWAYS AS (a * 100) STORED); /* sub # */ CREATE SUBSCRIPTION sub1 CONNECTION 'dbname=test_pub' PUBLICATION pub1; /* sub # */ SELECT * from tab_gen_to_gen; a | b ---+---- 1 | 100 2 | 200 3 | 300 (3 rows)
事实上,在 18.0 版本之前,逻辑复制根本不发布 GENERATED
列。
但是,有时将生成列复制到常规列可能是有益的。
当通过输出插件将数据复制到非 PostgreSQL 数据库时,此功能可能很有用,尤其是在目标数据库不支持生成列的情况下。
生成列默认不发布,但用户可以选择像常规列一样发布存储的生成列。
有两种方法可以做到这一点:
将 PUBLICATION
参数 publish_generated_columns
设置为 stored
。这会指示 PostgreSQL 逻辑复制发布发布者表中当前和将来的存储的生成列。
指定表列列表,以明确指定将发布哪些存储的生成列。
在确定将发布哪些表列时,列列表具有优先权,会覆盖 publish_generated_columns
参数的效果。
下表总结了逻辑复制涉及生成列时的行为。结果显示了未启用发布生成列以及启用发布生成列时的情况。
表 29.2. 复制结果摘要
发布生成列? | 发布者表列 | 订阅者表列 | 结果 |
---|---|---|---|
否 | GENERATED | GENERATED | 发布者表列未复制。使用订阅者表的生成列值。 |
否 | GENERATED | regular | 发布者表列未复制。使用订阅者表常规列的默认值。 |
否 | GENERATED | --missing-- | 发布者表列未复制。无操作。 |
是 | GENERATED | GENERATED | 错误。不支持。 |
是 | GENERATED | regular | 发布者表列值已复制到订阅者表列。 |
是 | GENERATED | --missing-- | 错误。该列在订阅者表中被报告为缺失。 |
目前不支持包含多个发布者,其中同一个表被发布者具有不同的列列表。请参阅 第 29.5 节。
如果一个发布者正在发布生成列,而同一订阅中的另一个发布者没有为同一个表发布生成列,那么也会发生同样的情况。
如果订阅者来自 18 版本之前的版本,那么即使生成列在发布者中定义,初始表同步也不会复制生成列。
如果您在文档中看到任何不正确、与您对特定功能的体验不符或需要进一步澄清的内容,请使用此表单来报告文档问题。