Fix relation descriptor leak.
authorAmit Kapila
Tue, 12 Jan 2021 03:00:16 +0000 (08:30 +0530)
committerAmit Kapila
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/[email protected]
Discussion: https://postgr.es/m/[email protected]

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);