mirror of
https://github.com/postgres/postgres.git
synced 2026-03-12 21:54:00 -04:00
Even after reaching the minimum recovery point, if there are long-lived
write transactions with 64 subtransactions on the primary, the recovery
snapshot may not yet be ready for hot standby, delaying read-only
connections on the standby. Previously, when read-only connections were
not accepted due to this condition, the following error message was logged:
FATAL: the database system is not yet accepting connections
DETAIL: Consistent recovery state has not been yet reached.
This DETAIL message was misleading because the following message was
already logged in this case:
LOG: consistent recovery state reached
This contradiction, i.e., indicating that the recovery state was consistent
while also stating it wasn’t, caused confusion.
This commit improves the error message to better reflect the actual state:
FATAL: the database system is not yet accepting connections
DETAIL: Recovery snapshot is not yet ready for hot standby.
HINT: To enable hot standby, close write transactions with more than 64 subtransactions on the primary server.
To implement this, the commit introduces a new postmaster signal,
PMSIGNAL_RECOVERY_CONSISTENT. When the startup process reaches
a consistent recovery state, it sends this signal to the postmaster,
allowing it to correctly recognize that state.
Since this is not a clear bug, the change is applied only to the master
branch and is not back-patched.
Author: Atsushi Torikoshi <torikoshia@oss.nttdata.com>
Co-authored-by: Fujii Masao <masao.fujii@gmail.com>
Reviewed-by: Yugo Nagata <nagata@sraoss.co.jp>
Discussion: https://postgr.es/m/02db8cd8e1f527a8b999b94a4bee3165@oss.nttdata.com
110 lines
3.5 KiB
C
110 lines
3.5 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* pmsignal.h
|
|
* routines for signaling between the postmaster and its child processes
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/storage/pmsignal.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef PMSIGNAL_H
|
|
#define PMSIGNAL_H
|
|
|
|
#include <signal.h>
|
|
|
|
#ifdef HAVE_SYS_PRCTL_H
|
|
#include "sys/prctl.h"
|
|
#endif
|
|
|
|
#ifdef HAVE_SYS_PROCCTL_H
|
|
#include "sys/procctl.h"
|
|
#endif
|
|
|
|
/*
|
|
* Reasons for signaling the postmaster. We can cope with simultaneous
|
|
* signals for different reasons. If the same reason is signaled multiple
|
|
* times in quick succession, however, the postmaster is likely to observe
|
|
* only one notification of it. This is okay for the present uses.
|
|
*/
|
|
typedef enum
|
|
{
|
|
PMSIGNAL_RECOVERY_STARTED, /* recovery has started */
|
|
PMSIGNAL_RECOVERY_CONSISTENT, /* recovery has reached consistent state */
|
|
PMSIGNAL_BEGIN_HOT_STANDBY, /* begin Hot Standby */
|
|
PMSIGNAL_ROTATE_LOGFILE, /* send SIGUSR1 to syslogger to rotate logfile */
|
|
PMSIGNAL_START_AUTOVAC_LAUNCHER, /* start an autovacuum launcher */
|
|
PMSIGNAL_START_AUTOVAC_WORKER, /* start an autovacuum worker */
|
|
PMSIGNAL_BACKGROUND_WORKER_CHANGE, /* background worker state change */
|
|
PMSIGNAL_START_WALRECEIVER, /* start a walreceiver */
|
|
PMSIGNAL_ADVANCE_STATE_MACHINE, /* advance postmaster's state machine */
|
|
PMSIGNAL_XLOG_IS_SHUTDOWN, /* ShutdownXLOG() completed */
|
|
} PMSignalReason;
|
|
|
|
#define NUM_PMSIGNALS (PMSIGNAL_XLOG_IS_SHUTDOWN+1)
|
|
|
|
/*
|
|
* Reasons why the postmaster would send SIGQUIT to its children.
|
|
*/
|
|
typedef enum
|
|
{
|
|
PMQUIT_NOT_SENT = 0, /* postmaster hasn't sent SIGQUIT */
|
|
PMQUIT_FOR_CRASH, /* some other backend bought the farm */
|
|
PMQUIT_FOR_STOP, /* immediate stop was commanded */
|
|
} QuitSignalReason;
|
|
|
|
/* PMSignalData is an opaque struct, details known only within pmsignal.c */
|
|
typedef struct PMSignalData PMSignalData;
|
|
|
|
#ifdef EXEC_BACKEND
|
|
extern PGDLLIMPORT volatile PMSignalData *PMSignalState;
|
|
#endif
|
|
|
|
/*
|
|
* prototypes for functions in pmsignal.c
|
|
*/
|
|
extern Size PMSignalShmemSize(void);
|
|
extern void PMSignalShmemInit(void);
|
|
extern void SendPostmasterSignal(PMSignalReason reason);
|
|
extern bool CheckPostmasterSignal(PMSignalReason reason);
|
|
extern void SetQuitSignalReason(QuitSignalReason reason);
|
|
extern QuitSignalReason GetQuitSignalReason(void);
|
|
extern void MarkPostmasterChildSlotAssigned(int slot);
|
|
extern bool MarkPostmasterChildSlotUnassigned(int slot);
|
|
extern bool IsPostmasterChildWalSender(int slot);
|
|
extern void RegisterPostmasterChildActive(void);
|
|
extern void MarkPostmasterChildWalSender(void);
|
|
extern bool PostmasterIsAliveInternal(void);
|
|
extern void PostmasterDeathSignalInit(void);
|
|
|
|
|
|
/*
|
|
* Do we have a way to ask for a signal on parent death?
|
|
*
|
|
* If we do, pmsignal.c will set up a signal handler, that sets a flag when
|
|
* the parent dies. Checking the flag first makes PostmasterIsAlive() a lot
|
|
* cheaper in usual case that the postmaster is alive.
|
|
*/
|
|
#if (defined(HAVE_SYS_PRCTL_H) && defined(PR_SET_PDEATHSIG)) || \
|
|
(defined(HAVE_SYS_PROCCTL_H) && defined(PROC_PDEATHSIG_CTL))
|
|
#define USE_POSTMASTER_DEATH_SIGNAL
|
|
#endif
|
|
|
|
#ifdef USE_POSTMASTER_DEATH_SIGNAL
|
|
extern PGDLLIMPORT volatile sig_atomic_t postmaster_possibly_dead;
|
|
|
|
static inline bool
|
|
PostmasterIsAlive(void)
|
|
{
|
|
if (likely(!postmaster_possibly_dead))
|
|
return true;
|
|
return PostmasterIsAliveInternal();
|
|
}
|
|
#else
|
|
#define PostmasterIsAlive() PostmasterIsAliveInternal()
|
|
#endif
|
|
|
|
#endif /* PMSIGNAL_H */
|