473,781 Members | 2,335 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

postgresql locks the whole table!

Help!

I have a table that multiple processes must be able to
write to concurrently. However, it for some reason
gets locked in exclusive mode. I narrowed it down to
one SQL statement + some weirdness with foreign keys.
To debug this, I opened two psql sessions and typed in
the sql statements manually. Here is the situation:

CREATE TABLE take2
(
id serial not null,
timestamp timestamp NOT NULL DEFAULT now(),
description text,
iteration smallint,
asset_id integer,
-- FOREIGN KEY (asset_id) REFERENCES public.asset
(id), -- ON UPDATE CASCADE ON DELETE CASCADE,

primary key(id)
);

(notice that the foreign key statement is commented
out). Just to make sure I am not causing excessive
locking unintentionally , I did "set transaction
isolation level read committed" in both psql shells
(default was serializable).

Now I type the following commands:

shell 1:

1. BEGIN
2. insert into take2 values(default, 'now()', 't1', 1,
1);
shell 2:

1. BEGIN
2. insert into take2 values(default, 'now()', 't2', 1,
1);

this works.

However, if I uncomment the foreign key statement and
recreate the table, then the second shell blocks on
the insert statement. As soon as the first transaction
is either committed or rolled back, the insert
statement goes through.

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?

looking at pg_locks, I see the following:

relation | database | transaction | pid |
mode | granted
----------+----------+-------------+-------+------------------+---------
39356 | 34862 | NULL | 18671 |
AccessShareLock | t
39356 | 34862 | NULL | 18671 |
RowExclusiveLoc k | t
NULL | NULL | 9914 | 18671 |
ExclusiveLock | t
39354 | 34862 | NULL | 18671 |
AccessShareLock | t
34886 | 34862 | NULL | 18671 |
AccessShareLock | t
34886 | 34862 | NULL | 18671 |
RowShareLock | t
16759 | 34862 | NULL | 18671 |
AccessShareLock | t
(7 rows)

Where does the ExclusiveLock come from? What is being
locked?

It is critical for us to run multiple transactions
concurrently -- in fact that was one of the reasons
for choosing PostgreSQL over MySQL. There are a lot of
file system operations and other processing that need
to happen along side the DB transaction. Those things
take a long time, so there is typically up to a
5-minute span between BEGIN and COMMIT. We cannot
block the production floor for 5 minutes when a user
tries to run a transaction, so as a temporary fix, we
got rid of the begin/commit. But obviously we would
rather not lose the atomicity.

So, in summary:
why does PostgreSQL lock the entire table?
what can we do about it?

This was tested on PostgreSQL 7.4.0 and 7.3.2.

thanks in advance,

Eugene

_______________ _______________ ____
Do you Yahoo!?
Free Pop-Up Blocker - Get it now
http://companion.yahoo.com/

---------------------------(end of broadcast)---------------------------
TIP 9: the planner will ignore your desire to choose an index scan if your
joining column's datatypes do not match

Nov 12 '05
17 12833
Greg Stark wrote:

Dr NoName <sp********@yah oo.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
pg***@candle.ph a.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073

---------------------------(end of broadcast)---------------------------
TIP 9: the planner will ignore your desire to choose an index scan if your
joining column's datatypes do not match

Nov 12 '05 #11
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.


The way I understand it, is that you're having trouble storing all of
the xids in the row; right now you just store one and mark it "locked".
If you were able to store several, but not necessarily all xids in all
cases, wouldn't that be a big improvement? The xids not in the list
would lock, as they do now, and the ones in the list would show an
improvement by sharing the lock, right?

Otherwise I don't entirely understand what you're saying.

Regards,
Jeff Davis

---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings

Nov 12 '05 #12
Jeff Davis wrote:
The way I understand it, is that you're having trouble storing all of
the xids in the row; right now you just store one and mark it "locked".
If you were able to store several, but not necessarily all xids in all
cases, wouldn't that be a big improvement? The xids not in the list
would lock, as they do now, and the ones in the list would show an
improvement by sharing the lock, right?

Otherwise I don't entirely understand what you're saying.


Yes, we could do that but we really want something that isn't going to
work only some of the time. Ideally we want something that can share no
matter how many backends try.

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

---------------------------(end of broadcast)---------------------------
TIP 8: explain analyze is your friend

Nov 12 '05 #13

It's not strictly necessary to have a list of all xids at all. The normal
"shared read lock" is just "take the write lock, increment the readers
counter, unlock" Anyone who wants to write has to wait (using, eg, a condition
variable) until the readers count goes to 0.

This gets the right semantics but without the debugging info of a list of
lockers. Other than debugging the only advantage I see to having the list of
lockers is for deadlock detection. Is that absolutely mandatory?

--
greg
---------------------------(end of broadcast)---------------------------
TIP 2: you can get off all lists at once with the unregister command
(send "unregister YourEmailAddres sHere" to ma*******@postg resql.org)

Nov 12 '05 #14
Greg Stark wrote:
It's not strictly necessary to have a list of all xids at all. The normal
"shared read lock" is just "take the write lock, increment the readers
counter, unlock" Anyone who wants to write has to wait (using, eg, a condition
variable) until the readers count goes to 0.

This gets the right semantics but without the debugging info of a list of
lockers. Other than debugging the only advantage I see to having the list of
lockers is for deadlock detection. Is that absolutely mandatory?


What happens if a backend is killed and never decrements its reference
count?

Mike Mascari
ma*****@mascari .com
---------------------------(end of broadcast)---------------------------
TIP 6: Have you searched our list archives?

http://archives.postgresql.org

