8000 PublishStartupProcessInformation() to avoid rare hang in recovery. · jaylevitt/postgres@7c24bac · GitHub
[go: up one dir, main page]

Skip to content

Commit 7c24bac

Browse files
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
1 parent 2ab199b commit 7c24bac

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

src/backend/access/transam/xlog.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "storage/fd.h"
4545
#include "storage/ipc.h"
4646
#include "storage/pmsignal.h"
47+
#include "storage/proc.h"
4748
#include "storage/procarray.h"
4849
#include "storage/smgr.h"
4950
#include "storage/spin.h"
@@ -5569,6 +5570,7 @@ StartupXLOG(void)
55695570
*/
55705571
if (InArchiveRecovery && IsUnderPostmaster)
55715572
{
5573+
PublishStartupProcessInformation();
55725574
SetForwardFsyncRequests();
55735575
SendPostmasterSignal(PMSIGNAL_RECOVERY_STARTED);
55745576
bgwriterLaunched = true;

src/backend/storage/lmgr/proc.c

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1287,12 +1287,53 @@ ProcWaitForSignal(void)
12871287
void
12881288
ProcSendSignal(int pid)
12891289
{
1290-
PGPROC *proc = BackendPidGetProc(pid);
1290+
PGPROC *proc = NULL;
1291+
1292+
proc = BackendPidGetProc(pid);
1293+
1294+
if (proc == NULL)
1295+
{
1296+
/* use volatile pointer to prevent code rearrangement */
1297+
volatile PROC_HDR *procglobal = ProcGlobal;
1298+
1299+
SpinLockAcquire(ProcStructLock);
1300+
1301+
/*
1302+
* Check to see whether it is the Startup process we wish to signal.
1303+
* This call is made by the buffer manager when it wishes to wake up a
1304+
* process that has been waiting for a pin in so it can obtain a
1305+
* cleanup lock using LockBufferForCleanup(). Startup is not a normal
1306+
* backend, so BackendPidGetProc() will not return any pid at all. So
1307+
* we remember the information for this special case.
1308+
*/
1309+
if (pid == procglobal->startupProcPid)
1310+
proc = procglobal->startupProc;
1311+
1312+
SpinLockRelease(ProcStructLock);
1313+
}
12911314

12921315
if (proc != NULL)
12931316
PGSemaphoreUnlock(&proc->sem);
12941317
}
12951318

1319+
/*
1320+
* Record the PID and PGPROC structures for the Startup process, for use in
1321+
* ProcSendSignal(). See comments there for further explanation.
1322+
*/
1323+
void
1324+
PublishStartupProcessInformation(void)
1325+
{
1326+
/* use volatile pointer to prevent code rearrangement */
1327+
volatile PROC_HDR *procglobal = ProcGlobal;
1328+
1329+
SpinLockAcquire(ProcStructLock);
1330+
1331+
procglobal->startupProc = MyProc;
1332+
procglobal->startupProcPid = MyProcPid;
1333+
1334+
SpinLockRelease(ProcStructLock);
1335+
}
1336+
12961337

12971338
/*****************************************************************************
12981339
* SIGALRM interrupt support

src/include/storage/proc.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,11 @@ typedef struct PROC_HDR
133133
PGPROC *autovacFreeProcs;
134134
/* Current shared estimate of appropriate spins_per_delay value */
135135
int spins_per_delay;
136+
137+
/* PGPROC of Startup process */
138+
PGPROC *startupProc;
139+
/* Pid of Startup process */
140+
int startupProcPid;
136141
} PROC_HDR;
137142

138143
/*
@@ -175,6 +180,7 @@ extern void LockWaitCancel(void);
175180

176181
extern void ProcWaitForSignal(void);
177182
extern void ProcSendSignal(int pid);
183+
extern void PublishStartupProcessInformation(void);
178184

179185
extern bool enable_sig_alarm(int delayms, bool is_statement_timeout);
180186
extern bool disable_sig_alarm(bool is_statement_timeout);

0 commit comments

Comments
 (0)
0