diff --git a/src/backend/storage/lmgr/deadlock.c b/src/backend/storage/lmgr/deadlock.c index 5e49c78905..2d6a282d0a 100644 --- a/src/backend/storage/lmgr/deadlock.c +++ b/src/backend/storage/lmgr/deadlock.c @@ -214,7 +214,7 @@ InitDeadLockChecking(void) * and (b) we are typically invoked inside a signal handler. */ DeadLockState -DeadLockCheck(PGPROC *proc) +DeadLockCheck(PGPROC *proc, bool readonly) { int i, j; @@ -245,6 +245,16 @@ DeadLockCheck(PGPROC *proc) return DS_HARD_DEADLOCK; /* cannot find a non-deadlocked state */ } + if (readonly) + { + if (nWaitOrders > 0) + return DS_SOFT_DEADLOCK; + else if (blocking_autovacuum_proc != NULL) + return DS_BLOCKED_BY_AUTOVACUUM; + else + return DS_NO_DEADLOCK; + } + /* Apply any needed rearrangements of wait queues */ for (i = 0; i < nWaitOrders; i++) { diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 5f6727d501..a95bd99f8f 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -1665,6 +1665,7 @@ static void CheckDeadLock(void) { int i; + bool shared = true; /* * Acquire exclusive lock on the entire shared lock data structures. Must @@ -1677,7 +1678,9 @@ CheckDeadLock(void) * interrupts. */ for (i = 0; i < NUM_LOCK_PARTITIONS; i++) - LWLockAcquire(LockHashPartitionLockByIndex(i), LW_EXCLUSIVE); + LWLockAcquire(LockHashPartitionLockByIndex(i), LW_SHARED); + +retry: /* * Check to see if we've been awoken by anyone in the interim. @@ -1700,10 +1703,20 @@ CheckDeadLock(void) #endif /* Run the deadlock check, and set deadlock_state for use by ProcSleep */ - deadlock_state = DeadLockCheck(MyProc); + deadlock_state = DeadLockCheck(MyProc, shared); if (deadlock_state == DS_HARD_DEADLOCK) { + if (shared) + { + shared = false; + for (i = NUM_LOCK_PARTITIONS; --i >= 0;) + LWLockRelease(LockHashPartitionLockByIndex(i)); + for (i = 0; i < NUM_LOCK_PARTITIONS; i++) + LWLockAcquire(LockHashPartitionLockByIndex(i), LW_EXCLUSIVE); + goto retry; + } + /* * Oops. We have a deadlock. * diff --git a/src/include/storage/lock.h b/src/include/storage/lock.h index 765431e299..a501142059 100644 --- a/src/include/storage/lock.h +++ b/src/include/storage/lock.h @@ -564,7 +564,7 @@ extern void lock_twophase_postabort(TransactionId xid, uint16 info, extern void lock_twophase_standby_recover(TransactionId xid, uint16 info, void *recdata, uint32 len); -extern DeadLockState DeadLockCheck(PGPROC *proc); +extern DeadLockState DeadLockCheck(PGPROC *proc, bool readonly); extern PGPROC *GetBlockingAutoVacuumPgproc(void); extern void DeadLockReport(void) pg_attribute_noreturn(); extern void RememberSimpleDeadLock(PGPROC *proc1,