From e2ecf9c29fe47b52f5a867b1136a6e9f56d58490 Mon Sep 17 00:00:00 2001 From: Masahiko Sawada Date: Wed, 26 Feb 2020 12:43:41 +0900 Subject: [PATCH 1/2] Set wait events for recovery conflict resolution --- src/backend/storage/ipc/standby.c | 45 +++++++++++++++---------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c index 3090e57fa4..c85def7317 100644 --- a/src/backend/storage/ipc/standby.c +++ b/src/backend/storage/ipc/standby.c @@ -43,7 +43,8 @@ int max_standby_streaming_delay = 30 * 1000; static HTAB *RecoveryLockLists; static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, - ProcSignalReason reason); + ProcSignalReason reason, + uint32 wait_event_info); static void SendRecoveryConflictWithBufferPin(ProcSignalReason reason); static XLogRecPtr LogCurrentRunningXacts(RunningTransactions CurrRunningXacts); static void LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks); @@ -175,8 +176,7 @@ GetStandbyLimitTime(void) } } -#define STANDBY_INITIAL_WAIT_US 1000 -static int standbyWait_us = STANDBY_INITIAL_WAIT_US; +#define STANDBY_WAIT_MS 1000 /* * Standby wait logic for ResolveRecoveryConflictWithVirtualXIDs. @@ -184,7 +184,7 @@ static int standbyWait_us = STANDBY_INITIAL_WAIT_US; * more then we return true, if we can wait some more return false. */ static bool -WaitExceedsMaxStandbyDelay(void) +WaitExceedsMaxStandbyDelay(uint32 wait_event_info) { TimestampTz ltime; @@ -198,15 +198,11 @@ WaitExceedsMaxStandbyDelay(void) /* * Sleep a bit (this is essential to avoid busy-waiting). */ - pg_usleep(standbyWait_us); - - /* - * Progressively increase the sleep times, but not to more than 1s, since - * pg_usleep isn't interruptible on some platforms. - */ - standbyWait_us *= 2; - if (standbyWait_us > 1000000) - standbyWait_us = 1000000; + WaitLatch(MyLatch, + WL_LATCH_SET | WL_POSTMASTER_DEATH | WL_TIMEOUT, + STANDBY_WAIT_MS, + wait_event_info); + ResetLatch(MyLatch); return false; } @@ -219,7 +215,8 @@ WaitExceedsMaxStandbyDelay(void) */ static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, - ProcSignalReason reason) + ProcSignalReason reason, + uint32 wait_event_info) { TimestampTz waitStart; char *new_status; @@ -233,9 +230,6 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, while (VirtualTransactionIdIsValid(*waitlist)) { - /* reset standbyWait_us for each xact we wait for */ - standbyWait_us = STANDBY_INITIAL_WAIT_US; - /* wait until the virtual xid is gone */ while (!VirtualXactLock(*waitlist, false)) { @@ -259,7 +253,7 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, } /* Is it time to kill it? */ - if (WaitExceedsMaxStandbyDelay()) + if (WaitExceedsMaxStandbyDelay(wait_event_info)) { pid_t pid; @@ -311,7 +305,8 @@ ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileNode node.dbNode); ResolveRecoveryConflictWithVirtualXIDs(backends, - PROCSIG_RECOVERY_CONFLICT_SNAPSHOT); + PROCSIG_RECOVERY_CONFLICT_SNAPSHOT, + PG_WAIT_LOCK | LOCKTAG_TRANSACTION); } void @@ -339,7 +334,8 @@ ResolveRecoveryConflictWithTablespace(Oid tsid) temp_file_users = GetConflictingVirtualXIDs(InvalidTransactionId, InvalidOid); ResolveRecoveryConflictWithVirtualXIDs(temp_file_users, - PROCSIG_RECOVERY_CONFLICT_TABLESPACE); + PROCSIG_RECOVERY_CONFLICT_TABLESPACE, + PG_WAIT_LOCK | LOCKTAG_TRANSACTION); } void @@ -403,7 +399,8 @@ ResolveRecoveryConflictWithLock(LOCKTAG locktag) backends = GetLockConflicts(&locktag, AccessExclusiveLock, NULL); ResolveRecoveryConflictWithVirtualXIDs(backends, - PROCSIG_RECOVERY_CONFLICT_LOCK); + PROCSIG_RECOVERY_CONFLICT_LOCK, + PG_WAIT_LOCK | locktag.locktag_type); } else { @@ -416,10 +413,10 @@ ResolveRecoveryConflictWithLock(LOCKTAG locktag) timeouts[0].type = TMPARAM_AT; timeouts[0].fin_time = ltime; enable_timeouts(timeouts, 1); - } - /* Wait to be signaled by the release of the Relation Lock */ - ProcWaitForSignal(PG_WAIT_LOCK | locktag.locktag_type); + /* Wait to be signaled by the release of the Relation Lock */ + ProcWaitForSignal(PG_WAIT_LOCK | locktag.locktag_type); + } /* * Clear any timeout requests established above. We assume here that the -- 2.23.0