Skip to content

Commit 335f3d0

Browse files
committed
Improve memory management in autovacuum.c.
Invoke vacuum(), as well as "work item" processing, in the PortalContext that do_autovacuum() has manufactured, which will be reset before each such invocation. This ensures cleanup of any memory leaked by these operations. It also avoids the rather dangerous practice of calling vacuum() in a context that vacuum() itself will destroy while it runs. There's no known live bug there, but it's not hard to imagine introducing one if we leave it like this. Tom Lane, reviewed by Michael Paquier and Alvaro Herrera Discussion: https://postgr.es/m/[email protected]
1 parent ad51c6f commit 335f3d0

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

src/backend/postmaster/autovacuum.c

+17-5
Original file line numberDiff line numberDiff line change
@@ -2444,8 +2444,10 @@ do_autovacuum(void)
24442444
*/
24452445
PG_TRY();
24462446
{
2447+
/* Use PortalContext for any per-table allocations */
2448+
MemoryContextSwitchTo(PortalContext);
2449+
24472450
/* have at it */
2448-
MemoryContextSwitchTo(TopTransactionContext);
24492451
autovacuum_do_vac_analyze(tab, bstrategy);
24502452

24512453
/*
@@ -2482,6 +2484,9 @@ do_autovacuum(void)
24822484
}
24832485
PG_END_TRY();
24842486

2487+
/* Make sure we're back in AutovacMemCxt */
2488+
MemoryContextSwitchTo(AutovacMemCxt);
2489+
24852490
did_vacuum = true;
24862491

24872492
/* the PGXACT flags are reset at the next end of transaction */
@@ -2533,8 +2538,7 @@ do_autovacuum(void)
25332538
perform_work_item(workitem);
25342539

25352540
/*
2536-
* Check for config changes before acquiring lock for further
2537-
* jobs.
2541+
* Check for config changes before acquiring lock for further jobs.
25382542
*/
25392543
CHECK_FOR_INTERRUPTS();
25402544
if (got_SIGHUP)
@@ -2605,6 +2609,7 @@ perform_work_item(AutoVacuumWorkItem *workitem)
26052609
* must live in a long-lived memory context because we call vacuum and
26062610
* analyze in different transactions.
26072611
*/
2612+
Assert(CurrentMemoryContext == AutovacMemCxt);
26082613

26092614
cur_relname = get_rel_name(workitem->avw_relation);
26102615
cur_nspname = get_namespace_name(get_rel_namespace(workitem->avw_relation));
@@ -2614,6 +2619,9 @@ perform_work_item(AutoVacuumWorkItem *workitem)
26142619

26152620
autovac_report_workitem(workitem, cur_nspname, cur_datname);
26162621

2622+
/* clean up memory before each work item */
2623+
MemoryContextResetAndDeleteChildren(PortalContext);
2624+
26172625
/*
26182626
* We will abort the current work item if something errors out, and
26192627
* continue with the next one; in particular, this happens if we are
@@ -2622,9 +2630,10 @@ perform_work_item(AutoVacuumWorkItem *workitem)
26222630
*/
26232631
PG_TRY();
26242632
{
2625-
/* have at it */
2626-
MemoryContextSwitchTo(TopTransactionContext);
2633+
/* Use PortalContext for any per-work-item allocations */
2634+
MemoryContextSwitchTo(PortalContext);
26272635

2636+
/* have at it */
26282637
switch (workitem->avw_type)
26292638
{
26302639
case AVW_BRINSummarizeRange:
@@ -2668,6 +2677,9 @@ perform_work_item(AutoVacuumWorkItem *workitem)
26682677
}
26692678
PG_END_TRY();
26702679

2680+
/* Make sure we're back in AutovacMemCxt */
2681+
MemoryContextSwitchTo(AutovacMemCxt);
2682+
26712683
/* We intentionally do not set did_vacuum here */
26722684

26732685
/* be tidy */

0 commit comments

Comments
 (0)