@@ -72,12 +72,6 @@ intvacuum_multixact_freeze_table_age;
7272int vacuum_failsafe_age ;
7373int vacuum_multixact_failsafe_age ;
7474
75-
76- /* A few variables that don't seem worth passing around as parameters */
77- static MemoryContext vac_context = NULL ;
78- static BufferAccessStrategy vac_strategy ;
79-
80-
8175/*
8276 * Variables for cost-based parallel vacuum. See comments atop
8377 * compute_parallel_delay to understand how it works.
@@ -87,14 +81,15 @@ pg_atomic_uint32 *VacuumActiveNWorkers = NULL;
8781int VacuumCostBalanceLocal = 0 ;
8882
8983/* non-export function prototypes */
90- static List * expand_vacuum_rel (VacuumRelation * vrel ,int options );
91- static List * get_all_vacuum_rels (int options );
84+ static List * expand_vacuum_rel (VacuumRelation * vrel ,
85+ MemoryContext vac_context ,int options );
86+ static List * get_all_vacuum_rels (MemoryContext vac_context ,int options );
9287static void vac_truncate_clog (TransactionId frozenXID ,
9388MultiXactId minMulti ,
9489TransactionId lastSaneFrozenXid ,
9590MultiXactId lastSaneMinMulti );
9691static bool vacuum_rel (Oid relid ,RangeVar * relation ,VacuumParams * params ,
97- bool skip_privs );
92+ bool skip_privs , BufferAccessStrategy bstrategy );
9893static double compute_parallel_delay (void );
9994static VacOptValue get_vacoptval_from_boolean (DefElem * def );
10095static bool vac_tid_reaped (ItemPointer itemptr ,void * state );
@@ -313,6 +308,7 @@ vacuum(List *relations, VacuumParams *params,
313308{
314309static bool in_vacuum = false;
315310
311+ MemoryContext vac_context ;
316312const char * stmttype ;
317313volatile bool in_outer_xact ,
318314use_own_xacts ;
@@ -338,9 +334,9 @@ vacuum(List *relations, VacuumParams *params,
338334in_outer_xact = IsInTransactionBlock (isTopLevel );
339335
340336/*
341- *Due to static variables vac_context, anl_context and vac_strategy,
342- *vacuum() is not reentrant. This matters when VACUUM FULL or ANALYZE
343- *calls a hostile index expression that itself calls ANALYZE.
337+ *Check for and disallow recursive calls. This could happen when VACUUM
338+ *FULL or ANALYZE calls a hostile index expression that itself calls
339+ * ANALYZE.
344340 */
345341if (in_vacuum )
346342ereport (ERROR ,
@@ -404,7 +400,6 @@ vacuum(List *relations, VacuumParams *params,
404400bstrategy = GetAccessStrategy (BAS_VACUUM );
405401MemoryContextSwitchTo (old_context );
406402}
407- vac_strategy = bstrategy ;
408403
409404/*
410405 * Build list of relation(s) to process, putting any new data in
@@ -426,15 +421,15 @@ vacuum(List *relations, VacuumParams *params,
426421List * sublist ;
427422MemoryContext old_context ;
428423
429- sublist = expand_vacuum_rel (vrel ,params -> options );
424+ sublist = expand_vacuum_rel (vrel ,vac_context , params -> options );
430425old_context = MemoryContextSwitchTo (vac_context );
431426newrels = list_concat (newrels ,sublist );
432427MemoryContextSwitchTo (old_context );
433428}
434429relations = newrels ;
435430}
436431else
437- relations = get_all_vacuum_rels (params -> options );
432+ relations = get_all_vacuum_rels (vac_context , params -> options );
438433
439434/*
440435 * Decide whether we need to start/commit our own transactions.
@@ -509,7 +504,8 @@ vacuum(List *relations, VacuumParams *params,
509504
510505if (params -> options & VACOPT_VACUUM )
511506{
512- if (!vacuum_rel (vrel -> oid ,vrel -> relation ,params , false))
507+ if (!vacuum_rel (vrel -> oid ,vrel -> relation ,params , false,
508+ bstrategy ))
513509continue ;
514510}
515511
@@ -527,7 +523,7 @@ vacuum(List *relations, VacuumParams *params,
527523}
528524
529525analyze_rel (vrel -> oid ,vrel -> relation ,params ,
530- vrel -> va_cols ,in_outer_xact ,vac_strategy );
526+ vrel -> va_cols ,in_outer_xact ,bstrategy );
531527
532528if (use_own_xacts )
533529{
@@ -582,7 +578,6 @@ vacuum(List *relations, VacuumParams *params,
582578 * context!
583579 */
584580MemoryContextDelete (vac_context );
585- vac_context = NULL ;
586581}
587582
588583/*
@@ -760,7 +755,8 @@ vacuum_open_relation(Oid relid, RangeVar *relation, bits32 options,
760755 * are made in vac_context.
761756 */
762757static List *
763- expand_vacuum_rel (VacuumRelation * vrel ,int options )
758+ expand_vacuum_rel (VacuumRelation * vrel ,MemoryContext vac_context ,
759+ int options )
764760{
765761List * vacrels = NIL ;
766762MemoryContext oldcontext ;
@@ -899,7 +895,7 @@ expand_vacuum_rel(VacuumRelation *vrel, int options)
899895 * the current database. The list is built in vac_context.
900896 */
901897static List *
902- get_all_vacuum_rels (int options )
898+ get_all_vacuum_rels (MemoryContext vac_context , int options )
903899{
904900List * vacrels = NIL ;
905901Relation pgclass ;
@@ -1838,7 +1834,8 @@ vac_truncate_clog(TransactionId frozenXID,
18381834 *At entry and exit, we are not inside a transaction.
18391835 */
18401836static bool
1841- vacuum_rel (Oid relid ,RangeVar * relation ,VacuumParams * params ,bool skip_privs )
1837+ vacuum_rel (Oid relid ,RangeVar * relation ,VacuumParams * params ,
1838+ bool skip_privs ,BufferAccessStrategy bstrategy )
18421839{
18431840LOCKMODE lmode ;
18441841Relation rel ;
@@ -2084,7 +2081,7 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, bool skip_privs)
20842081cluster_rel (relid ,InvalidOid ,& cluster_params );
20852082}
20862083else
2087- table_relation_vacuum (rel ,params ,vac_strategy );
2084+ table_relation_vacuum (rel ,params ,bstrategy );
20882085}
20892086
20902087/* Roll back any GUC changes executed by index functions */
@@ -2118,7 +2115,7 @@ vacuum_rel(Oid relid, RangeVar *relation, VacuumParams *params, bool skip_privs)
21182115memcpy (& toast_vacuum_params ,params ,sizeof (VacuumParams ));
21192116toast_vacuum_params .options |=VACOPT_PROCESS_MAIN ;
21202117
2121- vacuum_rel (toast_relid ,NULL ,& toast_vacuum_params , true);
2118+ vacuum_rel (toast_relid ,NULL ,& toast_vacuum_params , true, bstrategy );
21222119}
21232120
21242121/*