From 82b3684672d1de55d244f9908d1bb327ff6acd1d Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 16 Jul 2007 21:09:50 +0000 Subject: [PATCH] Add comments spelling out why it's a good idea to release multiple partition locks in reverse order. --- src/backend/storage/lmgr/lock.c | 10 ++++++++-- src/backend/storage/lmgr/proc.c | 10 ++++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/backend/storage/lmgr/lock.c b/src/backend/storage/lmgr/lock.c index fa062a1f7b..a4a0910d39 100644 --- a/src/backend/storage/lmgr/lock.c +++ b/src/backend/storage/lmgr/lock.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.176 2007/02/01 19:10:28 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/storage/lmgr/lock.c,v 1.177 2007/07/16 21:09:50 tgl Exp $ * * NOTES * A lock table is a shared memory hash table. When @@ -2119,7 +2119,13 @@ GetLockStatusData(void) el++; } - /* And release locks */ + /* + * And release locks. We do this in reverse order for two reasons: + * (1) Anyone else who needs more than one of the locks will be trying + * to lock them in increasing order; we don't want to release the other + * process until it can get all the locks it needs. + * (2) This avoids O(N^2) behavior inside LWLockRelease. + */ for (i = NUM_LOCK_PARTITIONS; --i >= 0;) LWLockRelease(FirstLockMgrLock + i); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 367c0e6cf8..6e7efe6d6c 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.190 2007/06/19 22:01:15 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/storage/lmgr/proc.c,v 1.191 2007/07/16 21:09:50 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1168,9 +1168,11 @@ CheckDeadLock(void) } /* - * Release locks acquired at head of routine. Order is not critical, so - * do it back-to-front to avoid waking another CheckDeadLock instance - * before it can get all the locks. + * And release locks. We do this in reverse order for two reasons: + * (1) Anyone else who needs more than one of the locks will be trying + * to lock them in increasing order; we don't want to release the other + * process until it can get all the locks it needs. + * (2) This avoids O(N^2) behavior inside LWLockRelease. */ check_done: for (i = NUM_LOCK_PARTITIONS; --i >= 0;) -- 2.40.0