diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 9856968997..16c5a6ee65 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -1281,7 +1281,7 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
Waiting for confirmation from remote server during synchronous replication.
- Timeout>
+ Timeout>
BaseBackupThrottle>
Waiting during base backup when throttling activity.
@@ -1294,6 +1294,10 @@ postgres 27093 0.0 0.0 30096 2752 ? Ss 11:34 0:00 postgres: ser
Waiting to apply WAL at recovery because it is delayed.
+ RecoveryConflict>
+ Waiting for conflict resolution of query running on standby.
+
+
IO>
BufFileRead>
Waiting for a read from a buffered file.
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 56a8bf2d17..6309014703 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -3600,6 +3600,9 @@ pgstat_get_wait_timeout(WaitEventTimeout w)
case WAIT_EVENT_RECOVERY_APPLY_DELAY:
event_name = "RecoveryApplyDelay";
break;
+ case WAIT_EVENT_RECOVERY_CONFLICT:
+ event_name = "RecoveryConflict";
+ break;
/* no default case, so that compiler will warn */
}
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index 8e57f933ca..38eebe4f5d 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -148,8 +148,8 @@ GetStandbyLimitTime(void)
}
}
-#define STANDBY_INITIAL_WAIT_US 1000
-static int standbyWait_us = STANDBY_INITIAL_WAIT_US;
+#define STANDBY_INITIAL_WAIT_MS 1
+static int standbyWait_ms = STANDBY_INITIAL_WAIT_MS;
/*
* Standby wait logic for ResolveRecoveryConflictWithVirtualXIDs.
@@ -160,8 +160,7 @@ static bool
WaitExceedsMaxStandbyDelay(void)
{
TimestampTz ltime;
-
- CHECK_FOR_INTERRUPTS();
+ int rc;
/* Are we past the limit time? */
ltime = GetStandbyLimitTime();
@@ -171,15 +170,25 @@ WaitExceedsMaxStandbyDelay(void)
/*
* Sleep a bit (this is essential to avoid busy-waiting).
*/
- pg_usleep(standbyWait_us);
+ rc = WaitLatch(MyLatch,
+ WL_TIMEOUT | WL_POSTMASTER_DEATH,
+ standbyWait_ms,
+ WAIT_EVENT_RECOVERY_CONFLICT);
/*
- * Progressively increase the sleep times, but not to more than 1s, since
- * pg_usleep isn't interruptable on some platforms.
+ * Progressively increase the sleep times, but not to more than 1s.
+ * This process is expected to wake up reasonably fast after the
+ * transactions this is waiting for are committed.
*/
- standbyWait_us *= 2;
- if (standbyWait_us > 1000000)
- standbyWait_us = 1000000;
+ if (rc & WL_TIMEOUT)
+ {
+ standbyWait_ms *= 2;
+ if (standbyWait_ms > 1000)
+ standbyWait_ms = 1000;
+ }
+
+ /* An interrupt may have occurred while waiting */
+ HandleStartupProcInterrupts();
return false;
}
@@ -206,8 +215,8 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
while (VirtualTransactionIdIsValid(*waitlist))
{
- /* reset standbyWait_us for each xact we wait for */
- standbyWait_us = STANDBY_INITIAL_WAIT_US;
+ /* reset standbyWait_ms for each xact we wait for */
+ standbyWait_ms = STANDBY_INITIAL_WAIT_MS;
/* wait until the virtual xid is gone */
while (!VirtualXactLock(*waitlist, false))
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index e29397f25b..2bb213fdd4 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -824,7 +824,8 @@ typedef enum
{
WAIT_EVENT_BASE_BACKUP_THROTTLE = PG_WAIT_TIMEOUT,
WAIT_EVENT_PG_SLEEP,
- WAIT_EVENT_RECOVERY_APPLY_DELAY
+ WAIT_EVENT_RECOVERY_APPLY_DELAY,
+ WAIT_EVENT_RECOVERY_CONFLICT
} WaitEventTimeout;
/* ----------