diff --git a/contrib/pgrowlocks/.gitignore b/contrib/pgrowlocks/.gitignore new file mode 100644 index 0000000000..b4903eba65 --- /dev/null +++ b/contrib/pgrowlocks/.gitignore @@ -0,0 +1,6 @@ +# Generated subdirectories +/log/ +/results/ +/output_iso/ +/tmp_check/ +/tmp_check_iso/ diff --git a/contrib/pgrowlocks/Makefile b/contrib/pgrowlocks/Makefile index 294c05dd0f..e808064664 100644 --- a/contrib/pgrowlocks/Makefile +++ b/contrib/pgrowlocks/Makefile @@ -9,6 +9,9 @@ EXTENSION = pgrowlocks DATA = pgrowlocks--1.2.sql pgrowlocks--1.1--1.2.sql pgrowlocks--1.0--1.1.sql PGFILEDESC = "pgrowlocks - display row locking information" +ISOLATION = pgrowlocks +ISOLATION_OPTS = --load-extension=pgrowlocks + ifdef USE_PGXS PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) diff --git a/contrib/pgrowlocks/expected/pgrowlocks.out b/contrib/pgrowlocks/expected/pgrowlocks.out new file mode 100644 index 0000000000..725467266a --- /dev/null +++ b/contrib/pgrowlocks/expected/pgrowlocks.out @@ -0,0 +1,233 @@ +Parsed test spec with 2 sessions + +starting permutation: s1_begin s1_tuplock1 s2_rowlocks s1_commit +step s1_begin: BEGIN; +step s1_tuplock1: SELECT * FROM multixact_conflict FOR KEY SHARE; +a|b +-+- +1|2 +3|4 +(2 rows) + +step s2_rowlocks: SELECT locked_row, multi, modes FROM pgrowlocks('multixact_conflict'); +locked_row|multi|modes +----------+-----+----------------- +(0,1) |f |{"For Key Share"} +(0,2) |f |{"For Key Share"} +(2 rows) + +step s1_commit: COMMIT; + +starting permutation: s1_begin s1_tuplock2 s2_rowlocks s1_commit +step s1_begin: BEGIN; +step s1_tuplock2: SELECT * FROM multixact_conflict FOR SHARE; +a|b +-+- +1|2 +3|4 +(2 rows) + +step s2_rowlocks: SELECT locked_row, multi, modes FROM pgrowlocks('multixact_conflict'); +locked_row|multi|modes +----------+-----+------------- +(0,1) |f |{"For Share"} +(0,2) |f |{"For Share"} +(2 rows) + +step s1_commit: COMMIT; + +starting permutation: s1_begin s1_tuplock3 s2_rowlocks s1_commit +step s1_begin: BEGIN; +step s1_tuplock3: SELECT * FROM multixact_conflict FOR NO KEY UPDATE; +a|b +-+- +1|2 +3|4 +(2 rows) + +step s2_rowlocks: SELECT locked_row, multi, modes FROM pgrowlocks('multixact_conflict'); +locked_row|multi|modes +----------+-----+--------------------- +(0,1) |f |{"For No Key Update"} +(0,2) |f |{"For No Key Update"} +(2 rows) + +step s1_commit: COMMIT; + +starting permutation: s1_begin s1_tuplock4 s2_rowlocks s1_commit +step s1_begin: BEGIN; +step s1_tuplock4: SELECT * FROM multixact_conflict FOR UPDATE; +a|b +-+- +1|2 +3|4 +(2 rows) + +step s2_rowlocks: SELECT locked_row, multi, modes FROM pgrowlocks('multixact_conflict'); +locked_row|multi|modes +----------+-----+-------------- +(0,1) |f |{"For Update"} +(0,2) |f |{"For Update"} +(2 rows) + +step s1_commit: COMMIT; + +starting permutation: s1_begin s1_updatea s2_rowlocks s1_commit +step s1_begin: BEGIN; +step s1_updatea: UPDATE multixact_conflict SET a = 10 WHERE a = 1; +step s2_rowlocks: SELECT locked_row, multi, modes FROM pgrowlocks('multixact_conflict'); +locked_row|multi|modes +----------+-----+-------- +(0,1) |f |{Update} +(1 row) + +step s1_commit: COMMIT; + +starting permutation: s1_begin s1_updateb s2_rowlocks s1_commit +step s1_begin: BEGIN; +step s1_updateb: UPDATE multixact_conflict SET b = 11 WHERE b = 4; +step s2_rowlocks: SELECT locked_row, multi, modes FROM pgrowlocks('multixact_conflict'); +locked_row|multi|modes +----------+-----+----------------- +(0,2) |f |{"No Key Update"} +(1 row) + +step s1_commit: COMMIT; + +starting permutation: s1_begin s1_lcksvpt s1_tuplock1 s2_rowlocks s1_commit +step s1_begin: BEGIN; +step s1_lcksvpt: SELECT * FROM multixact_conflict FOR KEY SHARE; SAVEPOINT s; +a|b +-+- +1|2 +3|4 +(2 rows) + +step s1_tuplock1: SELECT * FROM multixact_conflict FOR KEY SHARE; +a|b +-+- +1|2 +3|4 +(2 rows) + +step s2_rowlocks: SELECT locked_row, multi, modes FROM pgrowlocks('multixact_conflict'); +locked_row|multi|modes +----------+-----+----------------- +(0,1) |f |{"For Key Share"} +(0,2) |f |{"For Key Share"} +(2 rows) + +step s1_commit: COMMIT; + +starting permutation: s1_begin s1_lcksvpt s1_tuplock2 s2_rowlocks s1_commit +step s1_begin: BEGIN; +step s1_lcksvpt: SELECT * FROM multixact_conflict FOR KEY SHARE; SAVEPOINT s; +a|b +-+- +1|2 +3|4 +(2 rows) + +step s1_tuplock2: SELECT * FROM multixact_conflict FOR SHARE; +a|b +-+- +1|2 +3|4 +(2 rows) + +step s2_rowlocks: SELECT locked_row, multi, modes FROM pgrowlocks('multixact_conflict'); +locked_row|multi|modes +----------+-----+------------------- +(0,1) |t |{"Key Share",Share} +(0,2) |t |{"Key Share",Share} +(2 rows) + +step s1_commit: COMMIT; + +starting permutation: s1_begin s1_lcksvpt s1_tuplock3 s2_rowlocks s1_commit +step s1_begin: BEGIN; +step s1_lcksvpt: SELECT * FROM multixact_conflict FOR KEY SHARE; SAVEPOINT s; +a|b +-+- +1|2 +3|4 +(2 rows) + +step s1_tuplock3: SELECT * FROM multixact_conflict FOR NO KEY UPDATE; +a|b +-+- +1|2 +3|4 +(2 rows) + +step s2_rowlocks: SELECT locked_row, multi, modes FROM pgrowlocks('multixact_conflict'); +locked_row|multi|modes +----------+-----+--------------------------------- +(0,1) |t |{"Key Share","For No Key Update"} +(0,2) |t |{"Key Share","For No Key Update"} +(2 rows) + +step s1_commit: COMMIT; + +starting permutation: s1_begin s1_lcksvpt s1_tuplock4 s2_rowlocks s1_commit +step s1_begin: BEGIN; +step s1_lcksvpt: SELECT * FROM multixact_conflict FOR KEY SHARE; SAVEPOINT s; +a|b +-+- +1|2 +3|4 +(2 rows) + +step s1_tuplock4: SELECT * FROM multixact_conflict FOR UPDATE; +a|b +-+- +1|2 +3|4 +(2 rows) + +step s2_rowlocks: SELECT locked_row, multi, modes FROM pgrowlocks('multixact_conflict'); +locked_row|multi|modes +----------+-----+-------------------------- +(0,1) |t |{"Key Share","For Update"} +(0,2) |t |{"Key Share","For Update"} +(2 rows) + +step s1_commit: COMMIT; + +starting permutation: s1_begin s1_lcksvpt s1_updatea s2_rowlocks s1_commit +step s1_begin: BEGIN; +step s1_lcksvpt: SELECT * FROM multixact_conflict FOR KEY SHARE; SAVEPOINT s; +a|b +-+- +1|2 +3|4 +(2 rows) + +step s1_updatea: UPDATE multixact_conflict SET a = 10 WHERE a = 1; +step s2_rowlocks: SELECT locked_row, multi, modes FROM pgrowlocks('multixact_conflict'); +locked_row|multi|modes +----------+-----+-------------------- +(0,1) |t |{"Key Share",Update} +(0,2) |f |{"For Key Share"} +(2 rows) + +step s1_commit: COMMIT; + +starting permutation: s1_begin s1_lcksvpt s1_updateb s2_rowlocks s1_commit +step s1_begin: BEGIN; +step s1_lcksvpt: SELECT * FROM multixact_conflict FOR KEY SHARE; SAVEPOINT s; +a|b +-+- +1|2 +3|4 +(2 rows) + +step s1_updateb: UPDATE multixact_conflict SET b = 11 WHERE b = 4; +step s2_rowlocks: SELECT locked_row, multi, modes FROM pgrowlocks('multixact_conflict'); +locked_row|multi|modes +----------+-----+----------------------------- +(0,1) |f |{"For Key Share"} +(0,2) |t |{"Key Share","No Key Update"} +(2 rows) + +step s1_commit: COMMIT; diff --git a/contrib/pgrowlocks/specs/pgrowlocks.spec b/contrib/pgrowlocks/specs/pgrowlocks.spec new file mode 100644 index 0000000000..4f4013cddd --- /dev/null +++ b/contrib/pgrowlocks/specs/pgrowlocks.spec @@ -0,0 +1,39 @@ +# Tests for contrib/pgrowlocks + +setup { + CREATE TABLE multixact_conflict (a int PRIMARY KEY, b int); + INSERT INTO multixact_conflict VALUES (1, 2), (3, 4); +} + +teardown { + DROP TABLE multixact_conflict; +} + +session s1 +step s1_begin { BEGIN; } +step s1_tuplock1 { SELECT * FROM multixact_conflict FOR KEY SHARE; } +step s1_tuplock2 { SELECT * FROM multixact_conflict FOR SHARE; } +step s1_tuplock3 { SELECT * FROM multixact_conflict FOR NO KEY UPDATE; } +step s1_tuplock4 { SELECT * FROM multixact_conflict FOR UPDATE; } +step s1_updatea { UPDATE multixact_conflict SET a = 10 WHERE a = 1; } +step s1_updateb { UPDATE multixact_conflict SET b = 11 WHERE b = 4; } +step s1_lcksvpt { SELECT * FROM multixact_conflict FOR KEY SHARE; SAVEPOINT s; } +step s1_commit { COMMIT; } + +session s2 +step s2_rowlocks { SELECT locked_row, multi, modes FROM pgrowlocks('multixact_conflict'); } + +permutation s1_begin s1_tuplock1 s2_rowlocks s1_commit +permutation s1_begin s1_tuplock2 s2_rowlocks s1_commit +permutation s1_begin s1_tuplock3 s2_rowlocks s1_commit +permutation s1_begin s1_tuplock4 s2_rowlocks s1_commit +permutation s1_begin s1_updatea s2_rowlocks s1_commit +permutation s1_begin s1_updateb s2_rowlocks s1_commit + +# test multixact cases using savepoints +permutation s1_begin s1_lcksvpt s1_tuplock1 s2_rowlocks s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock2 s2_rowlocks s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock3 s2_rowlocks s1_commit +permutation s1_begin s1_lcksvpt s1_tuplock4 s2_rowlocks s1_commit +permutation s1_begin s1_lcksvpt s1_updatea s2_rowlocks s1_commit +permutation s1_begin s1_lcksvpt s1_updateb s2_rowlocks s1_commit