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

Commit69e8c7c

Browse files
committed
Limit memory usage of pg_walinspect functions.
GetWALRecordsInfo() and pg_get_wal_fpi_info() can leak memory acrossWAL record iterations. Fix this by using a temporary memory contextthat's reset for each WAL record iteraion.Also a use temporary context for loops in GetXLogSummaryStats(). Thenumber of iterations is a small constant, so the previous behavior wasnot a leak, but fix for clarity (but no need to backport).Backport GetWALRecordsInfo() change to version15. pg_get_wal_fpi_info() didn't exist in version 15.Reported-by: Peter GeogheganAuthor: Bharath RupireddyDiscussion:https://www.postgresql.org/message-id/CAH2-WznLEJjn7ghmKOABOEZYuJvkTk%3DGKU3m0%2B-XBAH%2BerPiJQ%40mail.gmail.comBackpatch-through: 15
1 parentc6c3b3b commit69e8c7c

File tree

1 file changed

+53
-5
lines changed

1 file changed

+53
-5
lines changed

‎contrib/pg_walinspect/pg_walinspect.c

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,8 @@ pg_get_wal_fpi_info(PG_FUNCTION_ARGS)
304304
XLogRecPtrstart_lsn;
305305
XLogRecPtrend_lsn;
306306
XLogReaderState*xlogreader;
307+
MemoryContextold_cxt;
308+
MemoryContexttmp_cxt;
307309

308310
start_lsn=PG_GETARG_LSN(0);
309311
end_lsn=PG_GETARG_LSN(1);
@@ -314,14 +316,26 @@ pg_get_wal_fpi_info(PG_FUNCTION_ARGS)
314316

315317
xlogreader=InitXLogReaderState(start_lsn);
316318

319+
tmp_cxt=AllocSetContextCreate(CurrentMemoryContext,
320+
"pg_get_wal_fpi_info temporary cxt",
321+
ALLOCSET_DEFAULT_SIZES);
322+
317323
while (ReadNextXLogRecord(xlogreader)&&
318324
xlogreader->EndRecPtr <=end_lsn)
319325
{
326+
/* Use the tmp context so we can clean up after each tuple is done */
327+
old_cxt=MemoryContextSwitchTo(tmp_cxt);
328+
320329
GetWALFPIInfo(fcinfo,xlogreader);
321330

331+
/* clean up and switch back */
332+
MemoryContextSwitchTo(old_cxt);
333+
MemoryContextReset(tmp_cxt);
334+
322335
CHECK_FOR_INTERRUPTS();
323336
}
324337

338+
MemoryContextDelete(tmp_cxt);
325339
pfree(xlogreader->private_data);
326340
XLogReaderFree(xlogreader);
327341

@@ -440,23 +454,37 @@ GetWALRecordsInfo(FunctionCallInfo fcinfo, XLogRecPtr start_lsn,
440454
ReturnSetInfo*rsinfo= (ReturnSetInfo*)fcinfo->resultinfo;
441455
Datumvalues[PG_GET_WAL_RECORDS_INFO_COLS]= {0};
442456
boolnulls[PG_GET_WAL_RECORDS_INFO_COLS]= {0};
457+
MemoryContextold_cxt;
458+
MemoryContexttmp_cxt;
443459

444460
InitMaterializedSRF(fcinfo,0);
445461

446462
xlogreader=InitXLogReaderState(start_lsn);
447463

464+
tmp_cxt=AllocSetContextCreate(CurrentMemoryContext,
465+
"GetWALRecordsInfo temporary cxt",
466+
ALLOCSET_DEFAULT_SIZES);
467+
448468
while (ReadNextXLogRecord(xlogreader)&&
449469
xlogreader->EndRecPtr <=end_lsn)
450470
{
471+
/* Use the tmp context so we can clean up after each tuple is done */
472+
old_cxt=MemoryContextSwitchTo(tmp_cxt);
473+
451474
GetWALRecordInfo(xlogreader,values,nulls,
452475
PG_GET_WAL_RECORDS_INFO_COLS);
453476

454477
tuplestore_putvalues(rsinfo->setResult,rsinfo->setDesc,
455478
values,nulls);
456479

480+
/* clean up and switch back */
481+
MemoryContextSwitchTo(old_cxt);
482+
MemoryContextReset(tmp_cxt);
483+
457484
CHECK_FOR_INTERRUPTS();
458485
}
459486

487+
MemoryContextDelete(tmp_cxt);
460488
pfree(xlogreader->private_data);
461489
XLogReaderFree(xlogreader);
462490

@@ -560,11 +588,13 @@ GetXLogSummaryStats(XLogStats *stats, ReturnSetInfo *rsinfo,
560588
Datum*values,bool*nulls,uint32ncols,
561589
boolstats_per_record)
562590
{
563-
uint64total_count=0;
564-
uint64total_rec_len=0;
565-
uint64total_fpi_len=0;
566-
uint64total_len=0;
567-
intri;
591+
MemoryContextold_cxt;
592+
MemoryContexttmp_cxt;
593+
uint64total_count=0;
594+
uint64total_rec_len=0;
595+
uint64total_fpi_len=0;
596+
uint64total_len=0;
597+
intri;
568598

569599
/*
570600
* Each row shows its percentages of the total, so make a first pass to
@@ -581,6 +611,10 @@ GetXLogSummaryStats(XLogStats *stats, ReturnSetInfo *rsinfo,
581611
}
582612
total_len=total_rec_len+total_fpi_len;
583613

614+
tmp_cxt=AllocSetContextCreate(CurrentMemoryContext,
615+
"GetXLogSummaryStats temporary cxt",
616+
ALLOCSET_DEFAULT_SIZES);
617+
584618
for (ri=0;ri <=RM_MAX_ID;ri++)
585619
{
586620
uint64count;
@@ -614,6 +648,8 @@ GetXLogSummaryStats(XLogStats *stats, ReturnSetInfo *rsinfo,
614648
if (count==0)
615649
continue;
616650

651+
old_cxt=MemoryContextSwitchTo(tmp_cxt);
652+
617653
/* the upper four bits in xl_info are the rmgr's */
618654
id=desc.rm_identify(rj <<4);
619655
if (id==NULL)
@@ -626,6 +662,10 @@ GetXLogSummaryStats(XLogStats *stats, ReturnSetInfo *rsinfo,
626662

627663
tuplestore_putvalues(rsinfo->setResult,rsinfo->setDesc,
628664
values,nulls);
665+
666+
/* clean up and switch back */
667+
MemoryContextSwitchTo(old_cxt);
668+
MemoryContextReset(tmp_cxt);
629669
}
630670
}
631671
else
@@ -635,14 +675,22 @@ GetXLogSummaryStats(XLogStats *stats, ReturnSetInfo *rsinfo,
635675
fpi_len=stats->rmgr_stats[ri].fpi_len;
636676
tot_len=rec_len+fpi_len;
637677

678+
old_cxt=MemoryContextSwitchTo(tmp_cxt);
679+
638680
FillXLogStatsRow(desc.rm_name,count,total_count,rec_len,
639681
total_rec_len,fpi_len,total_fpi_len,tot_len,
640682
total_len,values,nulls,ncols);
641683

642684
tuplestore_putvalues(rsinfo->setResult,rsinfo->setDesc,
643685
values,nulls);
686+
687+
/* clean up and switch back */
688+
MemoryContextSwitchTo(old_cxt);
689+
MemoryContextReset(tmp_cxt);
644690
}
645691
}
692+
693+
MemoryContextDelete(tmp_cxt);
646694
}
647695

648696
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp