]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix relation descriptor leak.
authorAmit Kapila <akapila@postgresql.org>
Tue, 12 Jan 2021 03:00:16 +0000 (08:30 +0530)
committerAmit Kapila <akapila@postgresql.org>
Tue, 12 Jan 2021 03:00:16 +0000 (08:30 +0530)
We missed closing the relation descriptor while sending changes via the
root of partitioned relations during logical replication.

Author: Amit Langote and Mark Zhao
Reviewed-by: Amit Kapila and Ashutosh Bapat
Backpatch-through: 13, where it was introduced
Discussion: https://postgr.es/m/tencent_41FEA657C206F19AB4F406BE9252A0F69C06@qq.com
Discussion: https://postgr.es/m/tencent_6E296D2F7D70AFC90D83353B69187C3AA507@qq.com

src/backend/replication/pgoutput/pgoutput.c

index 15379e311819a6e6e8efd68029470ad969987f22..c5fbebf55ab50bb6e060698321bf7adb18aee634 100644 (file)
@@ -363,6 +363,7 @@ pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
        PGOutputData *data = (PGOutputData *) ctx->output_plugin_private;
        MemoryContext old;
        RelationSyncEntry *relentry;
+       Relation        ancestor = NULL;
 
        if (!is_publishable_relation(relation))
                return;
@@ -404,7 +405,8 @@ pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
                                if (relentry->publish_as_relid != RelationGetRelid(relation))
                                {
                                        Assert(relation->rd_rel->relispartition);
-                                       relation = RelationIdGetRelation(relentry->publish_as_relid);
+                                       ancestor = RelationIdGetRelation(relentry->publish_as_relid);
+                                       relation = ancestor;
                                        /* Convert tuple if needed. */
                                        if (relentry->map)
                                                tuple = execute_attr_map_tuple(tuple, relentry->map);
@@ -425,7 +427,8 @@ pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
                                if (relentry->publish_as_relid != RelationGetRelid(relation))
                                {
                                        Assert(relation->rd_rel->relispartition);
-                                       relation = RelationIdGetRelation(relentry->publish_as_relid);
+                                       ancestor = RelationIdGetRelation(relentry->publish_as_relid);
+                                       relation = ancestor;
                                        /* Convert tuples if needed. */
                                        if (relentry->map)
                                        {
@@ -448,7 +451,8 @@ pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
                                if (relentry->publish_as_relid != RelationGetRelid(relation))
                                {
                                        Assert(relation->rd_rel->relispartition);
-                                       relation = RelationIdGetRelation(relentry->publish_as_relid);
+                                       ancestor = RelationIdGetRelation(relentry->publish_as_relid);
+                                       relation = ancestor;
                                        /* Convert tuple if needed. */
                                        if (relentry->map)
                                                oldtuple = execute_attr_map_tuple(oldtuple, relentry->map);
@@ -465,6 +469,12 @@ pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
                        Assert(false);
        }
 
+       if (RelationIsValid(ancestor))
+       {
+               RelationClose(ancestor);
+               ancestor = NULL;
+       }
+
        /* Cleanup */
        MemoryContextSwitchTo(old);
        MemoryContextReset(data->context);