Skip to content

Commit

Permalink
Fix fractional vacuum_cost_delay.
Browse files Browse the repository at this point in the history
Commit 4753ef3 changed vacuum_delay_point() to use the WaitLatch() API,
to fix the problem that vacuum could keep running for a very long time
after the postmaster died.

Unfortunately, that broke commit caf626b's support for fractional
vacuum_cost_delay, which shipped in PostgreSQL 12.  WaitLatch() works in
whole milliseconds.

For now, revert the change from commit 4753ef3, but add an explicit
check for postmaster death.  That's an extra system call on systems
other than Linux and FreeBSD, but that overhead doesn't matter much
considering that we willingly went to sleep and woke up again.  (In
later work, we might add higher resolution timeouts to the latch API so
that we could do this with our standard programming pattern, but that
wouldn't be back-patched.)

Back-patch to 14, where commit 4753ef3 arrived.

Reported-by: Melanie Plageman <melanieplageman@gmail.com>
Discussion: https://postgr.es/m/CAAKRu_b-q0hXCBUCAATh0Z4Zi6UkiC0k2DFgoD3nC-r3SkR3tg%40mail.gmail.com
  • Loading branch information
macdice committed Mar 15, 2023
1 parent 9b6e0b9 commit 2bef57e
Showing 1 changed file with 13 additions and 5 deletions.
18 changes: 13 additions & 5 deletions src/backend/commands/vacuum.c
Expand Up @@ -45,6 +45,7 @@
#include "postmaster/bgworker_internals.h"
#include "storage/bufmgr.h"
#include "storage/lmgr.h"
#include "storage/pmsignal.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "utils/acl.h"
Expand Down Expand Up @@ -2171,11 +2172,18 @@ vacuum_delay_point(void)
if (msec > VacuumCostDelay * 4)
msec = VacuumCostDelay * 4;

(void) WaitLatch(MyLatch,
WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
msec,
WAIT_EVENT_VACUUM_DELAY);
ResetLatch(MyLatch);
pgstat_report_wait_start(WAIT_EVENT_VACUUM_DELAY);
pg_usleep(msec * 1000);
pgstat_report_wait_end();

/*
* We don't want to ignore postmaster death during very long vacuums
* with vacuum_cost_delay configured. We can't use the usual
* WaitLatch() approach here because we want microsecond-based sleep
* durations above.
*/
if (IsUnderPostmaster && !PostmasterIsAlive())
exit(1);

VacuumCostBalance = 0;

Expand Down

0 comments on commit 2bef57e

Please sign in to comment.