PublishStartupProcessInformation() to avoid rare hang in recovery.
Bgwriter could cause hang in recovery during page concurrent cleaning. Bug report and testing by Bernd Helmle, fix by me
This commit is contained in:
parent
2ab199b354
commit
7c24bac64c
@ -44,6 +44,7 @@
|
|||||||
#include "storage/fd.h"
|
#include "storage/fd.h"
|
||||||
#include "storage/ipc.h"
|
#include "storage/ipc.h"
|
||||||
#include "storage/pmsignal.h"
|
#include "storage/pmsignal.h"
|
||||||
|
#include "storage/proc.h"
|
||||||
#include "storage/procarray.h"
|
#include "storage/procarray.h"
|
||||||
#include "storage/smgr.h"
|
#include "storage/smgr.h"
|
||||||
#include "storage/spin.h"
|
#include "storage/spin.h"
|
||||||
@ -5569,6 +5570,7 @@ StartupXLOG(void)
|
|||||||
*/
|
*/
|
||||||
if (InArchiveRecovery && IsUnderPostmaster)
|
if (InArchiveRecovery && IsUnderPostmaster)
|
||||||
{
|
{
|
||||||
|
PublishStartupProcessInformation();
|
||||||
SetForwardFsyncRequests();
|
SetForwardFsyncRequests();
|
||||||
SendPostmasterSignal(PMSIGNAL_RECOVERY_STARTED);
|
SendPostmasterSignal(PMSIGNAL_RECOVERY_STARTED);
|
||||||
bgwriterLaunched = true;
|
bgwriterLaunched = true;
|
||||||
|
@ -1287,12 +1287,53 @@ ProcWaitForSignal(void)
|
|||||||
void
|
void
|
||||||
ProcSendSignal(int pid)
|
ProcSendSignal(int pid)
|
||||||
{
|
{
|
||||||
PGPROC *proc = BackendPidGetProc(pid);
|
PGPROC *proc = NULL;
|
||||||
|
|
||||||
|
proc = BackendPidGetProc(pid);
|
||||||
|
|
||||||
|
if (proc == NULL)
|
||||||
|
{
|
||||||
|
/* use volatile pointer to prevent code rearrangement */
|
||||||
|
volatile PROC_HDR *procglobal = ProcGlobal;
|
||||||
|
|
||||||
|
SpinLockAcquire(ProcStructLock);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check to see whether it is the Startup process we wish to signal.
|
||||||
|
* This call is made by the buffer manager when it wishes to wake up a
|
||||||
|
* process that has been waiting for a pin in so it can obtain a
|
||||||
|
* cleanup lock using LockBufferForCleanup(). Startup is not a normal
|
||||||
|
* backend, so BackendPidGetProc() will not return any pid at all. So
|
||||||
|
* we remember the information for this special case.
|
||||||
|
*/
|
||||||
|
if (pid == procglobal->startupProcPid)
|
||||||
|
proc = procglobal->startupProc;
|
||||||
|
|
||||||
|
SpinLockRelease(ProcStructLock);
|
||||||
|
}
|
||||||
|
|
||||||
if (proc != NULL)
|
if (proc != NULL)
|
||||||
PGSemaphoreUnlock(&proc->sem);
|
PGSemaphoreUnlock(&proc->sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Record the PID and PGPROC structures for the Startup process, for use in
|
||||||
|
* ProcSendSignal(). See comments there for further explanation.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
PublishStartupProcessInformation(void)
|
||||||
|
{
|
||||||
|
/* use volatile pointer to prevent code rearrangement */
|
||||||
|
volatile PROC_HDR *procglobal = ProcGlobal;
|
||||||
|
|
||||||
|
SpinLockAcquire(ProcStructLock);
|
||||||
|
|
||||||
|
procglobal->startupProc = MyProc;
|
||||||
|
procglobal->startupProcPid = MyProcPid;
|
||||||
|
|
||||||
|
SpinLockRelease(ProcStructLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* SIGALRM interrupt support
|
* SIGALRM interrupt support
|
||||||
|
@ -133,6 +133,11 @@ typedef struct PROC_HDR
|
|||||||
PGPROC *autovacFreeProcs;
|
PGPROC *autovacFreeProcs;
|
||||||
/* Current shared estimate of appropriate spins_per_delay value */
|
/* Current shared estimate of appropriate spins_per_delay value */
|
||||||
int spins_per_delay;
|
int spins_per_delay;
|
||||||
|
|
||||||
|
/* PGPROC of Startup process */
|
||||||
|
PGPROC *startupProc;
|
||||||
|
/* Pid of Startup process */
|
||||||
|
int startupProcPid;
|
||||||
} PROC_HDR;
|
} PROC_HDR;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -175,6 +180,7 @@ extern void LockWaitCancel(void);
|
|||||||
|
|
||||||
extern void ProcWaitForSignal(void);
|
extern void ProcWaitForSignal(void);
|
||||||
extern void ProcSendSignal(int pid);
|
extern void ProcSendSignal(int pid);
|
||||||
|
extern void PublishStartupProcessInformation(void);
|
||||||
|
|
||||||
extern bool enable_sig_alarm(int delayms, bool is_statement_timeout);
|
extern bool enable_sig_alarm(int delayms, bool is_statement_timeout);
|
||||||
extern bool disable_sig_alarm(bool is_statement_timeout);
|
extern bool disable_sig_alarm(bool is_statement_timeout);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user