2025年9月25日: PostgreSQL 18 发布!
支持的版本: 当前 (18)
开发版本: 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 列。

但是,有时将生成列复制到常规列可能是有益的。

提示

当通过输出插件将数据复制到非 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 版本之前的版本,那么即使生成列在发布者中定义,初始表同步也不会复制生成列。

提交更正

如果您在文档中看到任何不正确、与您对特定功能的体验不符或需要进一步澄清的内容,请使用此表单来报告文档问题。