Fix relation descriptor leak.

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
This commit is contained in:
Amit Kapila 2021-01-12 08:30:16 +05:30
parent 14a608aef4
commit decf3fe61c
1 changed files with 13 additions and 3 deletions

View File

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