From: | Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
---|---|
To: | Tomasz Zielonka <tomek(at)mult(dot)i(dot)pl> |
Cc: | PostgreSQL bugs <pgsql-bugs(at)postgresql(dot)org> |
Subject: | Re: Error in backend/storage/lmgr/proc.c: ProcSleep() |
Date: | 2001-09-04 02:37:11 |
Message-ID: | 24206.999571031@sss.pgh.pa.us |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-bugs |
Tomasz Zielonka <tomek(at)mult(dot)i(dot)pl> writes:
> Platform: PostgreSQL 7.1.3, Linux 2.4.8, egcs 2.91.66
> PostgreSQL forgets to release lock until shutdown in this scenario:
Good catch! This has been broken since 7.1 ... surprising that no one
discovered the problem sooner.
I think that rather than removing the early-deadlock-detection code as
you suggest, it's better to make it work correctly. I have applied a
patch that allows RemoveFromWaitQueue() to be used, so that the recovery
path is the same as if HandleDeadLock had been invoked.
regards, tom lane
*** /home/postgres/pgsql/src/backend/storage/lmgr/proc.c.orig Fri Jul 6 17:04:26 2001
--- /home/postgres/pgsql/src/backend/storage/lmgr/proc.c Mon Sep 3 22:26:57 2001
***************
*** 506,521 ****
SPINLOCK spinlock = lockctl->masterLock;
PROC_QUEUE *waitQueue = &(lock->waitProcs);
int myHeldLocks = MyProc->heldLocks;
PROC *proc;
int i;
-
#ifndef __BEOS__
struct itimerval timeval,
dummy;
-
#else
bigtime_t time_interval;
-
#endif
/*
--- 506,519 ----
SPINLOCK spinlock = lockctl->masterLock;
PROC_QUEUE *waitQueue = &(lock->waitProcs);
int myHeldLocks = MyProc->heldLocks;
+ bool early_deadlock = false;
PROC *proc;
int i;
#ifndef __BEOS__
struct itimerval timeval,
dummy;
#else
bigtime_t time_interval;
#endif
/*
***************
*** 535,541 ****
* immediately. This is the same as the test for immediate grant in
* LockAcquire, except we are only considering the part of the wait
* queue before my insertion point.
- *
*/
if (myHeldLocks != 0)
{
--- 533,538 ----
***************
*** 550,558 ****
/* Must I wait for him ? */
if (lockctl->conflictTab[lockmode] & proc->heldLocks)
{
! /* Yes, can report deadlock failure immediately */
! MyProc->errType = STATUS_ERROR;
! return STATUS_ERROR;
}
/* I must go before this waiter. Check special case. */
if ((lockctl->conflictTab[lockmode] & aheadRequests) == 0 &&
--- 547,560 ----
/* Must I wait for him ? */
if (lockctl->conflictTab[lockmode] & proc->heldLocks)
{
! /*
! * Yes, so we have a deadlock. Easiest way to clean up
! * correctly is to call RemoveFromWaitQueue(), but we
! * can't do that until we are *on* the wait queue.
! * So, set a flag to check below, and break out of loop.
! */
! early_deadlock = true;
! break;
}
/* I must go before this waiter. Check special case. */
if ((lockctl->conflictTab[lockmode] & aheadRequests) == 0 &&
***************
*** 600,606 ****
MyProc->waitHolder = holder;
MyProc->waitLockMode = lockmode;
! MyProc->errType = STATUS_OK;/* initialize result for success */
/* mark that we are waiting for a lock */
waitingForLock = true;
--- 602,620 ----
MyProc->waitHolder = holder;
MyProc->waitLockMode = lockmode;
! MyProc->errType = STATUS_OK; /* initialize result for success */
!
! /*
! * If we detected deadlock, give up without waiting. This must agree
! * with HandleDeadLock's recovery code, except that we shouldn't release
! * the semaphore since we haven't tried to lock it yet.
! */
! if (early_deadlock)
! {
! RemoveFromWaitQueue(MyProc);
! MyProc->errType = STATUS_ERROR;
! return STATUS_ERROR;
! }
/* mark that we are waiting for a lock */
waitingForLock = true;
From | Date | Subject | |
---|---|---|---|
Next Message | pgsql-bugs | 2001-09-04 03:33:19 | Bug #437: postgresql-python rpm fails on mx dependency |
Previous Message | John Summerfield | 2001-09-04 00:34:16 | Logging problems in PostgreSQL 7.2devel |