Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd3061f0

Browse files
committed
Move CheckRecoveryConflictDeadlock() call to a safer place.
This kluge was inserted in a spot apparently chosen at random: the lockmanager's state is not yet fully set up for the wait, and in particularLockWaitCancel hasn't been armed by setting lockAwaited, so the ProcLockwill not get cleaned up if the ereport is thrown. This seems to not causeany observable problem in trivial test cases, because LockReleaseAll willsilently clean up the debris; but I was able to cause failures with testsinvolving subtransactions.Fixes breakage induced by commitc85c941.Back-patch to all affected branches.
1 parent0f904c9 commitd3061f0

File tree

4 files changed

+22
-19
lines changed

4 files changed

+22
-19
lines changed

‎src/backend/storage/ipc/standby.c

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -463,24 +463,25 @@ SendRecoveryConflictWithBufferPin(ProcSignalReason reason)
463463

464464
/*
465465
* In Hot Standby perform early deadlock detection. We abort the lock
466-
* wait if are about to sleep while holding the buffer pin that Startup
467-
* process is waiting for. The deadlock occurs because we can only be
468-
* waiting behind an AccessExclusiveLock, which can only clear when a
469-
* transaction completion record is replayed, which can only occur when
470-
* Startup process is not waiting. So if Startup process is waiting we
471-
* never will clear that lock, so if we wait we cause deadlock. If we
472-
* are the Startup process then no need to check for deadlocks.
466+
* wait if we are about to sleep while holding the buffer pin that Startup
467+
* process is waiting for.
468+
*
469+
* Note: this code is pessimistic, because there is no way for it to
470+
* determine whether an actual deadlock condition is present: the lock we
471+
* need to wait for might be unrelated to any held by the Startup process.
472+
* Sooner or later, this mechanism should get ripped out in favor of somehow
473+
* accounting for buffer locks in DeadLockCheck(). However, errors here
474+
* seem to be very low-probability in practice, so for now it's not worth
475+
* the trouble.
473476
*/
474477
void
475-
CheckRecoveryConflictDeadlock(LWLockIdpartitionLock)
478+
CheckRecoveryConflictDeadlock(void)
476479
{
477-
Assert(!InRecovery);
480+
Assert(!InRecovery);/* do not call in Startup process */
478481

479482
if (!HoldingBufferPinThatDelaysRecovery())
480483
return;
481484

482-
LWLockRelease(partitionLock);
483-
484485
/*
485486
* Error message should match ProcessInterrupts() but we avoid calling
486487
* that because we aren't handling an interrupt at this point. Note that

‎src/backend/storage/lmgr/lock.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -829,13 +829,6 @@ LockAcquireExtended(const LOCKTAG *locktag,
829829
returnLOCKACQUIRE_NOT_AVAIL;
830830
}
831831

832-
/*
833-
* In Hot Standby perform early deadlock detection in normal backends.
834-
* If deadlock found we release partition lock but do not return.
835-
*/
836-
if (RecoveryInProgress()&& !InRecovery)
837-
CheckRecoveryConflictDeadlock(partitionLock);
838-
839832
/*
840833
* Set bitmask of locks this process already holds on this object.
841834
*/

‎src/backend/storage/lmgr/proc.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,15 @@ ProcSleep(LOCALLOCK *locallock, LockMethod lockMethodTable)
927927
*/
928928
LWLockRelease(partitionLock);
929929

930+
/*
931+
* Also, now that we will successfully clean up after an ereport, it's
932+
* safe to check to see if there's a buffer pin deadlock against the
933+
* Startup process. Of course, that's only necessary if we're doing
934+
* Hot Standby and are not the Startup process ourselves.
935+
*/
936+
if (RecoveryInProgress()&& !InRecovery)
937+
CheckRecoveryConflictDeadlock();
938+
930939
/* Reset deadlock_state before enabling the signal handler */
931940
deadlock_state=DS_NOT_YET_CHECKED;
932941

‎src/include/storage/standby.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ extern void ResolveRecoveryConflictWithDatabase(Oid dbid);
3535

3636
externvoidResolveRecoveryConflictWithBufferPin(void);
3737
externvoidSendRecoveryConflictWithBufferPin(ProcSignalReasonreason);
38-
externvoidCheckRecoveryConflictDeadlock(LWLockIdpartitionLock);
38+
externvoidCheckRecoveryConflictDeadlock(void);
3939

4040
/*
4141
* Standby Rmgr (RM_STANDBY_ID)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp