Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitbbe68c1

Browse files
committed
Fix memory leak in pgoutput with publication list cache
The pgoutput module caches publication names in a list and frees it uponinvalidation. However, the code forgot to free the actual publicationnames within the list elements, as publication names are pstrdup()'d inGetPublication(). This would cause memory to leak inCacheMemoryContext, bloating it over time as this context is notcleaned.This is a problem for WAL senders running for a long time, as anaccumulation of invalidation requests would bloat its cache memoryusage. A second case, where this leak is easier to see, involves abackend calling SQL functions like pg_logical_slot_{get,peek}_changes()which create a new decoding context with each execution. Morepublications create more bloat.To address this, this commit adds a new memory context within thelogical decoding context and resets it each time the publication namescache is invalidated, based on a suggestion from Amit Kapila. Thisensures that the lifespan of the publication names aligns with that ofthe logical decoding context.Contrary to the HEAD-only commitf0c569d that has changedPGOutputData to track this new child memory context, the context istracked with a static variable whose state is reset with a MemoryContextreset callback attached to PGOutputData->context, so as ABIcompatibility is preserved in stable branches. This approach is basedon an suggestion from Amit Kapila.Analyzed-by: Michael Paquier, Jeff DavisAuthor: Masahiko SawadaReviewed-by: Amit Kapila, Michael Paquier, Euler Taveira, Hou ZhijieDiscussion:https://postgr.es/m/Z0khf9EVMVLOc_YY@paquier.xyzBackpatch-through: 13
1 parent7cfdb4d commitbbe68c1

File tree

1 file changed

+37
-9
lines changed

1 file changed

+37
-9
lines changed

‎src/backend/replication/pgoutput/pgoutput.c

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,13 @@ static void pgoutput_stream_prepare_txn(LogicalDecodingContext *ctx,
8181

8282
staticboolpublications_valid;
8383

84+
/*
85+
* Private memory context for publication data, created in
86+
* PGOutputData->context when starting pgoutput, and set to NULL when its
87+
* parent context is reset via a dedicated MemoryContextCallback.
88+
*/
89+
staticMemoryContextpubctx=NULL;
90+
8491
staticList*LoadPublications(List*pubnames);
8592
staticvoidpublication_invalidation_cb(Datumarg,intcacheid,
8693
uint32hashvalue);
@@ -411,6 +418,15 @@ parse_output_parameters(List *options, PGOutputData *data)
411418
errmsg("option \"%s\" missing","publication_names"));
412419
}
413420

421+
/*
422+
* Callback of PGOutputData->context in charge of cleaning pubctx.
423+
*/
424+
staticvoid
425+
pgoutput_pubctx_reset_callback(void*arg)
426+
{
427+
pubctx=NULL;
428+
}
429+
414430
/*
415431
* Initialize this plugin
416432
*/
@@ -420,6 +436,7 @@ pgoutput_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt,
420436
{
421437
PGOutputData*data=palloc0(sizeof(PGOutputData));
422438
staticboolpublication_callback_registered= false;
439+
MemoryContextCallback*mcallback;
423440

424441
/* Create our memory context for private allocations. */
425442
data->context=AllocSetContextCreate(ctx->context,
@@ -430,6 +447,15 @@ pgoutput_startup(LogicalDecodingContext *ctx, OutputPluginOptions *opt,
430447
"logical replication cache context",
431448
ALLOCSET_DEFAULT_SIZES);
432449

450+
Assert(pubctx==NULL);
451+
pubctx=AllocSetContextCreate(ctx->context,
452+
"logical replication publication list context",
453+
ALLOCSET_SMALL_SIZES);
454+
455+
mcallback=palloc0(sizeof(MemoryContextCallback));
456+
mcallback->func=pgoutput_pubctx_reset_callback;
457+
MemoryContextRegisterResetCallback(ctx->context,mcallback);
458+
433459
ctx->output_plugin_private=data;
434460

435461
/* This plugin uses binary protocol. */
@@ -1696,9 +1722,9 @@ pgoutput_origin_filter(LogicalDecodingContext *ctx,
16961722
/*
16971723
* Shutdown the output plugin.
16981724
*
1699-
* Note, we don't need to clean the data->context anddata->cachectxas
1700-
* they are child contexts of the ctx->context so they will be cleaned up by
1701-
* logical decoding machinery.
1725+
* Note, we don't need to clean the data->context,data->cachectxand pubctx
1726+
*asthey are child contexts of the ctx->context so they will be cleaned up
1727+
*bylogical decoding machinery.
17021728
*/
17031729
staticvoid
17041730
pgoutput_shutdown(LogicalDecodingContext*ctx)
@@ -1708,6 +1734,9 @@ pgoutput_shutdown(LogicalDecodingContext *ctx)
17081734
hash_destroy(RelationSyncCache);
17091735
RelationSyncCache=NULL;
17101736
}
1737+
1738+
/* Better safe than sorry */
1739+
pubctx=NULL;
17111740
}
17121741

17131742
/*
@@ -2024,12 +2053,11 @@ get_rel_sync_entry(PGOutputData *data, Relation relation)
20242053
/* Reload publications if needed before use. */
20252054
if (!publications_valid)
20262055
{
2027-
oldctx=MemoryContextSwitchTo(CacheMemoryContext);
2028-
if (data->publications)
2029-
{
2030-
list_free_deep(data->publications);
2031-
data->publications=NIL;
2032-
}
2056+
Assert(pubctx);
2057+
2058+
MemoryContextReset(pubctx);
2059+
oldctx=MemoryContextSwitchTo(pubctx);
2060+
20332061
data->publications=LoadPublications(data->publication_names);
20342062
MemoryContextSwitchTo(oldctx);
20352063
publications_valid= true;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp