mirror of
https://github.com/postgres/postgres.git
synced 2025-09-02 04:21:28 +03:00
Fix row filters with multiple publications
When publishing changes through a artition root, we should use the row filter for the top-most ancestor. The relation may be added to multiple publications, using different ancestors, and52e4f0cd47
handled this incorrectly. Withc91f71b9dc
we find the correct top-most ancestor, but the code tried to fetch the row filter from all publications, including those using a different ancestor etc. No row filter can be found for such publications, which was treated as replicating all rows. Similarly toc91f71b9dc
, this seems to be a rare issue in practice. It requires multiple publications including the same partitioned relation, through different ancestors. Fixed by only passing publications containing the top-most ancestor to pgoutput_row_filter_init(), so that treating a missing row filter as replicating all rows is correct. Report and fix by me, test case by Hou zj. Reviews and improvements by Amit Kapila. Author: Tomas Vondra, Hou zj, Amit Kapila Reviewed-by: Amit Kapila, Hou zj Discussion: https://postgr.es/m/d26d24dd-2fab-3c48-0162-2b7f84a9c893%40enterprisedb.com
This commit is contained in:
@@ -1890,8 +1890,6 @@ get_rel_sync_entry(PGOutputData *data, Relation relation)
|
||||
entry->pubactions.pubdelete |= pub->pubactions.pubdelete;
|
||||
entry->pubactions.pubtruncate |= pub->pubactions.pubtruncate;
|
||||
|
||||
rel_publications = lappend(rel_publications, pub);
|
||||
|
||||
/*
|
||||
* We want to publish the changes as the top-most ancestor
|
||||
* across all publications. So we need to check if the
|
||||
@@ -1902,9 +1900,27 @@ get_rel_sync_entry(PGOutputData *data, Relation relation)
|
||||
if (publish_ancestor_level > ancestor_level)
|
||||
continue;
|
||||
|
||||
/* The new value is an ancestor, so let's keep it. */
|
||||
publish_as_relid = pub_relid;
|
||||
publish_ancestor_level = ancestor_level;
|
||||
/*
|
||||
* If we found an ancestor higher up in the tree, discard
|
||||
* the list of publications through which we replicate it,
|
||||
* and use the new ancestor.
|
||||
*/
|
||||
if (publish_ancestor_level < ancestor_level)
|
||||
{
|
||||
publish_as_relid = pub_relid;
|
||||
publish_ancestor_level = ancestor_level;
|
||||
|
||||
/* reset the publication list for this relation */
|
||||
rel_publications = NIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Same ancestor level, has to be the same OID. */
|
||||
Assert(publish_as_relid == pub_relid);
|
||||
}
|
||||
|
||||
/* Track publications for this ancestor. */
|
||||
rel_publications = lappend(rel_publications, pub);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user