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
This commit is contained in:
parent
305d89ad93
commit
da32a99df1
|
@ -332,6 +332,8 @@ GetWALRecordsInfo(FunctionCallInfo fcinfo, XLogRecPtr start_lsn,
|
||||||
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
|
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
|
||||||
Datum values[PG_GET_WAL_RECORDS_INFO_COLS];
|
Datum values[PG_GET_WAL_RECORDS_INFO_COLS];
|
||||||
bool nulls[PG_GET_WAL_RECORDS_INFO_COLS];
|
bool nulls[PG_GET_WAL_RECORDS_INFO_COLS];
|
||||||
|
MemoryContext old_cxt;
|
||||||
|
MemoryContext tmp_cxt;
|
||||||
|
|
||||||
InitMaterializedSRF(fcinfo, 0);
|
InitMaterializedSRF(fcinfo, 0);
|
||||||
|
|
||||||
|
@ -340,18 +342,30 @@ GetWALRecordsInfo(FunctionCallInfo fcinfo, XLogRecPtr start_lsn,
|
||||||
MemSet(values, 0, sizeof(values));
|
MemSet(values, 0, sizeof(values));
|
||||||
MemSet(nulls, 0, sizeof(nulls));
|
MemSet(nulls, 0, sizeof(nulls));
|
||||||
|
|
||||||
|
tmp_cxt = AllocSetContextCreate(CurrentMemoryContext,
|
||||||
|
"GetWALRecordsInfo temporary cxt",
|
||||||
|
ALLOCSET_DEFAULT_SIZES);
|
||||||
|
|
||||||
while (ReadNextXLogRecord(xlogreader) &&
|
while (ReadNextXLogRecord(xlogreader) &&
|
||||||
xlogreader->EndRecPtr <= end_lsn)
|
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,
|
GetWALRecordInfo(xlogreader, values, nulls,
|
||||||
PG_GET_WAL_RECORDS_INFO_COLS);
|
PG_GET_WAL_RECORDS_INFO_COLS);
|
||||||
|
|
||||||
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
|
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc,
|
||||||
values, nulls);
|
values, nulls);
|
||||||
|
|
||||||
|
/* clean up and switch back */
|
||||||
|
MemoryContextSwitchTo(old_cxt);
|
||||||
|
MemoryContextReset(tmp_cxt);
|
||||||
|
|
||||||
CHECK_FOR_INTERRUPTS();
|
CHECK_FOR_INTERRUPTS();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MemoryContextDelete(tmp_cxt);
|
||||||
pfree(xlogreader->private_data);
|
pfree(xlogreader->private_data);
|
||||||
XLogReaderFree(xlogreader);
|
XLogReaderFree(xlogreader);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue