Skip site navigation (1) Skip section navigation (2)

Re: [HACKERS] Re: [PATCHES] patches for 6.2.1p6

From: Bruce Momjian <maillist(at)candle(dot)pha(dot)pa(dot)us>
To: dz(at)cs(dot)unitn(dot)it (Massimo Dal Zotto)
Cc: hackers(at)postgreSQL(dot)org
Subject: Re: [HACKERS] Re: [PATCHES] patches for 6.2.1p6
Date: 1998-03-19 19:47:10
Message-ID: 199803191947.OAA14598@candle.pha.pa.us (view raw or flat)
Thread:
Lists: pgsql-hackers
> I have already applied all my old patches against 6.3 except the lock
> patch. The lock code has changed and I have to verify if my patches are

Great.

> still compatible. It will take some time and I haven't very much.
> I found also an interesting bug in the notify code. I will post the new
> patches when I find some spare time to verify them.
> Could you please send me some documentation on the new lock and deadlock
> code in the meantime ?

Here is some comments from storage/lmgr/lock.c:DeadLockCheck().  This
was a real mind-bender for me.  It finds holders of the lock it has been
waiting on, and checks to see if any of those holders is waiting on the
lock I own.  If not, it then checks all the holders of locks these new
processes are waiting on, and checks to see if they are waiting on my
lock, and it continues until it has traced all backend process id's
related to my lock.  I have a static checked_procs[] array that keeps
track of what I have checked so I don't loop.  The code is recursive.

The new wait queue handling is documented in storage/lmgr/lock.c:ProcSleep().

---------------------------------------------------------------------------

 * This code takes a list of locks a process holds, and the lock that
 * the process is sleeping on, and tries to find if any of the processes
 * waiting on its locks hold the lock it is waiting for.  If no deadlock
 * is found, it goes on to look at all the processes waiting on their locks.
 *
 * We have already locked the master lock before being called.
 */
bool
DeadLockCheck(SHM_QUEUE *lockQueue, LOCK *findlock, bool skip_check)


---------------------------------------------------------------------------

        /*
         * This is our only check to see if we found the lock we want.
         *
         * The lock we are waiting for is already in MyProc->lockQueue so we
         * need to skip it here.  We are trying to find it in someone
         * else's lockQueue.
         */
        if (lock == findlock && !skip_check)

 
---------------------------------------------------------------------------

                    /*
                     * For findlock's wait queue, we are interested in
                     * procs who are blocked waiting for a write-lock on
                     * the table we are waiting on, and already hold a
                     * lock on it. We first check to see if there is an
                     * escalation deadlock, where we hold a readlock and
                     * want a writelock, and someone else holds readlock
                     * on the same table, and wants a writelock.
                     *
                     * Basically, the test is, "Do we both hold some lock on
                     * findlock, and we are both waiting in the lock
                     * queue?"
                     */

---------------------------------------------------------------------------

                         * For non-MyProc entries, we are looking only
                         * waiters, not necessarily people who already
                         * hold locks and are waiting. Now we check for
                         * cases where we have two or more tables in a
                         * deadlock.  We do this by continuing to search
                         * for someone holding a lock
                         */
                        if (DeadLockCheck(&(proc->lockQueue), findlock, false))

---------------------------------------------------------------------------

    /*
     * If the first entries in the waitQueue have a greater priority than
     * we have, we must be a reader, and they must be a writers, and we
     * must be here because the current holder is a writer or a reader but
     * we don't share shared locks if a writer is waiting. We put
     * ourselves after the writers.  This way, we have a FIFO, but keep
     * the readers together to give them decent priority, and no one
     * starves.  Because we group all readers together, a non-empty queue
     * only has a few possible configurations:
     *
     * [readers] [writers] [readers][writers] [writers][readers]
     * [writers][readers][writers]
     *
     * In a full queue, we would have a reader holding a lock, then a writer
     * gets the lock, then a bunch of readers, made up of readers who
     * could not share the first readlock because a writer was waiting,
     * and new readers arriving while the writer had the lock.
     *
     */

-- 
Bruce Momjian                          |  830 Blythe Avenue
maillist(at)candle(dot)pha(dot)pa(dot)us              |  Drexel Hill, Pennsylvania 19026
  +  If your life is a hard drive,     |  (610) 353-9879(w)
  +  Christ can be your backup.        |  (610) 853-3000(h)

In response to

pgsql-hackers by date

Next:From: Bruce MomjianDate: 1998-03-19 19:50:11
Subject: Re: AW: [HACKERS] varchar() vs char16 performance
Previous:From: Maurice GittensDate: 1998-03-19 18:50:24
Subject: Re: [HACKERS] Re: [QUESTIONS] Inheriting Triggers

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group