暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

逻辑复制发布中的列列表-此有用的PostgreSQL功能概述

原创 eternity 2022-10-12
370

PostgreSQL 15引入了一个新功能,允许在发布中指定列列表,以限制复制的数据量。让我们看看此功能的优点以及如何使用它。

在这篇博客文章中,我将简要介绍这个新的PostgreSQL15特性发布列列表。

用户可能选择定义逻辑复制列列表有几个原因,例如减少网络流量、仅复制相关数据,以及通过省略敏感数据的复制作为一种安全形式。

在开始之前

通常,当使用逻辑复制PUB/SUB时,已发布表中的所有数据更改都将复制到适当的订户。使用新的列列表功能,用户现在可以限制复制,以便只复制指定列中的数据。

功能概述

在CREATE PUBLICATION时,可以选择为每个表指定列列表。列列表可以在表名后指定,并用括号括起来。每个发布可能有零个或多个列列表。

如果指定了列列表,则只复制指定列中的数据,列表顺序并不重要。

如果未指定列列表,则通过此发布复制表的所有列,包括稍后添加的所有列。这意味着命名所有列的列列表与根本没有列列表并不完全相同。例如,如果向表中添加了其他列,那么(在REFRESH PUBLICATION之后)如果存在列列表,则只会继续复制那些命名列。

列列表对TRUNCATE命令没有影响。

修改了CREATE/ALTER PUBLICATION语法

以下是简化的CREATE/ALTER PUBLICATION语法,突出显示了为PostgreSQL 15添加的新列列表子句:

CREATE PUBLICATION <pub-name> FOR TABLE <table-name> [(column-list)]
ALTER  PUBLICATION <pub-name> ADD TABLE <table-name> [(column-list)]
ALTER  PUBLICATION <pub-name> SET TABLE <table-name> [(column-list)]

<column-list> ::= <column-list-item> [,<column-list>]
<column-list-item> ::= <column-name>
复制

列列表子句

此子句允许指定列列表。要发布UPDATE或DELETE操作,任何列列表都必须包含REPLICA IDENTITY列。此外,如果表使用REPLICA IDENTITY FULL,则不允许指定列列表(这将导致UPDATE或DELETE操作的发布错误)。如果发布仅发布INSERT操作,则可以在列表中指定任何列。

示例:

CREATE PUBLICATION salary_information FOR TABLE employee (user_id, name, salary);
复制
CREATE PUBLICATION company_address FOR TABLE company (company_id, company_name, address);
复制

应用列列表

在发布者决定发布更改之前应用列列表。发布者将跳过复制列列表中未指定的列。

注意:如果同一个表是用不同的列列表发布的,则订阅无法订阅多个发布。例如,如果我们有发布员工表的user_id、name和salary列的发布pub1,以及发布员工表user_id和email_id列的另一个发布pub2,那么我们不能订阅pub1和pub2发布,因为列列表不同。

示例1
image.png

在订户节点上,创建一个学生表,该表现在只需要发布者表学生上的列的子集。我们可以看到订户表没有dob、course_id和photo列。

当用户选择使用(默认)copy_data=true订阅参数时,只有列列表中包含的列才会复制到订阅服务器。

psql命令的增强功能

作为这个新特性的一部分,PostgreSQL 15 psql命令也进行了修改,以提供关于列列表的有用信息。

显示表命令(\d)现在显示为该表所属发布指定的列列表。显示发布命令(\dRp+)现在显示为表指定的列列表。

实例

