mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-12 18:34:36 +08:00
Remove set_latch_on_sigusr1 flag.
This flag has proven to be a recipe for bugs, and it doesn't seem like it can really buy anything in terms of performance. So let's just *always* set the process latch when we receive SIGUSR1 instead of trying to do it only when needed. Per my recent proposal on pgsql-hackers.
This commit is contained in:
parent
b7aac36245
commit
db0f6cad48
@ -954,45 +954,31 @@ WaitForBackgroundWorkerStartup(BackgroundWorkerHandle *handle, pid_t *pidp)
|
|||||||
{
|
{
|
||||||
BgwHandleStatus status;
|
BgwHandleStatus status;
|
||||||
int rc;
|
int rc;
|
||||||
bool save_set_latch_on_sigusr1;
|
|
||||||
|
|
||||||
save_set_latch_on_sigusr1 = set_latch_on_sigusr1;
|
for (;;)
|
||||||
set_latch_on_sigusr1 = true;
|
|
||||||
|
|
||||||
PG_TRY();
|
|
||||||
{
|
{
|
||||||
for (;;)
|
pid_t pid;
|
||||||
|
|
||||||
|
CHECK_FOR_INTERRUPTS();
|
||||||
|
|
||||||
|
status = GetBackgroundWorkerPid(handle, &pid);
|
||||||
|
if (status == BGWH_STARTED)
|
||||||
|
*pidp = pid;
|
||||||
|
if (status != BGWH_NOT_YET_STARTED)
|
||||||
|
break;
|
||||||
|
|
||||||
|
rc = WaitLatch(MyLatch,
|
||||||
|
WL_LATCH_SET | WL_POSTMASTER_DEATH, 0);
|
||||||
|
|
||||||
|
if (rc & WL_POSTMASTER_DEATH)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
status = BGWH_POSTMASTER_DIED;
|
||||||
|
break;
|
||||||
CHECK_FOR_INTERRUPTS();
|
|
||||||
|
|
||||||
status = GetBackgroundWorkerPid(handle, &pid);
|
|
||||||
if (status == BGWH_STARTED)
|
|
||||||
*pidp = pid;
|
|
||||||
if (status != BGWH_NOT_YET_STARTED)
|
|
||||||
break;
|
|
||||||
|
|
||||||
rc = WaitLatch(MyLatch,
|
|
||||||
WL_LATCH_SET | WL_POSTMASTER_DEATH, 0);
|
|
||||||
|
|
||||||
if (rc & WL_POSTMASTER_DEATH)
|
|
||||||
{
|
|
||||||
status = BGWH_POSTMASTER_DIED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResetLatch(MyLatch);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
PG_CATCH();
|
|
||||||
{
|
|
||||||
set_latch_on_sigusr1 = save_set_latch_on_sigusr1;
|
|
||||||
PG_RE_THROW();
|
|
||||||
}
|
|
||||||
PG_END_TRY();
|
|
||||||
|
|
||||||
set_latch_on_sigusr1 = save_set_latch_on_sigusr1;
|
ResetLatch(MyLatch);
|
||||||
|
}
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1009,40 +995,26 @@ WaitForBackgroundWorkerShutdown(BackgroundWorkerHandle *handle)
|
|||||||
{
|
{
|
||||||
BgwHandleStatus status;
|
BgwHandleStatus status;
|
||||||
int rc;
|
int rc;
|
||||||
bool save_set_latch_on_sigusr1;
|
|
||||||
|
|
||||||
save_set_latch_on_sigusr1 = set_latch_on_sigusr1;
|
for (;;)
|
||||||
set_latch_on_sigusr1 = true;
|
|
||||||
|
|
||||||
PG_TRY();
|
|
||||||
{
|
{
|
||||||
for (;;)
|
pid_t pid;
|
||||||
{
|
|
||||||
pid_t pid;
|
|
||||||
|
|
||||||
CHECK_FOR_INTERRUPTS();
|
CHECK_FOR_INTERRUPTS();
|
||||||
|
|
||||||
status = GetBackgroundWorkerPid(handle, &pid);
|
status = GetBackgroundWorkerPid(handle, &pid);
|
||||||
if (status == BGWH_STOPPED)
|
if (status == BGWH_STOPPED)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
rc = WaitLatch(&MyProc->procLatch,
|
rc = WaitLatch(&MyProc->procLatch,
|
||||||
WL_LATCH_SET | WL_POSTMASTER_DEATH, 0);
|
WL_LATCH_SET | WL_POSTMASTER_DEATH, 0);
|
||||||
|
|
||||||
if (rc & WL_POSTMASTER_DEATH)
|
if (rc & WL_POSTMASTER_DEATH)
|
||||||
return BGWH_POSTMASTER_DIED;
|
return BGWH_POSTMASTER_DIED;
|
||||||
|
|
||||||
ResetLatch(&MyProc->procLatch);
|
ResetLatch(&MyProc->procLatch);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
PG_CATCH();
|
|
||||||
{
|
|
||||||
set_latch_on_sigusr1 = save_set_latch_on_sigusr1;
|
|
||||||
PG_RE_THROW();
|
|
||||||
}
|
|
||||||
PG_END_TRY();
|
|
||||||
|
|
||||||
set_latch_on_sigusr1 = save_set_latch_on_sigusr1;
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,14 +59,6 @@ typedef struct
|
|||||||
*/
|
*/
|
||||||
#define NumProcSignalSlots (MaxBackends + NUM_AUXPROCTYPES)
|
#define NumProcSignalSlots (MaxBackends + NUM_AUXPROCTYPES)
|
||||||
|
|
||||||
/*
|
|
||||||
* If this flag is set, the process latch will be set whenever SIGUSR1
|
|
||||||
* is received. This is useful when waiting for a signal from the postmaster.
|
|
||||||
* Spurious wakeups must be expected. Make sure that the flag is cleared
|
|
||||||
* in the error path.
|
|
||||||
*/
|
|
||||||
bool set_latch_on_sigusr1;
|
|
||||||
|
|
||||||
static ProcSignalSlot *ProcSignalSlots = NULL;
|
static ProcSignalSlot *ProcSignalSlots = NULL;
|
||||||
static volatile ProcSignalSlot *MyProcSignalSlot = NULL;
|
static volatile ProcSignalSlot *MyProcSignalSlot = NULL;
|
||||||
|
|
||||||
@ -296,8 +288,7 @@ procsignal_sigusr1_handler(SIGNAL_ARGS)
|
|||||||
if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN))
|
if (CheckProcSignal(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN))
|
||||||
RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN);
|
RecoveryConflictInterrupt(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN);
|
||||||
|
|
||||||
if (set_latch_on_sigusr1)
|
SetLatch(MyLatch);
|
||||||
SetLatch(MyLatch);
|
|
||||||
|
|
||||||
latch_sigusr1_handler();
|
latch_sigusr1_handler();
|
||||||
|
|
||||||
|
@ -962,63 +962,49 @@ static bool
|
|||||||
shm_mq_wait_internal(volatile shm_mq *mq, PGPROC *volatile * ptr,
|
shm_mq_wait_internal(volatile shm_mq *mq, PGPROC *volatile * ptr,
|
||||||
BackgroundWorkerHandle *handle)
|
BackgroundWorkerHandle *handle)
|
||||||
{
|
{
|
||||||
bool save_set_latch_on_sigusr1;
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
save_set_latch_on_sigusr1 = set_latch_on_sigusr1;
|
for (;;)
|
||||||
if (handle != NULL)
|
|
||||||
set_latch_on_sigusr1 = true;
|
|
||||||
|
|
||||||
PG_TRY();
|
|
||||||
{
|
{
|
||||||
for (;;)
|
BgwHandleStatus status;
|
||||||
|
pid_t pid;
|
||||||
|
bool detached;
|
||||||
|
|
||||||
|
/* Acquire the lock just long enough to check the pointer. */
|
||||||
|
SpinLockAcquire(&mq->mq_mutex);
|
||||||
|
detached = mq->mq_detached;
|
||||||
|
result = (*ptr != NULL);
|
||||||
|
SpinLockRelease(&mq->mq_mutex);
|
||||||
|
|
||||||
|
/* Fail if detached; else succeed if initialized. */
|
||||||
|
if (detached)
|
||||||
{
|
{
|
||||||
BgwHandleStatus status;
|
result = false;
|
||||||
pid_t pid;
|
break;
|
||||||
bool detached;
|
}
|
||||||
|
if (result)
|
||||||
|
break;
|
||||||
|
|
||||||
/* Acquire the lock just long enough to check the pointer. */
|
if (handle != NULL)
|
||||||
SpinLockAcquire(&mq->mq_mutex);
|
{
|
||||||
detached = mq->mq_detached;
|
/* Check for unexpected worker death. */
|
||||||
result = (*ptr != NULL);
|
status = GetBackgroundWorkerPid(handle, &pid);
|
||||||
SpinLockRelease(&mq->mq_mutex);
|
if (status != BGWH_STARTED && status != BGWH_NOT_YET_STARTED)
|
||||||
|
|
||||||
/* Fail if detached; else succeed if initialized. */
|
|
||||||
if (detached)
|
|
||||||
{
|
{
|
||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (result)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (handle != NULL)
|
|
||||||
{
|
|
||||||
/* Check for unexpected worker death. */
|
|
||||||
status = GetBackgroundWorkerPid(handle, &pid);
|
|
||||||
if (status != BGWH_STARTED && status != BGWH_NOT_YET_STARTED)
|
|
||||||
{
|
|
||||||
result = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait to be signalled. */
|
|
||||||
WaitLatch(MyLatch, WL_LATCH_SET, 0);
|
|
||||||
|
|
||||||
/* An interrupt may have occurred while we were waiting. */
|
|
||||||
CHECK_FOR_INTERRUPTS();
|
|
||||||
|
|
||||||
/* Reset the latch so we don't spin. */
|
|
||||||
ResetLatch(MyLatch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Wait to be signalled. */
|
||||||
|
WaitLatch(MyLatch, WL_LATCH_SET, 0);
|
||||||
|
|
||||||
|
/* An interrupt may have occurred while we were waiting. */
|
||||||
|
CHECK_FOR_INTERRUPTS();
|
||||||
|
|
||||||
|
/* Reset the latch so we don't spin. */
|
||||||
|
ResetLatch(MyLatch);
|
||||||
}
|
}
|
||||||
PG_CATCH();
|
|
||||||
{
|
|
||||||
set_latch_on_sigusr1 = save_set_latch_on_sigusr1;
|
|
||||||
PG_RE_THROW();
|
|
||||||
}
|
|
||||||
PG_END_TRY();
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -2825,9 +2825,7 @@ RecoveryConflictInterrupt(ProcSignalReason reason)
|
|||||||
/*
|
/*
|
||||||
* Set the process latch. This function essentially emulates signal
|
* Set the process latch. This function essentially emulates signal
|
||||||
* handlers like die() and StatementCancelHandler() and it seems prudent
|
* handlers like die() and StatementCancelHandler() and it seems prudent
|
||||||
* to behave similarly as they do. Alternatively all plain backend code
|
* to behave similarly as they do.
|
||||||
* waiting on that latch, expecting to get interrupted by query cancels et
|
|
||||||
* al., would also need to set set_latch_on_sigusr1.
|
|
||||||
*/
|
*/
|
||||||
SetLatch(MyLatch);
|
SetLatch(MyLatch);
|
||||||
|
|
||||||
|
@ -55,6 +55,5 @@ extern int SendProcSignal(pid_t pid, ProcSignalReason reason,
|
|||||||
BackendId backendId);
|
BackendId backendId);
|
||||||
|
|
||||||
extern void procsignal_sigusr1_handler(SIGNAL_ARGS);
|
extern void procsignal_sigusr1_handler(SIGNAL_ARGS);
|
||||||
extern PGDLLIMPORT bool set_latch_on_sigusr1;
|
|
||||||
|
|
||||||
#endif /* PROCSIGNAL_H */
|
#endif /* PROCSIGNAL_H */
|
||||||
|
@ -255,51 +255,38 @@ static void
|
|||||||
wait_for_workers_to_become_ready(worker_state *wstate,
|
wait_for_workers_to_become_ready(worker_state *wstate,
|
||||||
volatile test_shm_mq_header *hdr)
|
volatile test_shm_mq_header *hdr)
|
||||||
{
|
{
|
||||||
bool save_set_latch_on_sigusr1;
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
|
|
||||||
save_set_latch_on_sigusr1 = set_latch_on_sigusr1;
|
for (;;)
|
||||||
set_latch_on_sigusr1 = true;
|
|
||||||
|
|
||||||
PG_TRY();
|
|
||||||
{
|
{
|
||||||
for (;;)
|
int workers_ready;
|
||||||
|
|
||||||
|
/* If all the workers are ready, we have succeeded. */
|
||||||
|
SpinLockAcquire(&hdr->mutex);
|
||||||
|
workers_ready = hdr->workers_ready;
|
||||||
|
SpinLockRelease(&hdr->mutex);
|
||||||
|
if (workers_ready >= wstate->nworkers)
|
||||||
{
|
{
|
||||||
int workers_ready;
|
result = true;
|
||||||
|
break;
|
||||||
/* If all the workers are ready, we have succeeded. */
|
|
||||||
SpinLockAcquire(&hdr->mutex);
|
|
||||||
workers_ready = hdr->workers_ready;
|
|
||||||
SpinLockRelease(&hdr->mutex);
|
|
||||||
if (workers_ready >= wstate->nworkers)
|
|
||||||
{
|
|
||||||
result = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If any workers (or the postmaster) have died, we have failed. */
|
|
||||||
if (!check_worker_status(wstate))
|
|
||||||
{
|
|
||||||
result = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Wait to be signalled. */
|
|
||||||
WaitLatch(MyLatch, WL_LATCH_SET, 0);
|
|
||||||
|
|
||||||
/* An interrupt may have occurred while we were waiting. */
|
|
||||||
CHECK_FOR_INTERRUPTS();
|
|
||||||
|
|
||||||
/* Reset the latch so we don't spin. */
|
|
||||||
ResetLatch(MyLatch);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If any workers (or the postmaster) have died, we have failed. */
|
||||||
|
if (!check_worker_status(wstate))
|
||||||
|
{
|
||||||
|
result = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Wait to be signalled. */
|
||||||
|
WaitLatch(MyLatch, WL_LATCH_SET, 0);
|
||||||
|
|
||||||
|
/* An interrupt may have occurred while we were waiting. */
|
||||||
|
CHECK_FOR_INTERRUPTS();
|
||||||
|
|
||||||
|
/* Reset the latch so we don't spin. */
|
||||||
|
ResetLatch(MyLatch);
|
||||||
}
|
}
|
||||||
PG_CATCH();
|
|
||||||
{
|
|
||||||
set_latch_on_sigusr1 = save_set_latch_on_sigusr1;
|
|
||||||
PG_RE_THROW();
|
|
||||||
}
|
|
||||||
PG_END_TRY();
|
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
ereport(ERROR,
|
ereport(ERROR,
|
||||||
|
Loading…
Reference in New Issue
Block a user