Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b4e0d0c

Browse files
author
Amit Kapila
committed
Fix a WARNING for data origin discrepancies.
Previously, a WARNING was issued at the time of defining a subscription with origin=NONE only when the publisher subscribed to the same table from other publishers, indicating potential data origination from different origins. However, the publisher can subscribe to the partition ancestors or partition children of the table from other publishers, which could also result in mixed-origin data inclusion. So, give a WARNING in those cases as well. Reported-by: Sergey Tatarintsev <s.tatarintsev@postgrespro.ru> Author: Hou Zhijie <houzj.fnst@fujitsu.com> Author: Shlok Kyal <shlok.kyal.oss@gmail.com> Reviewed-by: Vignesh C <vignesh21@gmail.com> Reviewed-by: Amit Kapila <amit.kapila16@gmail.com> Backpatch-through: 16, where it was introduced Discussion: https://postgr.es/m/5eda6a9c-63cf-404d-8a49-8dcb116a29f3@postgrespro.ru
1 parent 984410b commit b4e0d0c

File tree

3 files changed

+133
-14
lines changed

3 files changed

+133
-14
lines changed

doc/src/sgml/ref/create_subscription.sgml

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -534,12 +534,14 @@ CREATE SUBSCRIPTION <replaceable class="parameter">subscription_name</replaceabl
534534
<programlisting>
535535
# substitute &lt;pub-names&gt; below with your publication name(s) to be queried
536536
SELECT DISTINCT PT.schemaname, PT.tablename
537-
FROM pg_publication_tables PT,
537+
FROM pg_publication_tables PT
538+
JOIN pg_class C ON (C.relname = PT.tablename)
539+
JOIN pg_namespace N ON (N.nspname = PT.schemaname),
538540
pg_subscription_rel PS
539-
JOIN pg_class C ON (C.oid = PS.srrelid)
540-
JOIN pg_namespace N ON (N.oid = C.relnamespace)
541-
WHERE N.nspname = PT.schemaname AND
542-
C.relname = PT.tablename AND
541+
WHERE C.relnamespace = N.oid AND
542+
(PS.srrelid = C.oid OR
543+
C.oid IN (SELECT relid FROM pg_partition_ancestors(PS.srrelid) UNION
544+
SELECT relid FROM pg_partition_tree(PS.srrelid))) AND
543545
PT.pubname IN (&lt;pub-names&gt;);
544546
</programlisting></para>
545547

src/backend/commands/subscriptioncmds.c

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,11 +2083,12 @@ AlterSubscriptionOwner_oid(Oid subid, Oid newOwnerId)
20832083
}
20842084

