Re: Update with subselect sometimes returns wrong result - Mailing list pgsql-bugs
From | Andres Freund |
---|---|
Subject | Re: Update with subselect sometimes returns wrong result |
Date | |
Msg-id | 20131130214018.GJ31100@awork2.anarazel.de Whole thread Raw |
In response to | Re: Update with subselect sometimes returns wrong result (Tom Lane <tgl@sss.pgh.pa.us>) |
Responses |
Re: Update with subselect sometimes returns wrong result
Re: Update with subselect sometimes returns wrong result |
List | pgsql-bugs |
On 2013-11-30 12:57:44 -0500, Tom Lane wrote: > Oliver Seemann <oseemann@gmail.com> writes: > > Given the following table: > > > CREATE TABLE t1 (id INTEGER); > > INSERT INTO t1 VALUES (0), (1); > > > Then the following UPDATE should return exactly one row: > > > UPDATE t1 SET id = t1.id > > FROM (SELECT id FROM t1 LIMIT 1 FOR UPDATE) AS subset > > WHERE t1.id = subset.id > > RETURNING t1.id > > > And it does so, most of of the time. But when run repeatedly in a loop like > > in the attached script, then it will occasionally return 2 rows with two > > different id values, something the LIMIT 1 should prevent. In my tests it > > took from anywhere between 0 to 10 minutes and on average 1 to 2 minutes to > > trigger the problem. > > I failed to reproduce the claimed misbehavior in git tip of any active > branch. I'd like to think this means we fixed the problem in the last > two months, but I don't see anything that looks like a promising candidate > in the commit logs. Perhaps there is some important contributing factor > you've not mentioned --- nondefault postgresql.conf settings, for > instance. Looks reproducable here as well, manually executing VACUUMs on the table greatly speeds things up. Fails within seconds when doing so. So, it looks like the limit returns more than one row, it's not updating the same row twice. Slightly hacked up (probably python 2 only) version of the test script attached. I'll get to trying to write the release stuff rather then playing with more interesting things ;) new row at: (0,4) updated row from (0,2) to (0,1) iter 400 deleted row at: (0,1) deleted row at: (0,5) new row at: (0,1) new row at: (0,5) updated row from (0,1) to (0,3) iter 401 deleted row at: (0,2) deleted row at: (0,3) new row at: (0,2) new row at: (0,3) updated row from (0,1) to (0,3) iter 402 deleted row at: (0,2) deleted row at: (0,3) new row at: (0,2) new row at: (0,3) updated row from (0,4) to (0,1) iter 403 deleted row at: (0,1) deleted row at: (0,5) new row at: (0,1) new row at: (0,5) updated row from (0,1) to (0,3) iter 404 deleted row at: (0,2) deleted row at: (0,3) new row at: (0,2) new row at: (0,3) updated row from (0,1) to (0,3) iter 405 deleted row at: (0,2) deleted row at: (0,3) new row at: (0,2) new row at: (0,3) updated row from (0,4) to (0,6) iter 406 ... deleted row at: (0,2) deleted row at: (0,3) new row at: (0,2) new row at: (0,3) updated row from (0,4) to (0,1) iter 447 updated row from (0,5) to (0,2) iter 447 Traceback (most recent call last): File "/tmp/pgbug.py", line 80, in <module> test_bug() File "/tmp/pgbug.py", line 51, in test_bug update(cur, i) File "/tmp/pgbug.py", line 76, in update assert(len(rows) == 1) AssertionError There's clearly something wrong. (0,4) has been updated several times, but seems to still be visible. Greetings, Andres Freund -- Andres Freund http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services
Attachment
pgsql-bugs by date: