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
在订户节点上,创建一个学生表,该表现在只需要发布者表学生上的列的子集。我们可以看到订户表没有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