Re: BUG #13723: "duplicate key" error occurs when update delete and insert the same row concurrently

From: chenhj <chjischj(at)163(dot)com>
To: "Jeff Janes" <jeff(dot)janes(at)gmail(dot)com>
Cc: "Tom Lane" <tgl(at)sss(dot)pgh(dot)pa(dot)us>, "pgsql-bugs(at)postgresql(dot)org" <pgsql-bugs(at)postgresql(dot)org>
Subject: Re: BUG #13723: "duplicate key" error occurs when update delete and insert the same row concurrently
Date: 2015-10-27 15:03:23
Message-ID: 5adc38f6.16e.150a9d339b0.Coremail.chjischj@163.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Hi,Jeff

> That is true only if the UPDATE actually updates the row. If you log the query completion tags, I think you will
> find the error is preceded by an UPDATE of zero rows. Now you could argue that this itself is a violation:
> that if a single statement sees that a row was deleted it is obliged to also see the row that was inserted
> in the same transaction as the deletion. But this is documented, and is unlikely to change.

My test result is just as you said, as the following:

test9.sql:
---------------------------------------
begin;
select * from tb1 where id=1;
update tb1 set c=2 where id=1;
delete from tb1 where id=1;
insert into tb1 values(1,2);
commit;
begin;
select * from tb1 where id=1;
update tb1 set c=2 where id=1;
delete from tb1 where id=1;
insert into tb1 values(1,2);
commit;
...
---------------------------------------

[postgres(at)localhost ~]$ psql -f test9.sql >a1.log 2>&1 &
[postgres(at)localhost ~]$ psql -f test9.sql >a2.log 2>&1 &

a2.log:
---------------------------------------
...
BEGIN
id | c
----+---
1 | 2
(1 row)

UPDATE 0
DELETE 0
psql:test9.sql:17: ERROR: duplicate key value violates unique constraint "tb1_pkey"
DETAIL: Key (id)=(1) already exists.
ROLLBACK
...
---------------------------------------

Even "EXPLICITLY" add "select ... for update" at first, "duplicate key " error still ocurrs.

test10.sql:
---------------------------------------
begin;
select * from tb1 where id=1 for update;
update tb1 set c=2 where id=1;
delete from tb1 where id=1;
insert into tb1 values(1,2);
commit;
begin;
select * from tb1 where id=1 for update;
update tb1 set c=2 where id=1;
delete from tb1 where id=1;
insert into tb1 values(1,2);
commit;
...
---------------------------------------

[postgres(at)localhost ~]$ psql -f test10.sql >b1.log 2>&1 &
[postgres(at)localhost ~]$ psql -f test10.sql >b2.log 2>&1 &

b1.log:
---------------------------------------
...
BEGIN
id | c
----+---
(0 rows)

UPDATE 0
DELETE 0
psql:test10.sql:29: ERROR: duplicate key value violates unique constraint "tb1_pkey"
DETAIL: Key (id)=(1) already exists.
ROLLBACK
...
---------------------------------------

So, "select * from tb1 where id=1 for update" also could see an inconsistent snapshot (sort of "Dirty Read").

Best Regard,
Chen Huajun

In response to

Browse pgsql-bugs by date

  From Date Subject
Next Message brown 2015-10-27 19:39:19 BUG #13741: vacuumdb does not accept valid password
Previous Message michael 2015-10-27 09:22:08 BUG #13739: Recurring corrupted page pointer panics on hot-standby replica