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

FOREIGN KEY and AccessExclusiveLock

From: Achilleus Mantzios <achill(at)matrix(dot)gatewaynet(dot)com>
To: pgsql-sql(at)postgresql(dot)org
Subject: FOREIGN KEY and AccessExclusiveLock
Date: 2004-09-28 06:14:20
Message-ID: (view raw, whole thread or download thread mbox)
Lists: pgsql-sql
Hi, all the below are for PostgreSQL 7.4.2.

I noticed that during 
ALTER TABLE kid ADD CONSTRAINT "parcon" FOREIGN KEY (parid) on parent(id)
pgsql tries to acquire an AccessExclusiveLock on *both* kid
(which is pretty natural since it adheres with the docs, and it is an 
alter command) *and* parent.

Whats the purpose of the AccessExclusiveLock on parent table?
Is there a way this alter command will affect parent's data or schema?

Lets see a simple example:

dynacom=# CREATE TABLE parent(id int PRIMARY KEY);
dynacom=# CREATE TABLE kid(parid int);

Then in session 1:

dynacom=# BEGIN ;
dynacom=# SELECT * from parent ;
(0 rows)


In Session 2:
dynacom=# BEGIN ;
dynacom=# ALTER TABLE kid ADD CONSTRAINT "parcon" FOREIGN KEY (parid) 
references parent(id);

*here Session 2 is deadlocked*

In Session 1:
dynacom=# SELECT c.relname,l.mode,l.granted from pg_locks l,pg_class c 
where l.relation=c.oid;
   relname    |        mode         | granted
 kid          | AccessExclusiveLock | t
 pg_locks     | AccessShareLock     | t
 pg_class     | AccessShareLock     | t
 parent       | AccessExclusiveLock | f
 parent       | AccessShareLock     | t
 pg_namespace | AccessShareLock     | t
(6 rows)


Again in Session 1:

dynacom=# end;

In Session 2:

Now imagine that session 2 is "called" by session 1, with commiting
after session 2 is done, we have clearly a deadlock situation.

The question is why an AccessExclusiveLock must be created
for the FK table?

Actually it puzzled me alot, since for me Session 1 is a java program
"executing" XML in various forms, one of them being plain UNIX (exec())
commands, which in turn sometimes are psql commands.

It was hard to imagine that an innocent select on the parent table in the 
java program
and an alter table on a child table as a pgsql UNIX command would cause a 
deadlock situation.

The natural workaround was to immediately commit in the java program
after select and before UNIX command (psql) is executed.



In response to


pgsql-sql by date

Next:From: Achilleus MantziosDate: 2004-09-28 12:24:13
Subject: Re: Best way to know if there is a row
Previous:From: sreejith sDate: 2004-09-28 03:27:50
Subject: Postgres Doubt

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