postgres=# CREATE TABLE employee (emp_no INTEGER NOT NULL, name VARCHAR, 
postgres(#                        phone VARCHAR, email VARCHAR, 
postgres(#                        address VARCHAR, dept_no INTEGER,
postgres(#                        birthday DATE, salary INTEGER);
CREATE TABLE
postgres=# CREATE TABLE department (dept_no INTEGER NOT NULL, dept_name VARCHAR,
postgres(#                          mgr_no INT, location VARCHAR);
CREATE TABLE
postgres=# CREATE PUBLICATION pub_emp FOR TABLE employee;
CREATE PUBLICATION
-- Publication can be altered to include another table with specified columns.
postgres=# ALTER PUBLICATION pub_emp ADD TABLE department (dept_no, dept_name);
ALTER PUBLICATION
postgres=# CREATE PUBLICATION pub_emp_birthday FOR TABLE employee (emp_no, birthday);
CREATE PUBLICATION
postgres=# CREATE PUBLICATION pub_emp_email FOR TABLE employee (emp_no, email);
CREATE PUBLICATION
postgres=# \d employee 
                    Table "public.employee"
  Column  |      Type         | Collation | Nullable | Default 
----------+-------------------+-----------+----------+---------
 emp_no   | integer           |           | not null | 
 name     | character varying |           |          | 
 phone    | character varying |           |          | 
 email    | character varying |           |          | 
 address  | character varying |           |          | 
 dept_no  | integer           |           |          | 
 birthday | date              |           |          | 
 salary   | integer           |           |          | 
Publications:
    "pub_emp"
    "pub_emp_birthday" (emp_no, birthday)
    "pub_emp_email" (emp_no, email)
postgres=# \dRp+
                             Publication pub_emp
  Owner  | All tables | Inserts | Updates | Deletes | Truncates | Via root 
---------+------------+---------+---------+---------+-----------+----------
 vignesh | f          | t       | t       | t       | t         | f
Tables:
    "public.department" (dept_no, dept_name)
    "public.employee"

                     Publication pub_emp_birthday
  Owner  | All tables | Inserts | Updates | Deletes | Truncates | Via root 
---------+------------+---------+---------+---------+-----------+----------
 vignesh | f          | t       | t       | t       | t         | f
Tables:
    "public.employee" (emp_no, birthday)

                         Publication pub_emp_email
  Owner  | All tables | Inserts | Updates | Deletes | Truncates | Via root 
---------+------------+---------+---------+---------+-----------+----------
 vignesh | f          | t       | t       | t       | t         | f
Tables:
    "public.employee" (emp_no, email)
postgres=#
复制

影响

用户可以选择定义逻辑复制列列表的原因有几个:

  • 通过仅复制大型数据表的一小部分(而不是复制映像)来减少网络流量(提高性能)。

例子:

CREATE PUBLICATION pub_data_staff_email
FOR TABLE staff (name, email, dept_id, salary);
复制
  • 仅提供与订户节点相关的数据。

例子:

CREATE PUBLICATION pub_data_city_population
FOR TABLE city (name, population);
复制
  • 通过隐藏敏感信息(而不是复制卡号)作为一种安全形式。

例子:

CREATE PUBLICATION pub_data_customer_investment
FOR TABLE customer_account (name, phone, investment);
复制

为了未来

添加列列表是PostgreSQL 15逻辑复制的主要功能。此功能为逻辑复制增加了更多灵活性。富士通OSS团队和社区将继续帮助增强和添加PostgreSQL逻辑复制的更多功能。

在哪里可以找到更多信息

  • CREATE PUBLICATION的PostgreSQL文档页面描述了新的列列表:

https://www.postgresql.org/docs/15/sql-createpublication.html

  • 描述列列表的PostgreSQL文档页面:

https://www.postgresql.org/docs/devel/logical-replication-col-lists.html

  • 描述副本标识的PostgreSQL文档页面:

https://www.postgresql.org/docs/15/logical-replication-publication.html
https://www.postgresql.org/docs/15/sql-altertable.html#SQL-ALTERTABLE-REPLICA-IDENTITY

  • PostgreSQL GitHub源代码主修补程序负责添加新的列列表功能:

https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=923def9a533a7d986acfb524139d8b9e5466d0a5

原文标题:Column lists in logical replication publications - an overview of this useful PostgreSQL feature
原文作者:Vigneshwaran C
原文链接:https://www.postgresql.fastware.com/blog/column-lists-in-logical-replication-publications

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论