Fix relation descriptor leak.
authorAmit Kapila
Tue, 12 Jan 2021 02:49:39 +0000 (08:19 +0530)
committerAmit Kapila
Tue, 12 Jan 2021 02:49:39 +0000 (08:19 +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 81dbed33d511c08fb633d7c341416d0bb43ca1a6..2f01137b426cd6cc9c152d327944abe883cecd83 100644 (file)
@@ -502,6 +502,7 @@ pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
    MemoryContext old;
    RelationSyncEntry *relentry;
    TransactionId xid = InvalidTransactionId;
+   Relation    ancestor = NULL;
 
    if (!is_publishable_relation(relation))
        return;
@@ -552,7 +553,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);
@@ -574,7 +576,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)
                    {
@@ -598,7 +601,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);
@@ -616,6 +620,12 @@ pgoutput_change(LogicalDecodingContext *ctx, ReorderBufferTXN *txn,
            Assert(false);
    }
 
+   if (RelationIsValid(ancestor))
+   {
+       RelationClose(ancestor);
+       ancestor = NULL;
+   }
+
    /* Cleanup */
    MemoryContextSwitchTo(old);
    MemoryContextReset(data->context);