Guo Xiang Tan <gxtan1990@gmail.com> writes:
>> Unsurprisingly, the given info is not enough to reproduce the crash.
> We could only reproduce this on our production PostgreSQL cluster.
Since the problem occurs during EvalPlanQual, it'd only manifest when
the update touched a concurrently-updated row, which is why it's hard
to reproduce if you aren't deliberately trying to trigger it. But
I've been able to reproduce a crash at the same spot, and have made
a test case using the isolationtester infrastructure (attached).
I'll look into an actual fix tomorrow.
regards, tom lane
diff --git a/src/test/isolation/specs/eval-plan-qual.spec b/src/test/isolation/specs/eval-plan-qual.spec
index 7ff6f6b..53a32e6 100644
*** a/src/test/isolation/specs/eval-plan-qual.spec
--- b/src/test/isolation/specs/eval-plan-qual.spec
*************** setup
*** 21,33 ****
CREATE TABLE table_b (id integer, value text);
INSERT INTO table_a VALUES (1, 'tableAValue');
INSERT INTO table_b VALUES (1, 'tableBValue');
}
teardown
{
DROP TABLE accounts;
DROP TABLE p CASCADE;
! DROP TABLE table_a, table_b;
}
session "s1"
--- 21,36 ----
CREATE TABLE table_b (id integer, value text);
INSERT INTO table_a VALUES (1, 'tableAValue');
INSERT INTO table_b VALUES (1, 'tableBValue');
+
+ CREATE TABLE jointest AS SELECT generate_series(1,10) AS id, 0 AS data;
+ CREATE INDEX ON jointest(id);
}
teardown
{
DROP TABLE accounts;
DROP TABLE p CASCADE;
! DROP TABLE table_a, table_b, jointest;
}
session "s1"
*************** step "updateforss" {
*** 78,83 ****
--- 81,96 ----
UPDATE table_b SET value = 'newTableBValue' WHERE id = 1;
}
+ # these tests exercise mark/restore during EPQ recheck, cf bug #15032
+
+ step "selectjoinforupdate" {
+ set enable_hashjoin to 0;
+ set enable_seqscan to 0;
+ explain (costs off)
+ select * from jointest a join jointest b on a.id=b.id for update;
+ select * from jointest a join jointest b on a.id=b.id for update;
+ }
+
session "s2"
setup { BEGIN ISOLATION LEVEL READ COMMITTED; }
*************** step "readforss" {
*** 104,109 ****
--- 117,123 ----
WHERE ta.id = 1 FOR UPDATE OF ta;
}
step "wrtwcte" { UPDATE table_a SET value = 'tableAValue2' WHERE id = 1; }
+ step "wrjt" { UPDATE jointest SET data = 42 WHERE id = 7; }
step "c2" { COMMIT; }
session "s3"
*************** permutation "wx2" "partiallock" "c2" "c1
*** 135,137 ****
--- 149,152 ----
permutation "wx2" "lockwithvalues" "c2" "c1" "read"
permutation "updateforss" "readforss" "c1" "c2"
permutation "wrtwcte" "readwcte" "c1" "c2"
+ permutation "wrjt" "selectjoinforupdate" "c2" "c1"