diff options
author | Jeff Davis <jdavis@postgresql.org> | 2023-02-20 11:29:31 -0800 |
---|---|---|
committer | Jeff Davis <jdavis@postgresql.org> | 2023-02-20 11:29:31 -0800 |
commit | da32a99df1f519622eee0d5c3ea61226468272a7 (patch) | |
tree | 0d39a914d02372e492d5e0065ecef480d2e75bba | |
parent | 305d89ad93ff6eb3eecae485bbfb2531a349906f (diff) |
Limit memory usage of pg_walinspect functions.
GetWALRecordsInfo() and pg_get_wal_fpi_info() can leak memory across
WAL record iterations. Fix this by using a temporary memory context
that's reset for each WAL record iteraion.
Also use a temporary context for loops in GetXLogSummaryStats(). The
number of iterations is a small constant, so the previous behavior was
not a leak, but fix for clarity (but no need to backport).
Backport GetWALRecordsInfo() change to version
15. pg_get_wal_fpi_info() didn't exist in version 15.
Reported-by: Peter Geoghegan
Author: Bharath Rupireddy
Discussion: https://www.postgresql.org/message-id/CAH2-WznLEJjn7ghmKOABOEZYuJvkTk%3DGKU3m0%2B-XBAH%2BerPiJQ%40mail.gmail.com
Backpatch-through: 15
-rw-r--r-- | contrib/pg_walinspect/pg_walinspect.c | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/contrib/pg_walinspect/pg_walinspect.c b/contrib/pg_walinspect/pg_walinspect.c index 6b6c7d46e27..826c9345aea 100644 --- a/contrib/pg_walinspect/pg_walinspect.c +++ b/contrib/pg_walinspect/pg_walinspect.c @@ -332,6 +332,8 @@ GetWALRecordsInfo(FunctionCallInfo fcinfo, XLogRecPtr start_lsn, ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; Datum values[PG_GET_WAL_RECORDS_INFO_COLS]; bool nulls[PG_GET_WAL_RECORDS_INFO_COLS]; + MemoryContext old_cxt; + MemoryContext tmp_cxt; InitMaterializedSRF(fcinfo, 0); @@ -340,18 +342,30 @@ GetWALRecordsInfo(FunctionCallInfo fcinfo, XLogRecPtr start_lsn, MemSet(values, 0, sizeof(values)); MemSet(nulls, 0, sizeof(nulls)); + tmp_cxt = AllocSetContextCreate(CurrentMemoryContext, + "GetWALRecordsInfo temporary cxt", + ALLOCSET_DEFAULT_SIZES); + while (ReadNextXLogRecord(xlogreader) && xlogreader->EndRecPtr <= end_lsn) { + /* Use the tmp context so we can clean up after each tuple is done */ + old_cxt = MemoryContextSwitchTo(tmp_cxt); + GetWALRecordInfo(xlogreader, values, nulls, PG_GET_WAL_RECORDS_INFO_COLS); tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls); + /* clean up and switch back */ + MemoryContextSwitchTo(old_cxt); + MemoryContextReset(tmp_cxt); + CHECK_FOR_INTERRUPTS(); } + MemoryContextDelete(tmp_cxt); pfree(xlogreader->private_data); XLogReaderFree(xlogreader); |