每個發布都可選擇性地指定每個資料表中要複寫到訂閱者的欄位。訂閱者端的資料表必須至少包含所有已發布的欄位。如果未指定欄位清單,則會複寫發布者上的所有欄位。有關語法的詳細資訊,請參閱CREATE PUBLICATION。
欄位的選擇可以基於行為或效能原因。但是,不要依賴此功能來確保安全性:惡意訂閱者能夠從未特別發布的欄位中獲取資料。如果考慮到安全性,則可以在發布者端應用保護措施。
如果未指定欄位清單,則稍後新增到資料表的任何欄位都會自動複寫。這表示擁有包含所有欄位的欄位清單與根本沒有欄位清單不同。
欄位清單只能包含簡單的欄位參照。清單中欄位的順序不會保留。
不支援在發布也發布FOR TABLES IN SCHEMA
時指定欄位清單。
對於分割資料表,發布參數publish_via_partition_root
決定使用哪個欄位清單。如果publish_via_partition_root
為true
,則使用根分割資料表的欄位清單。否則,如果publish_via_partition_root
為false
(預設值),則使用每個分割區的欄位清單。
如果發布發布UPDATE
或DELETE
操作,則任何欄位清單都必須包含資料表的複本身分欄位(請參閱REPLICA IDENTITY
)。如果發布僅發布INSERT
操作,則欄位清單可以省略複本身分欄位。
欄位清單對TRUNCATE
指令沒有影響。
在初始資料同步期間,僅複製已發布的欄位。但是,如果訂閱者來自 15 之前的版本,則在初始資料同步期間會複製資料表中的所有欄位,忽略任何欄位清單。
目前不支援包含多個發布的訂閱,其中同一個資料表已使用不同的欄位清單發布。CREATE SUBSCRIPTION不允許建立此類訂閱,但在建立訂閱後,透過在發布端新增或更改欄位清單,仍然有可能進入這種情況。
這表示更改已訂閱的發布上的資料表的欄位清單可能會導致在訂閱者端擲出錯誤。
如果訂閱受到此問題的影響,恢復複寫的唯一方法是調整發布端的一個欄位清單,使其全部匹配;然後重新建立訂閱,或使用ALTER SUBSCRIPTION ... DROP PUBLICATION
移除其中一個違規發布並重新新增它。
建立一個資料表t1
,用於以下範例。
test_pub=# CREATE TABLE t1(id int, a text, b text, c text, d text, e text, PRIMARY KEY(id)); CREATE TABLE
建立發布p1
。為資料表t1
定義一個欄位清單,以減少要複寫的欄位數量。請注意,欄位清單中欄位名稱的順序無關緊要。
test_pub=# CREATE PUBLICATION p1 FOR TABLE t1 (id, b, a, d); CREATE PUBLICATION
psql
可用於顯示每個發布的欄位清單(如果已定義)。
test_pub=# \dRp+ Publication p1 Owner | All tables | Inserts | Updates | Deletes | Truncates | Via root ----------+------------+---------+---------+---------+-----------+---------- postgres | f | t | t | t | t | f Tables: "public.t1" (id, a, b, d)
psql
可用於顯示每個資料表的欄位清單(如果已定義)。
test_pub=# \d t1 Table "public.t1" Column | Type | Collation | Nullable | Default --------+---------+-----------+----------+--------- id | integer | | not null | a | text | | | b | text | | | c | text | | | d | text | | | e | text | | | Indexes: "t1_pkey" PRIMARY KEY, btree (id) Publications: "p1" (id, a, b, d)
在訂閱者節點上,建立一個資料表t1
,現在只需要發布者資料表t1
上的欄位的子集,並建立訂閱s1
,該訂閱訂閱發布p1
。
test_sub=# CREATE TABLE t1(id int, b text, a text, d text, PRIMARY KEY(id)); CREATE TABLE test_sub=# CREATE SUBSCRIPTION s1 test_sub-# CONNECTION 'host=localhost dbname=test_pub application_name=s1' test_sub-# PUBLICATION p1; CREATE SUBSCRIPTION
在發布者節點上,將一些資料列插入資料表t1
。
test_pub=# INSERT INTO t1 VALUES(1, 'a-1', 'b-1', 'c-1', 'd-1', 'e-1'); INSERT 0 1 test_pub=# INSERT INTO t1 VALUES(2, 'a-2', 'b-2', 'c-2', 'd-2', 'e-2'); INSERT 0 1 test_pub=# INSERT INTO t1 VALUES(3, 'a-3', 'b-3', 'c-3', 'd-3', 'e-3'); INSERT 0 1 test_pub=# SELECT * FROM t1 ORDER BY id; id | a | b | c | d | e ----+-----+-----+-----+-----+----- 1 | a-1 | b-1 | c-1 | d-1 | e-1 2 | a-2 | b-2 | c-2 | d-2 | e-2 3 | a-3 | b-3 | c-3 | d-3 | e-3 (3 rows)
僅複寫發布p1
的欄位清單中的資料。
test_sub=# SELECT * FROM t1 ORDER BY id; id | b | a | d ----+-----+-----+----- 1 | b-1 | a-1 | d-1 2 | b-2 | a-2 | d-2 3 | b-3 | a-3 | d-3 (3 rows)
如果您在文件中發現任何不正確、與特定功能的體驗不符或需要進一步澄清的地方,請使用此表格報告文件問題。