Skip to content

Commit da32a99

Browse files
committed
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
1 parent 305d89a commit da32a99

File tree

1 file changed

+14
-0
lines changed

1 file changed

+14
-0
lines changed

contrib/pg_walinspect/pg_walinspect.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,8 @@ GetWALRecordsInfo(FunctionCallInfo fcinfo, XLogRecPtr start_lsn,
332332
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
333333
Datum values[PG_GET_WAL_RECORDS_INFO_COLS];
334334
bool nulls[PG_GET_WAL_RECORDS_INFO_COLS];
335+
MemoryContext old_cxt;
336+
MemoryContext tmp_cxt;
335337

336338
InitMaterializedSRF(fcinfo, 0);
337339

@@ -340,18 +342,30 @@ GetWALRecordsInfo(FunctionCallInfo fcinfo, XLogRecPtr start_lsn,
340342
MemSet(values, 0, sizeof(values));
341343
MemSet(nulls, 0, sizeof(nulls));
342344

345+
tmp_cxt = AllocSetContextCreate(CurrentMemoryContext,
346+
"GetWALRecordsInfo temporary cxt",
347+
ALLOCSET_DEFAULT_SIZES);
348+
343349
while (ReadNextXLogRecord(xlogreader) &&
344350
xlogreader->EndRecPtr <= end_lsn)
345351
{
352+
/* Use the tmp context so we can clean up after each tuple is done */
353+
old_cxt = MemoryContextSwitchTo(tmp_cxt);
354+
346355
GetWALRecordInfo(xlogreader, values, nulls,
347356
PG_GET_WAL_RECORDS_INFO_COLS);
348357

349358
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
350359
values, nulls);
351360

361+
/* clean up and switch back */
362+
MemoryContextSwitchTo(old_cxt);
363+
MemoryContextReset(tmp_cxt);
364+
352365
CHECK_FOR_INTERRUPTS();
353366
}
354367

368+
MemoryContextDelete(tmp_cxt);
355369
pfree(xlogreader->private_data);
356370
XLogReaderFree(xlogreader);
357371

0 commit comments

Comments
 (0)