Re: postgresql locks the whole table! - Mailing list pgsql-general

From Bruce Momjian
Subject Re: postgresql locks the whole table!
Date
Msg-id 200312061217.hB6CHiB03688@candle.pha.pa.us
Whole thread Raw
In response to Re: postgresql locks the whole table!  (Greg Stark <gsstark@mit.edu>)
Responses Re: postgresql locks the whole table!
List pgsql-general
Greg Stark wrote:
>
> Dr NoName <spamacct11@yahoo.com> writes:
>
> > My question is why??? The two insert operations do not
> > conflict with each other (at least not in the
> > real-world situation). Also, why does the foreign key
> > make a difference?
>
> It's not locking the whole table, it's locking the record that the foreign key
> references. Note that they're both referencing the same foreign key.
>
> It does this because it's afraid someone will go and delete that key before
> the transaction commits. It has to take a lock that will prevent someone from
> deleting the record (or updating the referenced column).
>
> Unfortunately the only lock to choose from is an exclusive write lock. That's
> overkill as you've noticed. I think this is something multiple people would
> like to fix by introducing shared locks, but I wouldn't expect a solution
> soon.

As I remember the implementation problem is that we do an exclusive row
lock right now by putting the transaction id on the row and set a
special row-lock bit in the tuple.  Shared locks need to store multiple
transaction ids, and that is where we are stuck.  Shared memory is of
finite size, and the number of proc/row combinations is infinite, so it
seems we will need some shared stucture with backing store to disk, and
that will be slow.

You know the maximum number of backends on startup, but I don't see how
that helps us.  If we could somehow know the unique combinations of
those backend ids that would be used for any row, we could reserve a
range of transactions ids to map them, but the number of combinations is
too large.

Our xid/command-counter is currently 64 bits, so if we only had a
maximum of 64 backends, we could use those bits to mark the backends
holding the locks rather than put the xid in there.  Of course, the
maximum number backends can change over time, so that isn't really a
solution but more a brainstorm, but I do think shared memory bitmaps
might be in the final solution.

One idea would be to allocate 10k of shared memory for a shared lock
bitmap.  Assuming a max 100 backend, that is 2500 lock combinations,
numbered 0-2499.  We would put the bitmap number on the rows rather than
the xid.  Of course, problems are that there are only 2500 combinations
supported, and transactions have to get an exclusive lock on transaction
commit to clear their backend bits from the bitmap table so the rows can
be reused. Another refinement would be to use the row xid to store
either the xid for single backend locks, and use the bitmap table number
only when there is sharing of row locks by multiple backends.  That
might reduce the contention on the bitmap table.  If a backend wasn't
involved in shared locks, its bit wouldn't be set in the bitmap table
and it has nothing to do, and it can read the table without a lock.

--
  Bruce Momjian                        |  http://candle.pha.pa.us
  pgman@candle.pha.pa.us               |  (610) 359-1001
  +  If your life is a hard drive,     |  13 Roberts Road
  +  Christ can be your backup.        |  Newtown Square, Pennsylvania 19073

pgsql-general by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: transaction in progress
Next
From: "Arjen van der Meijden"
Date:
Subject: Re: Making a tree with "millions and millions" of dynamic