From: Alvaro Herrera <alvherre@2ndquadrant.com>
To: Andres Freund <andres@2ndquadrant.com>
Cc: Erik Rijkers <er@xs4all.nl>
Cc: Kevin Grittner <kgrittn@mail.com>
Cc: pgsql-hackers@postgresql.org
Subject: Re: foreign key locks
Date: Fri, 11 Jan 2013 13:10:49 -0300
Message-ID: <20130111161049.GD4208@alvh.no-ip.org> (raw)
In-Reply-To: <20130111151930.GB6049@awork2.anarazel.de>
References: <20121129152326.69330@gmx.com>
<20121129160220.GA4942@alvh.no-ip.org>
<20121129161654.GB4942@alvh.no-ip.org>
<b1a78c715f9195e6f96546c8e723afd8.squirrel@webmail.xs4all.nl>
<20121228204847.GD4150@alvh.no-ip.org>
<20130110210040.GB4110@alvh.no-ip.org>
<20130110212218.GE4329@awork2.anarazel.de>
<20130111151147.GB4208@alvh.no-ip.org>
<20130111151930.GB6049@awork2.anarazel.de>
List-Unsubscribe: <mailto:majordomo@postgresql.org?body=unsub%20pgsql-hackers>
Andres Freund wrote:
> No, I was thinking about an update without triggers present.
>
> T0: CREATE TABLE tbl(id serial pk, name text unique, data text);
> T1: BEGIN; -- read committed
> T1: UPDATE tbl SET name = 'foo' WHERE name = 'blarg'; /* key update of row id = 1 */
> T2: BEGIN; -- read committed
> T2: UPDATE tbl SET name = 'blarg', data = 'blarg' WHERE id = 1; /* no key update, waiting */
> T1: COMMIT;
> T2: /* UPDATE follows to updated row, due to the changed name its a key update now */
>
> Does that make sense?
So I guess your question is "is T2 now holding a TupleLockExclusive
lock?" To answer it, I turned your example into a isolationtester spec:
setup
{
CREATE TABLE tbl(id serial primary key, name text unique, data text);
INSERT INTO tbl VALUES (1, 'blarg', 'no data');
}
teardown
{
DROP TABLE tbl;
}
session "s1"
step "s1b" { BEGIN; }
step "s1u" { UPDATE tbl SET name = 'foo' WHERE name = 'blarg'; }
step "s1c" { COMMIT; }
session "s2"
step "s2b" { BEGIN; }
step "s2u" { UPDATE tbl SET name = 'blarg', data = 'blarg' WHERE id = 1; }
step "s2c" { COMMIT; }
session "s3"
step "s3l" { SELECT * FROM tbl FOR KEY SHARE; }
permutation "s1b" "s1u" "s2b" "s2u" "s1c" "s3l" "s2c"
And the results:
Parsed test spec with 3 sessions
starting permutation: s1b s1u s2b s2u s1c s3l s2c
step s1b: BEGIN;
step s1u: UPDATE tbl SET name = 'foo' WHERE name = 'blarg';
step s2b: BEGIN;
step s2u: UPDATE tbl SET name = 'blarg', data = 'blarg' WHERE id = 1; <waiting ...>
step s1c: COMMIT;
step s2u: <... completed>
step s3l: SELECT * FROM tbl FOR KEY SHARE; <waiting ...>
step s2c: COMMIT;
step s3l: <... completed>
id name data
1 blarg blarg
So session 3 is correctly waiting for session 2 to finish before being
ablt to grab its FOR KEY SHARE lock, indicating that session 2 is
holding a FOR UPDATE lock. Good.
If I change session 1 to update the data column instead of name, session
3 no longer needs to wait for session 2, meaning session 2 now only
grabs a FOR NO KEY UPDATE lock. Also good.
--
Álvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-hackers@postgresql.org
Cc: alvherre@2ndquadrant.com, andres@2ndquadrant.com, er@xs4all.nl, kgrittn@mail.com
Subject: Re: foreign key locks
In-Reply-To: <20130111161049.GD4208@alvh.no-ip.org>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox