mirror of
https://github.com/postgres/postgres.git
synced 2026-04-08 18:51:56 -04:00
Previously, on standby promotion, the startup process sent SIGUSR1 to the slotsync worker (or a backend performing slot synchronization) and waited for it to exit. This worked in most cases, but if the process was blocked waiting for a response from the primary (e.g., due to a network failure), SIGUSR1 would not interrupt the wait. As a result, the process could remain stuck, causing the startup process to wait for a long time and delaying promotion. This commit fixes the issue by introducing a new procsignal reason, PROCSIG_SLOTSYNC_MESSAGE. On promotion, the startup process sends this signal, and the handler sets interrupt flags so the process exits (or errors out) promptly at CHECK_FOR_INTERRUPTS(), allowing promotion to complete without delay. Backpatch to v17, where slotsync was introduced. Author: Nisha Moond <nisha.moond412@gmail.com> Reviewed-by: shveta malik <shveta.malik@gmail.com> Reviewed-by: Amit Kapila <amit.kapila16@gmail.com> Reviewed-by: Zhijie Hou <houzj.fnst@fujitsu.com> Reviewed-by: Fujii Masao <masao.fujii@gmail.com> Discussion: https://postgr.es/m/CAHGQGwFzNYroAxSoyJhqTU-pH=t4Ej6RyvhVmBZ91Exj_TPMMQ@mail.gmail.com Backpatch-through: 17
76 lines
2.6 KiB
C
76 lines
2.6 KiB
C
/*-------------------------------------------------------------------------
|
|
*
|
|
* procsignal.h
|
|
* Routines for interprocess signaling
|
|
*
|
|
*
|
|
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
|
|
* Portions Copyright (c) 1994, Regents of the University of California
|
|
*
|
|
* src/include/storage/procsignal.h
|
|
*
|
|
*-------------------------------------------------------------------------
|
|
*/
|
|
#ifndef PROCSIGNAL_H
|
|
#define PROCSIGNAL_H
|
|
|
|
#include "storage/procnumber.h"
|
|
|
|
|
|
/*
|
|
* Reasons for signaling a Postgres child process (a backend or an auxiliary
|
|
* process, like checkpointer). We can cope with concurrent signals for different
|
|
* reasons. However, if the same reason is signaled multiple times in quick
|
|
* succession, the process is likely to observe only one notification of it.
|
|
* This is okay for the present uses.
|
|
*
|
|
* Also, because of race conditions, it's important that all the signals be
|
|
* defined so that no harm is done if a process mistakenly receives one.
|
|
*/
|
|
typedef enum
|
|
{
|
|
PROCSIG_CATCHUP_INTERRUPT, /* sinval catchup interrupt */
|
|
PROCSIG_NOTIFY_INTERRUPT, /* listen/notify interrupt */
|
|
PROCSIG_PARALLEL_MESSAGE, /* message from cooperating parallel backend */
|
|
PROCSIG_WALSND_INIT_STOPPING, /* ask walsenders to prepare for shutdown */
|
|
PROCSIG_BARRIER, /* global barrier interrupt */
|
|
PROCSIG_LOG_MEMORY_CONTEXT, /* ask backend to log the memory contexts */
|
|
PROCSIG_PARALLEL_APPLY_MESSAGE, /* Message from parallel apply workers */
|
|
PROCSIG_SLOTSYNC_MESSAGE, /* ask slot synchronization to stop */
|
|
|
|
/* Recovery conflict reasons */
|
|
PROCSIG_RECOVERY_CONFLICT_FIRST,
|
|
PROCSIG_RECOVERY_CONFLICT_DATABASE = PROCSIG_RECOVERY_CONFLICT_FIRST,
|
|
PROCSIG_RECOVERY_CONFLICT_TABLESPACE,
|
|
PROCSIG_RECOVERY_CONFLICT_LOCK,
|
|
PROCSIG_RECOVERY_CONFLICT_SNAPSHOT,
|
|
PROCSIG_RECOVERY_CONFLICT_LOGICALSLOT,
|
|
PROCSIG_RECOVERY_CONFLICT_BUFFERPIN,
|
|
PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK,
|
|
PROCSIG_RECOVERY_CONFLICT_LAST = PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK,
|
|
|
|
NUM_PROCSIGNALS /* Must be last! */
|
|
} ProcSignalReason;
|
|
|
|
typedef enum
|
|
{
|
|
PROCSIGNAL_BARRIER_SMGRRELEASE, /* ask smgr to close files */
|
|
} ProcSignalBarrierType;
|
|
|
|
/*
|
|
* prototypes for functions in procsignal.c
|
|
*/
|
|
extern Size ProcSignalShmemSize(void);
|
|
extern void ProcSignalShmemInit(void);
|
|
|
|
extern void ProcSignalInit(void);
|
|
extern int SendProcSignal(pid_t pid, ProcSignalReason reason,
|
|
ProcNumber procNumber);
|
|
|
|
extern uint64 EmitProcSignalBarrier(ProcSignalBarrierType type);
|
|
extern void WaitForProcSignalBarrier(uint64 generation);
|
|
extern void ProcessProcSignalBarrier(void);
|
|
|
|
extern void procsignal_sigusr1_handler(SIGNAL_ARGS);
|
|
|
|
#endif /* PROCSIGNAL_H */
|