20852085
/*
2086-
* Check and log a warning if the publisher has subscribed to the same table
2087-
* from some other publisher. This check is required only if "copy_data = true"
2088-
* and "origin = none" for CREATE SUBSCRIPTION and
2089-
* ALTER SUBSCRIPTION ... REFRESH statements to notify the user that data
2090-
* having origin might have been copied.
2086+
* Check and log a warning if the publisher has subscribed to the same table,
2087+
* its partition ancestors (if it's a partition), or its partition children (if
2088+
* it's a partitioned table), from some other publishers. This check is
2089+
* required only if "copy_data = true" and "origin = none" for CREATE
2090+
* SUBSCRIPTION and ALTER SUBSCRIPTION ... REFRESH statements to notify the
2091+
* user that data having origin might have been copied.
20912092
*
20922093
* This check need not be performed on the tables that are already added
20932094
* because incremental sync for those tables will happen through WAL and the
@@ -2117,7 +2118,9 @@ check_publications_origin(WalReceiverConn *wrconn, List *publications,
21172118
"SELECT DISTINCT P.pubname AS pubname\n"
21182119
"FROM pg_publication P,\n"
21192120
" LATERAL pg_get_publication_tables(P.pubname) GPT\n"
2120-
" JOIN pg_subscription_rel PS ON (GPT.relid = PS.srrelid),\n"
2121+
" JOIN pg_subscription_rel PS ON (GPT.relid = PS.srrelid OR"
2122+
" GPT.relid IN (SELECT relid FROM pg_partition_ancestors(PS.srrelid) UNION"
2123+
" SELECT relid FROM pg_partition_tree(PS.srrelid))),\n"
21212124
" pg_class C JOIN pg_namespace N ON (N.oid = C.relnamespace)\n"
21222125
"WHERE C.oid = GPT.relid AND P.pubname IN (");
21232126
GetPublicationsStr(publications, &cmd, true);

src/test/subscription/t/030_origin.pl

Lines changed: 117 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,9 +251,123 @@
251251
$node_B->wait_for_catchup($subname_AB2);
252252

253253
# clear the operations done by this test
254-
$node_A->safe_psql('postgres', "DROP TABLE tab_new");
255-
$node_B->safe_psql('postgres', "DROP TABLE tab_new");
256-
$node_A->safe_psql('postgres', "DROP SUBSCRIPTION $subname_AB2");
254+
$node_A->safe_psql(
255+
'postgres', qq(
256+
DROP TABLE tab_new;
257+
DROP SUBSCRIPTION $subname_AB2;
258+
DROP SUBSCRIPTION $subname_AB;
259+
DROP PUBLICATION tap_pub_A;
260+
));
261+
$node_B->safe_psql(
262+
'postgres', qq(
263+
DROP TABLE tab_new;
264+
DROP SUBSCRIPTION $subname_BA;
265+
DROP PUBLICATION tap_pub_B;
266+
));
267+
268+
###############################################################################
269+
# Specifying origin = NONE and copy_data = on must raise WARNING if we subscribe
270+
# to a partitioned table and this table contains any remotely originated data.
271+
#
272+
# node_B
273+
# __________________________
274+
# | tab_main | --------------> node_C (tab_main)
275+
# |__________________________|
276+
# | tab_part1 | tab_part2 | <-------------- node_A (tab_part2)
277+
# |____________|_____________|
278+
# | tab_part2_1 |
279+
# |_____________|
280+
#
281+
# node_B
282+
# __________________________
283+
# | tab_main |
284+
# |__________________________|
285+
# | tab_part1 | tab_part2 | <-------------- node_A (tab_part2)
286+
# |____________|_____________|
287+
# | tab_part2_1 | --------------> node_C (tab_part2_1)
288+
# |_____________|
289+
###############################################################################
290+
291+
# create a table on node A which will act as a source for a partition on node B
292+
$node_A->safe_psql(
293+
'postgres', qq(
294+
CREATE TABLE tab_part2(a int);
295+
CREATE PUBLICATION tap_pub_A FOR TABLE tab_part2;
296+
));
297+
298+
# create a partition table on node B
299+
$node_B->safe_psql(
300+
'postgres', qq(
301+
CREATE TABLE tab_main(a int) PARTITION BY RANGE(a);
302+
CREATE TABLE tab_part1 PARTITION OF tab_main FOR VALUES FROM (0) TO (5);
303+
CREATE TABLE tab_part2(a int) PARTITION BY RANGE(a);
304+
CREATE TABLE tab_part2_1 PARTITION OF tab_part2 FOR VALUES FROM (5) TO (10);
305+
ALTER TABLE tab_main ATTACH PARTITION tab_part2 FOR VALUES FROM (5) to (10);
306+
CREATE SUBSCRIPTION tap_sub_A_B CONNECTION '$node_A_connstr' PUBLICATION tap_pub_A;
307+
));
308+
309+
# create a table on node C
310+
$node_C->safe_psql(
311+
'postgres', qq(
312+
CREATE TABLE tab_main(a int);
313+
CREATE TABLE tab_part2_1(a int);
314+
));
315+
316+
# create a logical replication setup between node B and node C with
317+
# subscription on node C having origin = NONE and copy_data = on
318+
$node_B->safe_psql(
319+
'postgres', qq(
320+
CREATE PUBLICATION tap_pub_B FOR TABLE tab_main WITH (publish_via_partition_root);
321+
CREATE PUBLICATION tap_pub_B_2 FOR TABLE tab_part2_1;
322+
));
323+
324+
($result, $stdout, $stderr) = $node_C->psql(
325+
'postgres', "
326+
CREATE SUBSCRIPTION tap_sub_B_C CONNECTION '$node_B_connstr' PUBLICATION tap_pub_B WITH (origin = none, copy_data = on);
327+
");
328+
329+
# A warning must be logged as a partition 'tab_part2' in node B is subscribed to
330+
# node A so partition 'tab_part2' can have remotely originated data
331+
like(
332+
$stderr,
333+
qr/WARNING: ( [A-Z0-9]+:)? subscription "tap_sub_b_c" requested copy_data with origin = NONE but might copy data that had a different origin/,
334+
"Create subscription with origin = none and copy_data when the publisher's partition is subscribing from different origin"
335+
);
336+
$node_C->safe_psql('postgres', "DROP SUBSCRIPTION tap_sub_B_C");
337+
338+
($result, $stdout, $stderr) = $node_C->psql(
339+
'postgres', "
340+
CREATE SUBSCRIPTION tap_sub_B_C CONNECTION '$node_B_connstr' PUBLICATION tap_pub_B_2 WITH (origin = none, copy_data = on);
341+
");
342+
343+
# A warning must be logged as ancestor of table 'tab_part2_1' in node B is
344+
# subscribed to node A so table 'tab_part2_1' can have remotely originated
345+
# data
346+
like(
347+
$stderr,
348+
qr/WARNING: ( [A-Z0-9]+:)? subscription "tap_sub_b_c" requested copy_data with origin = NONE but might copy data that had a different origin/,
349+
"Create subscription with origin = none and copy_data when the publisher's ancestor is subscribing from different origin"
350+
);
351+
352+
# clear the operations done by this test
353+
$node_C->safe_psql(
354+
'postgres', qq(
355+
DROP SUBSCRIPTION tap_sub_B_C;
356+
DROP TABLE tab_main;
357+
DROP TABLE tab_part2_1;
358+
));
359+
$node_B->safe_psql(
360+
'postgres', qq(
361+
DROP SUBSCRIPTION tap_sub_A_B;
362+
DROP PUBLICATION tap_pub_B;
363+
DROP PUBLICATION tap_pub_B_2;
364+
DROP TABLE tab_main;
365+
));
366+
$node_A->safe_psql(
367+
'postgres', qq(
368+
DROP PUBLICATION tap_pub_A;
369+
DROP TABLE tab_part2;
370+
));
257371

258372
# shutdown
259373
$node_B->stop('fast');

0 commit comments

Comments
 (0)