RE: [HACKERS] Lock freeze ? in MVCC - Mailing list pgsql-hackers

From Hiroshi Inoue
Subject RE: [HACKERS] Lock freeze ? in MVCC
Date
Msg-id 001001be9139$dc2aabe0$2801007e@cadzone.tpf.co.jp
Whole thread Raw
In response to Re: [HACKERS] Lock freeze ? in MVCC  (Vadim Mikheev <vadim@krs.ru>)
List pgsql-hackers
> -----Original Message-----
> From: root@sunpine.krs.ru [mailto:root@sunpine.krs.ru]On Behalf Of Vadim
> Mikheev
> Sent: Wednesday, April 28, 1999 12:37 PM
> To: Bruce Momjian
> Cc: Inoue@tpf.co.jp; pgsql-hackers@postgreSQL.org
> Subject: Re: [HACKERS] Lock freeze ? in MVCC
>
>
> Bruce Momjian wrote:
> >
> > >
> > > if we already have some lock with priority X and new requested
> > > lock has priority Y, Y <= X, then lock must be granted.
> > >
> > > Also, I would get rid of lockReadPriority stuff...
> > >
> > > Bruce, what do you think?
> >
> > This sounds correct.  I thought I needed to have the queue ordering
> > changed so that row-level locks are queued before table-level locks,
> > because there could be cases of lock escalation from row-level to
> > table-level.
> >
> > However, it seems the problem is that readers don't share locks if
> > writers are waiting.  With table-level locks, you never escalated a read
> > lock because you had already locked the entire table, while now you do.
> > Perhaps we can tell the system not to share read locks unless you are
> > sharing your own lock due to a lock escalation.
>
> There is no row-level locks: all locks over tables are
> table-level ones, btree & hash use page-level locks, but
> never do page->table level lock escalation.
>
> However, I'm not sure that proposed changes will help in the next case:
>
> session-1 => begin;
> session-1 => insert into tt values (1);    --RowExclusiveLock
>
> session-2 => begin;
> session-2 => insert into tt values (2);    --RowExclusiveLock
>
> session-3 => begin;
> session-3 => lock table tt;            --AccessExclusiveLock
>                 (conflicts with 1 & 2)
>                                 ^
> session-1 => lock table tt in share mode;    --ShareLock
>                 (conflicts with 2 & 3)
>                                     ^
> This is deadlock situation and must be handled by
> DeadLockCheck().
>

It's really a deadlock ?
Certainly end/abort of session-2 doesn't wakeup session-1/session3.
I think it's due to the following code in ProcLockWakeup().
      while ((queue_size--) && (proc))       {
               /*                * This proc will conflict as the previous one did, don't
even                * try.                */               if (proc->token == last_locktype)
continue;
               /*                * This proc conflicts with locks held by others, ignored.                */
  if (LockResolveConflicts(lockmethod,                                                                lock,
 

proc->token,                                                                proc->xid,

(XIDLookupEnt *
) NULL) != STATUS_OK)               {                       last_locktype = proc->token;
continue;              }
 

Once LockResolveConflicts() doesn't return STATUS_OK,proc
is not changed and only queue_size-- is executed(never try
to wakeup other procs).

After inserting the code such asproc = (PROC *) MAKE_PTR(proc->links.prev);
before continue statements,ProcLockWakeup() triggerd
by end/abort of session-2 could try to wakeup session-1.

Comments ?

Thanks.

Hiroshi Inoue
Inoue@tpf.co.jp



pgsql-hackers by date:

Previous
From: Brook Milligan
Date:
Subject: rule plan string too big?
Next
From: Tom Lane
Date:
Subject: Re: [HACKERS] Hacker found bug in Postgres ?