Fix bug that causes to report waiting in PS display twice, in hot standby.
Previously "waiting" could appear twice via PS in case of lock conflict in hot standby mode. Specifically this issue happend when the delay in WAL application determined by max_standby_archive_delay and max_standby_streaming_delay had passed but it took more than 500 msec to cancel all the conflicting transactions. Especially we can observe this easily by setting those delay parameters to -1. The cause of this issue was that WaitOnLock() and ResolveRecoveryConflictWithVirtualXIDs() added "waiting" to the process title in that case. This commit prevents ResolveRecoveryConflictWithVirtualXIDs() from reporting waiting in case of lock conflict, to fix the bug. Back-patch to all back branches. Author: Masahiko Sawada Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/CA+fd4k4mXWTwfQLS3RPwGr4xnfAEs1ysFfgYHvmmoUgv6Zxvmg@mail.gmail.com
This commit is contained in:
parent
500fe161ed
commit
e54183cb0b
@ -43,7 +43,7 @@ int max_standby_streaming_delay = 30 * 1000;
|
||||
static HTAB *RecoveryLockLists;
|
||||
|
||||
static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
|
||||
ProcSignalReason reason);
|
||||
ProcSignalReason reason, bool report_waiting);
|
||||
static void SendRecoveryConflictWithBufferPin(ProcSignalReason reason);
|
||||
static XLogRecPtr LogCurrentRunningXacts(RunningTransactions CurrRunningXacts);
|
||||
static void LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks);
|
||||
@ -216,19 +216,24 @@ WaitExceedsMaxStandbyDelay(void)
|
||||
* recovery processing. Judgement has already been passed on it within
|
||||
* a specific rmgr. Here we just issue the orders to the procs. The procs
|
||||
* then throw the required error as instructed.
|
||||
*
|
||||
* If report_waiting is true, "waiting" is reported in PS display if necessary.
|
||||
* If the caller has already reported that, report_waiting should be false.
|
||||
* Otherwise, "waiting" is reported twice unexpectedly.
|
||||
*/
|
||||
static void
|
||||
ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
|
||||
ProcSignalReason reason)
|
||||
ProcSignalReason reason, bool report_waiting)
|
||||
{
|
||||
TimestampTz waitStart;
|
||||
TimestampTz waitStart = 0;
|
||||
char *new_status;
|
||||
|
||||
/* Fast exit, to avoid a kernel call if there's no work to be done. */
|
||||
if (!VirtualTransactionIdIsValid(*waitlist))
|
||||
return;
|
||||
|
||||
waitStart = GetCurrentTimestamp();
|
||||
if (report_waiting)
|
||||
waitStart = GetCurrentTimestamp();
|
||||
new_status = NULL; /* we haven't changed the ps display */
|
||||
|
||||
while (VirtualTransactionIdIsValid(*waitlist))
|
||||
@ -243,7 +248,7 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
|
||||
* Report via ps if we have been waiting for more than 500 msec
|
||||
* (should that be configurable?)
|
||||
*/
|
||||
if (update_process_title && new_status == NULL &&
|
||||
if (update_process_title && new_status == NULL && report_waiting &&
|
||||
TimestampDifferenceExceeds(waitStart, GetCurrentTimestamp(),
|
||||
500))
|
||||
{
|
||||
@ -311,7 +316,8 @@ ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileNode
|
||||
node.dbNode);
|
||||
|
||||
ResolveRecoveryConflictWithVirtualXIDs(backends,
|
||||
PROCSIG_RECOVERY_CONFLICT_SNAPSHOT);
|
||||
PROCSIG_RECOVERY_CONFLICT_SNAPSHOT,
|
||||
true);
|
||||
}
|
||||
|
||||
void
|
||||
@ -339,7 +345,8 @@ ResolveRecoveryConflictWithTablespace(Oid tsid)
|
||||
temp_file_users = GetConflictingVirtualXIDs(InvalidTransactionId,
|
||||
InvalidOid);
|
||||
ResolveRecoveryConflictWithVirtualXIDs(temp_file_users,
|
||||
PROCSIG_RECOVERY_CONFLICT_TABLESPACE);
|
||||
PROCSIG_RECOVERY_CONFLICT_TABLESPACE,
|
||||
true);
|
||||
}
|
||||
|
||||
void
|
||||
@ -402,8 +409,15 @@ ResolveRecoveryConflictWithLock(LOCKTAG locktag)
|
||||
VirtualTransactionId *backends;
|
||||
|
||||
backends = GetLockConflicts(&locktag, AccessExclusiveLock);
|
||||
|
||||
/*
|
||||
* Prevent ResolveRecoveryConflictWithVirtualXIDs() from reporting
|
||||
* "waiting" in PS display by disabling its argument report_waiting
|
||||
* because the caller, WaitOnLock(), has already reported that.
|
||||
*/
|
||||
ResolveRecoveryConflictWithVirtualXIDs(backends,
|
||||
PROCSIG_RECOVERY_CONFLICT_LOCK);
|
||||
PROCSIG_RECOVERY_CONFLICT_LOCK,
|
||||
false);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user