Disable vacuum's use of a buffer access strategy during failsafe

Traditionally, vacuum always makes use of a buffer access strategy 32
buffers in size.  This means that running vacuums tend not to cause too
many shared buffers to become dirty, however, this can cause vacuums to
run much more slowly than they otherwise could as WAL flushes will occur
more frequently due to having to flush WAL out to the LSN of the dirty
page before that page can be written to disk.

When we are performing failsafe VACUUMs (as added in 1e55e7d17), we really
want to make the vacuum work go as quickly as possible, so here we disable
the buffer access strategy when entering failsafe mode while vacuuming a
relation.

Per idea and analyis from Andres Freund.

In passing, also include some changes I had intended for 32fbe0239.

Author: Melanie Plageman
Reviewed-by: Justin Pryzby, David Rowley
Discussion: https://postgr.es/m/20230111182720.ejifsclfwymw2reb%40awork3.anarazel.de
This commit is contained in:
David Rowley 2023-04-03 23:05:58 +12:00
parent 525fb0a171
commit 4830f10243
3 changed files with 18 additions and 5 deletions

View File

@ -9320,8 +9320,12 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
</para>
<para>
When the failsafe is triggered, any cost-based delay that is
in effect will no longer be applied, and further non-essential
maintenance tasks (such as index vacuuming) are bypassed.
in effect will no longer be applied, further non-essential
maintenance tasks (such as index vacuuming) are bypassed, and any
<glossterm linkend="glossary-buffer-access-strategy">Buffer Access Strategy</glossterm>
in use will be disabled resulting in <command>VACUUM</command> being
free to make use of all of
<glossterm linkend="glossary-shared-memory">shared buffers</glossterm>.
</para>
<para>
The default is 1.6 billion transactions. Although users can

View File

@ -2623,6 +2623,13 @@ lazy_check_wraparound_failsafe(LVRelState *vacrel)
{
vacrel->failsafe_active = true;
/*
* Abandon use of a buffer access strategy to allow use of all of
* shared buffers. We assume the caller who allocated the memory for
* the BufferAccessStrategy will free it.
*/
vacrel->bstrategy = NULL;
/* Disable index vacuuming, index cleanup, and heap rel truncation */
vacrel->do_index_vacuuming = false;
vacrel->do_index_cleanup = false;

View File

@ -391,11 +391,13 @@ vacuum(List *relations, VacuumParams *params,
/*
* If caller didn't give us a buffer strategy object, make one in the
* cross-transaction memory context.
* cross-transaction memory context. We needn't bother making this for
* VACUUM (FULL) or VACUUM (ONLY_DATABASE_STATS) as they'll not make use
* of it.
*/
if (bstrategy == NULL &&
!(params->options & VACOPT_ONLY_DATABASE_STATS ||
params->options & VACOPT_FULL))
(params->options & (VACOPT_ONLY_DATABASE_STATS |
VACOPT_FULL)) == 0)
{
MemoryContext old_context = MemoryContextSwitchTo(vac_context);