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

Commitc85c941

Browse files
Detect early deadlock in Hot Standby when Startup is already waiting. First
stage of required deadlock detection to allow re-enabling max_standby_delaysetting of -1, which is now essential in the absence of improved relation-specific conflict resoluton. Requested by Greg Stark et al.
1 parent034fffb commitc85c941

File tree

3 files changed

+46
-4
lines changed

3 files changed

+46
-4
lines changed

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

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Portions Copyright (c) 1994, Regents of the University of California
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/storage/ipc/standby.c,v 1.8 2010/01/29 17:10:05 sriggs Exp $
14+
* $PostgreSQL: pgsql/src/backend/storage/ipc/standby.c,v 1.9 2010/01/31 19:01:11 sriggs Exp $
1515
*
1616
*-------------------------------------------------------------------------
1717
*/
@@ -22,6 +22,7 @@
2222
#include"access/xlog.h"
2323
#include"miscadmin.h"
2424
#include"pgstat.h"
25+
#include"storage/bufmgr.h"
2526
#include"storage/lmgr.h"
2627
#include"storage/proc.h"
2728
#include"storage/procarray.h"
@@ -384,7 +385,7 @@ ResolveRecoveryConflictWithBufferPin(void)
384385
TimestampDifference(GetLatestXLogTime(),now,
385386
&standby_delay_secs,&standby_delay_usecs);
386387

387-
if (standby_delay_secs >=(long)MaxStandbyDelay)
388+
if (standby_delay_secs >=MaxStandbyDelay)
388389
SendRecoveryConflictWithBufferPin();
389390
else
390391
{
@@ -445,6 +446,39 @@ SendRecoveryConflictWithBufferPin(void)
445446
CancelDBBackends(InvalidOid,PROCSIG_RECOVERY_CONFLICT_BUFFERPIN, false);
446447
}
447448

449+
/*
450+
* In Hot Standby perform early deadlock detection. We abort the lock
451+
* wait if are about to sleep while holding the buffer pin that Startup
452+
* process is waiting for. The deadlock occurs because we can only be
453+
* waiting behind an AccessExclusiveLock, which can only clear when a
454+
* transaction completion record is replayed, which can only occur when
455+
* Startup process is not waiting. So if Startup process is waiting we
456+
* never will clear that lock, so if we wait we cause deadlock. If we
457+
* are the Startup process then no need to check for deadlocks.
458+
*/
459+
void
460+
CheckRecoveryConflictDeadlock(LWLockIdpartitionLock)
461+
{
462+
Assert(!InRecovery);
463+
464+
if (!HoldingBufferPinThatDelaysRecovery())
465+
return;
466+
467+
LWLockRelease(partitionLock);
468+
469+
/*
470+
* Error message should match ProcessInterrupts() but we avoid calling
471+
* that because we aren't handling an interrupt at this point. Note
472+
* that we only cancel the current transaction here, so if we are in a
473+
* subtransaction and the pin is held by a parent, then the Startup
474+
* process will continue to wait even though we have avoided deadlock.
475+
*/
476+
ereport(ERROR,
477+
(errcode(ERRCODE_QUERY_CANCELED),
478+
errmsg("canceling statement due to conflict with recovery"),
479+
errdetail("User transaction caused buffer deadlock with recovery.")));
480+
}
481+
448482
/*
449483
* -----------------------------------------------------
450484
* Locking in Recovery Mode

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.193 2010/01/29 19:45:12 sriggs Exp $
11+
* $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.194 2010/01/31 19:01:11 sriggs Exp $
1212
*
1313
* NOTES
1414
* A lock table is a shared memory hash table. When
@@ -814,6 +814,13 @@ LockAcquireExtended(const LOCKTAG *locktag,
814814
returnLOCKACQUIRE_NOT_AVAIL;
815815
}
816816

817+
/*
818+
* In Hot Standby perform early deadlock detection in normal backends.
819+
* If deadlock found we release partition lock but do not return.
820+
*/
821+
if (RecoveryInProgress()&& !InRecovery)
822+
CheckRecoveryConflictDeadlock(partitionLock);
823+
817824
/*
818825
* Set bitmask of locks this process already holds on this object.
819826
*/

‎src/include/storage/standby.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/storage/standby.h,v 1.6 2010/01/29 17:10:05 sriggs Exp $
10+
* $PostgreSQL: pgsql/src/include/storage/standby.h,v 1.7 2010/01/31 19:01:11 sriggs Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -31,6 +31,7 @@ extern void ResolveRecoveryConflictWithDatabase(Oid dbid);
3131

3232
externvoidResolveRecoveryConflictWithBufferPin(void);
3333
externvoidSendRecoveryConflictWithBufferPin(void);
34+
externvoidCheckRecoveryConflictDeadlock(LWLockIdpartitionLock);
3435

3536
/*
3637
* Standby Rmgr (RM_STANDBY_ID)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp