From 226ec72269cf4bebb6576f23e7b88dfabe6aea16 Mon Sep 17 00:00:00 2001 From: Amul Sul Date: Tue, 13 Feb 2018 12:37:33 +0530 Subject: [PATCH 2/2] isolation tests v4 v4: - Rebased on Invalidate ip_blkid v5. v3: - Rebase on "UPDATE of partition key v35" patch[2] and latest maste head[3]. v2: - Error message changed. - Can't add isolation test[1] for RelationFindReplTupleByIndex & RelationFindReplTupleSeq - In ExecOnConflictUpdate, the error report is converted to assert check. v1: Added isolation tests to hit an error in the following functions: 1. ExecUpdate -> specs/partition-key-update-1 2. ExecDelete -> specs/partition-key-update-1 3. GetTupleForTrigger -> specs/partition-key-update-2 4. ExecLockRows -> specs/partition-key-update-3 ------------ References: ------------ 1] https://postgr.es/m/CA+TgmoYsMRo2PHFTGUFifv4ZSCZ9LNJASbOyb=9it2=UA4j4vw@mail.gmail.com 2] https://postgr.es/m/CAJ3gD9dixkkMzNnnP1CaZ1H17-U17ok_sVbjZZo+wnB=rJH6yg@mail.gmail.com 3] Commit id bdb70c12b3a2e69eec6e51411df60d9f43ecc841 --- .../isolation/expected/partition-key-update-1.out | 35 +++++++++++++++++++ .../isolation/expected/partition-key-update-2.out | 18 ++++++++++ .../isolation/expected/partition-key-update-3.out | 8 +++++ src/test/isolation/isolation_schedule | 3 ++ .../isolation/specs/partition-key-update-1.spec | 37 ++++++++++++++++++++ .../isolation/specs/partition-key-update-2.spec | 39 ++++++++++++++++++++++ .../isolation/specs/partition-key-update-3.spec | 30 +++++++++++++++++ 7 files changed, 170 insertions(+) create mode 100644 src/test/isolation/expected/partition-key-update-1.out create mode 100644 src/test/isolation/expected/partition-key-update-2.out create mode 100644 src/test/isolation/expected/partition-key-update-3.out create mode 100644 src/test/isolation/specs/partition-key-update-1.spec create mode 100644 src/test/isolation/specs/partition-key-update-2.spec create mode 100644 src/test/isolation/specs/partition-key-update-3.spec diff --git a/src/test/isolation/expected/partition-key-update-1.out b/src/test/isolation/expected/partition-key-update-1.out new file mode 100644 index 0000000000..56bf4450b0 --- /dev/null +++ b/src/test/isolation/expected/partition-key-update-1.out @@ -0,0 +1,35 @@ +Parsed test spec with 2 sessions + +starting permutation: s1u s1c s2u +step s1u: UPDATE foo SET a=2 WHERE a=1; +step s1c: COMMIT; +step s2u: UPDATE foo SET b='EFG' WHERE a=1; + +starting permutation: s1u s2u s1c +step s1u: UPDATE foo SET a=2 WHERE a=1; +step s2u: UPDATE foo SET b='EFG' WHERE a=1; +step s1c: COMMIT; +step s2u: <... completed> +error in steps s1c s2u: ERROR: tuple to be updated was already moved to another partition due to concurrent update + +starting permutation: s2u s1u s1c +step s2u: UPDATE foo SET b='EFG' WHERE a=1; +step s1u: UPDATE foo SET a=2 WHERE a=1; +step s1c: COMMIT; + +starting permutation: s1u s1c s2d +step s1u: UPDATE foo SET a=2 WHERE a=1; +step s1c: COMMIT; +step s2d: DELETE FROM foo WHERE a=1; + +starting permutation: s1u s2d s1c +step s1u: UPDATE foo SET a=2 WHERE a=1; +step s2d: DELETE FROM foo WHERE a=1; +step s1c: COMMIT; +step s2d: <... completed> +error in steps s1c s2d: ERROR: tuple to be updated was already moved to another partition due to concurrent update + +starting permutation: s2d s1u s1c +step s2d: DELETE FROM foo WHERE a=1; +step s1u: UPDATE foo SET a=2 WHERE a=1; +step s1c: COMMIT; diff --git a/src/test/isolation/expected/partition-key-update-2.out b/src/test/isolation/expected/partition-key-update-2.out new file mode 100644 index 0000000000..195ec4cedf --- /dev/null +++ b/src/test/isolation/expected/partition-key-update-2.out @@ -0,0 +1,18 @@ +Parsed test spec with 2 sessions + +starting permutation: s1u s1c s2u +step s1u: UPDATE foo SET b='EFG' WHERE a=1; +step s1c: COMMIT; +step s2u: UPDATE foo SET b='XYZ' WHERE a=1; + +starting permutation: s1u s2u s1c +step s1u: UPDATE foo SET b='EFG' WHERE a=1; +step s2u: UPDATE foo SET b='XYZ' WHERE a=1; +step s1c: COMMIT; +step s2u: <... completed> +error in steps s1c s2u: ERROR: tuple to be locked was already moved to another partition due to concurrent update + +starting permutation: s2u s1u s1c +step s2u: UPDATE foo SET b='XYZ' WHERE a=1; +step s1u: UPDATE foo SET b='EFG' WHERE a=1; +step s1c: COMMIT; diff --git a/src/test/isolation/expected/partition-key-update-3.out b/src/test/isolation/expected/partition-key-update-3.out new file mode 100644 index 0000000000..1922bdce46 --- /dev/null +++ b/src/test/isolation/expected/partition-key-update-3.out @@ -0,0 +1,8 @@ +Parsed test spec with 2 sessions + +starting permutation: s1u3 s2i s1c +step s1u3: UPDATE foo_r SET a=11 WHERE a=7 AND b = 'ABC'; +step s2i: INSERT INTO bar VALUES(7); +step s1c: COMMIT; +step s2i: <... completed> +error in steps s1c s2i: ERROR: tuple to be locked was already moved to another partition due to concurrent update diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule index 74d7d59546..9bda495de3 100644 --- a/src/test/isolation/isolation_schedule +++ b/src/test/isolation/isolation_schedule @@ -66,3 +66,6 @@ test: async-notify test: vacuum-reltuples test: timeouts test: vacuum-concurrent-drop +test: partition-key-update-1 +test: partition-key-update-2 +test: partition-key-update-3 diff --git a/src/test/isolation/specs/partition-key-update-1.spec b/src/test/isolation/specs/partition-key-update-1.spec new file mode 100644 index 0000000000..db76c9a9b5 --- /dev/null +++ b/src/test/isolation/specs/partition-key-update-1.spec @@ -0,0 +1,37 @@ +# Concurrency error from ExecUpdate and ExecDelete. + +# Throw an error to indicate that the targeted row has been already moved to +# another partition in the case of concurrency where a session trying to +# update/delete a row that's locked for a concurrent update by the another +# session cause tuple movement to the another partition due update of partition +# key. + +setup +{ + CREATE TABLE foo (a int, b text) PARTITION BY LIST(a); + CREATE TABLE foo1 PARTITION OF foo FOR VALUES IN (1); + CREATE TABLE foo2 PARTITION OF foo FOR VALUES IN (2); + INSERT INTO foo VALUES (1, 'ABC'); +} + +teardown +{ + DROP TABLE foo; +} + +session "s1" +setup { BEGIN; } +step "s1u" { UPDATE foo SET a=2 WHERE a=1; } +step "s1c" { COMMIT; } + +session "s2" +step "s2u" { UPDATE foo SET b='EFG' WHERE a=1; } +step "s2d" { DELETE FROM foo WHERE a=1; } + +permutation "s1u" "s1c" "s2u" +permutation "s1u" "s2u" "s1c" +permutation "s2u" "s1u" "s1c" + +permutation "s1u" "s1c" "s2d" +permutation "s1u" "s2d" "s1c" +permutation "s2d" "s1u" "s1c" diff --git a/src/test/isolation/specs/partition-key-update-2.spec b/src/test/isolation/specs/partition-key-update-2.spec new file mode 100644 index 0000000000..b09e76ce21 --- /dev/null +++ b/src/test/isolation/specs/partition-key-update-2.spec @@ -0,0 +1,39 @@ +# Concurrency error from GetTupleForTrigger + +# Like partition-key-update-1.spec, throw an error where a session trying to +# update a row that has been moved to another partition due to a concurrent +# update by other seesion. + +setup +{ + CREATE TABLE foo (a int, b text) PARTITION BY LIST(a); + CREATE TABLE foo1 PARTITION OF foo FOR VALUES IN (1); + CREATE TABLE foo2 PARTITION OF foo FOR VALUES IN (2); + INSERT INTO foo VALUES (1, 'ABC'); + CREATE FUNCTION func_foo_mod_a() RETURNS TRIGGER AS $$ + BEGIN + NEW.a = 2; -- This is changing partition key column. + RETURN NEW; + END $$ LANGUAGE PLPGSQL; + CREATE TRIGGER foo_mod_a BEFORE UPDATE ON foo1 + FOR EACH ROW EXECUTE PROCEDURE func_foo_mod_a(); +} + +teardown +{ + DROP TRIGGER foo_mod_a ON foo1; + DROP FUNCTION func_foo_mod_a(); + DROP TABLE foo; +} + +session "s1" +setup { BEGIN; } +step "s1u" { UPDATE foo SET b='EFG' WHERE a=1; } +step "s1c" { COMMIT; } + +session "s2" +step "s2u" { UPDATE foo SET b='XYZ' WHERE a=1; } + +permutation "s1u" "s1c" "s2u" +permutation "s1u" "s2u" "s1c" +permutation "s2u" "s1u" "s1c" diff --git a/src/test/isolation/specs/partition-key-update-3.spec b/src/test/isolation/specs/partition-key-update-3.spec new file mode 100644 index 0000000000..c1f547d9ba --- /dev/null +++ b/src/test/isolation/specs/partition-key-update-3.spec @@ -0,0 +1,30 @@ +# Concurrency error from ExecLockRows + +# Like partition-key-update-1.spec, throw an error where a session trying to +# lock a row that has been moved to another partition due to a concurrent +# update by other seesion. + +setup +{ + CREATE TABLE foo_r (a int, b text) PARTITION BY RANGE(a); + CREATE TABLE foo_r1 PARTITION OF foo_r FOR VALUES FROM (1) TO (10); + CREATE TABLE foo_r2 PARTITION OF foo_r FOR VALUES FROM (10) TO (20); + INSERT INTO foo_r VALUES(7, 'ABC'); + CREATE UNIQUE INDEX foo_r1_a_unique ON foo_r1 (a); + CREATE TABLE bar (a int REFERENCES foo_r1(a)); +} + +teardown +{ + DROP TABLE bar, foo_r; +} + +session "s1" +setup { BEGIN; } +step "s1u3" { UPDATE foo_r SET a=11 WHERE a=7 AND b = 'ABC'; } +step "s1c" { COMMIT; } + +session "s2" +step "s2i" { INSERT INTO bar VALUES(7); } + +permutation "s1u3" "s2i" "s1c" -- 2.14.1