Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 52ca757

Browse files
committed
Fix autovacuum work item error handling
In autovacuum's "work item" processing, a few strings were allocated in the current transaction's memory context, which goes away during error handling; if an error happened during execution of the work item, the pfree() calls to clean up afterwards would try to release already-released memory, possibly leading to a crash. In branch master, this was already fixed by commit 335f3d0, so backpatch that to REL_10_STABLE to fix the problem there too. As a secondary problem, verify that the autovacuum worker is connected to the right database for each work item; otherwise some items would be discarded by workers in other databases. Reported-by: Justin Pryzby Discussion: https://postgr.es/m/20171014035732.GB31726@telsasoft.com
1 parent 0f1fbe7 commit 52ca757

File tree

1 file changed

+20
-8
lines changed

1 file changed

+20
-8
lines changed

src/backend/postmaster/autovacuum.c

Lines changed: 20 additions & 8 deletions
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 */
@@ -2525,6 +2530,8 @@ do_autovacuum(void)
25252530
continue;
25262531
if (workitem->avw_active)
25272532
continue;
2533+
if (workitem->avw_database != MyDatabaseId)
2534+
continue;
25282535

25292536
/* claim this one, and release lock while performing it */
25302537
workitem->avw_active = true;
@@ -2533,8 +2540,7 @@ do_autovacuum(void)
25332540
perform_work_item(workitem);
25342541

25352542
/*
2536-
* Check for config changes before acquiring lock for further
2537-
* jobs.
2543+
* Check for config changes before acquiring lock for further jobs.
25382544
*/
25392545
CHECK_FOR_INTERRUPTS();
25402546
if (got_SIGHUP)
@@ -2601,10 +2607,9 @@ perform_work_item(AutoVacuumWorkItem *workitem)
26012607
/*
26022608
* Save the relation name for a possible error message, to avoid a catalog
26032609
* lookup in case of an error. If any of these return NULL, then the
2604-
* relation has been dropped since last we checked; skip it. Note: they
2605-
* must live in a long-lived memory context because we call vacuum and
2606-
* analyze in different transactions.
2610+
* relation has been dropped since last we checked; skip it.
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)