Nov 12 '05 #15
On Sun, 7 Dec 2003, Greg Stark wrote:
It's not strictly necessary to have a list of all xids at all. The normal
"shared read lock" is just "take the write lock, increment the readers
counter, unlock" Anyone who wants to write has to wait (using, eg, a condition
variable) until the readers count goes to 0.
There are some storage/cleanup questions though. If that's stored in the
tuple header, what happens after a crash?

In addition, how should the locks be granted for a sequence like:
T1: get shared lock on row A
T2: get exclusive lock on row A
T3: get shared lock on row A
Does T3 get the lock or not? If it does, then you have the possibility of
freezing out T2 for a very long time and badly hurting update/delete
performance. If it doesn't, then how are you keeping track of the fact
that there are one or more people who want exclusive locks on the same
row that are "in front" of you?
This gets the right semantics but without the debugging info of a list of
lockers. Other than debugging the only advantage I see to having the list of
lockers is for deadlock detection. Is that absolutely mandatory?


I think so, yes, especially if we're going to use it for things like
foreign keys. It's too easy to get into a deadlock with foreign keys
(even when implemented through shared locks) and I think having undetected
deadlocks would be even worse than our current behavior. At least with
the current behavior you get an indication that something is wrong.

---------------------------(end of broadcast)---------------------------
TIP 7: don't forget to increase your free space map settings

Nov 12 '05 #16
> Greg Stark wrote:
This gets the right semantics but without the debugging info of a list of
lockers. Other than debugging the only advantage I see to having the list of
lockers is for deadlock detection. Is that absolutely mandatory?

No, deadlock detection is not optional.

Mike Mascari <ma*****@mascar i.com> writes: What happens if a backend is killed and never decrements its reference
count?


Even if it's not killed, how does it know to decrement the reference
count? You still need a list of all locked tuples *somewhere*. Perhaps
a technique like this would allow the list to not be in shared memory,
which is helpful, but it's far from an ideal solution.

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 8: explain analyze is your friend

Nov 12 '05 #17
Stephan Szabo <ss****@megazon e.bigpanda.com> writes:
In addition, how should the locks be granted for a sequence like:
T1: get shared lock on row A
T2: get exclusive lock on row A
T3: get shared lock on row A
Does T3 get the lock or not? If it does, then you have the possibility of
freezing out T2 for a very long time and badly hurting update/delete
performance.


Well this is a fundamental question that applies to any scheme to handle
shared locks. You get into all sorts of fun stuff like livelock and priority
inversion that real time systems folk invent just to torture programmers.

--
greg
---------------------------(end of broadcast)---------------------------
TIP 2: you can get off all lists at once with the unregister command
(send "unregister YourEmailAddres sHere" to ma*******@postg resql.org)

Nov 12 '05 #18

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
505
by: Alex Kovach | last post by:
This simple command always takes 0.30 seconds or longer: mysql> select foo from footable order by -foo limit 20; (get the 20 most recent foo's) This however, always takes 0.0 seconds: mysql> select foo from footable where foo>'2004-01-10' order by -foo limit 20;
1
3433
by: Danny | last post by:
I have a 90 by 40 graphic. I would like to make this a background in my table so this nice backround will cover the whole table like painting it etc. no matter how big or small I make it. Right now, it is showng just the image. How do I do this?
3
10886
by: Thomas Mlynarczyk | last post by:
Hello, How can I make an <a> element (containing text only, styled to be a box with a border) as big as the table cell in which it resides, *without* having specified any width/height (neither fixed nor percentage) for this table cell? Sizing the element to 100% width and height does not work, as the parent element's width and height are not specified. And yet, in this case at least, the width and height of the table cell are very...
1
1439
by: Joseph Shraibman | last post by:
Is there any way to force analyze to run on a whole table? In other words for large tables to avoid sampling? What happens if I run a vacuum analyze? ---------------------------(end of broadcast)--------------------------- TIP 7: don't forget to increase your free space map settings
22
18814
by: RayPower | last post by:
I'm having problem with using DAO recordset to append record into a table and subsequent code to update other tables in a transaction. The MDB is Access 2000 with the latest service pack of JET 4. The system is client/server, multiusers based. The MDBs are using record locking. Here is part of the code: Dim wkSpace As Workspace, db As Database Dim rstTrans As DAO.Recordset Set wkSpace = DBEngine.Workspaces(0)
8
12104
by: UJ | last post by:
I have a table with multiple cells and I want to draw a box around the entire table but not around the individual cells. How do I do that? TIA - Jeff.
19
8109
by: Martin Eyles | last post by:
Hi, I want to make a whole table a link, so that clicking anywhere on it takes you to another page. Unfortunately the way I initially thought of doing this involved invalid html. I have tried a second valid way, but the behaviour is not quite as good (at least not in firefox 1.5), with only the actual text being links. The examples of what I have tried can be found at http://www.bytronic.com/tests/links.html
4
3657
by: neelesh kumar | last post by:
sir, i have a table named tblexam. i want to sort the whole table records according to the field subcode in ascending order. docmd.runsql "update tblexam order by subcode asc" But it is showing syntax error. please help me.
4
3720
by: Hemant Shah | last post by:
Folks, Our client has a program that browses whole table from begining to end. The table has 1 million rows in it. REORGCHK does not show any problems. It has unique index defined on KEY0 column. If I use SELECT statement without OPTIMIZE FOR clause, then it uses temporary table to sort the data, but if I use OPTIMIZE clause then it uses index access without temporary table. If I use OPTIMIZE FOR more than 700 rows then it uses...
0
9636
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10306
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10075
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9931
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8961
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6727
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5504
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4037
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2869
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.