受支持版本: 当前版本 (18) / 15
开发版本: devel

29.6. 生成列复制 #

通常,订阅端的表会与发布端表定义相同,因此如果发布端表包含 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 列。

但在某些场景中,将生成列复制到普通列是有意义的。

Tip

当通过输出插件将数据复制到非 PostgreSQL 数据库时,此特性可能很有用, 尤其是目标数据库不支持生成列时。

默认不会发布生成列,但用户可以选择像普通列一样发布存储生成列。

有两种方式:

  • PUBLICATION 参数 publish_generated_columns 设置为 stored。 这样 PostgreSQL 逻辑复制会发布该发布中各表当前及未来的存储生成列。

  • 指定表的 列列表, 显式指定要发布哪些存储生成列。

    Note

    在确定发布哪些表列时,列列表优先级更高,会覆盖 publish_generated_columns 参数的效果。

下表汇总了逻辑复制涉及生成列时的行为,分别展示未启用和启用发布生成列时的结果。

Table 29.2. 复制结果汇总

发布生成列? 发布端表列 订阅端表列 结果
GENERATED GENERATED 发布端该列不复制。使用订阅端表生成列的值。
GENERATED 普通列 发布端该列不复制。使用订阅端普通列默认值。
GENERATED --missing-- 发布端该列不复制。不会发生任何操作。
GENERATED GENERATED 错误。不支持。
GENERATED 普通列 发布端该列值会复制到订阅端表列。
GENERATED --missing-- 错误。该列会被报告为订阅端表缺失。

Warning

目前不支持一个订阅包含多个发布,且同一张表在这些发布中使用不同列列表。 见 Section 29.5

如果同一订阅中一个发布对该表发布生成列,而另一个发布不发布生成列, 也会出现同样的问题。

Note

如果订阅端版本早于 18,即使发布端定义了生成列,初始表同步也不会复制生成列。

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。