diff options
| author | Teodor Sigaev | 2018-03-30 11:23:17 +0000 |
|---|---|---|
| committer | Teodor Sigaev | 2018-03-30 11:23:17 +0000 |
| commit | 43d1ed60fdd96027f044e152176c0d45cd6bf443 (patch) | |
| tree | b5efc150a6cfa4d5edbc5ecbc828850097d0201f /src/test | |
| parent | 019fa576ca8298ecb7b8ded6e0c857840b57a4ae (diff) | |
Predicate locking in GIN index
Predicate locks are used on per page basis only if fastupdate = off, in
opposite case predicate lock on pending list will effectively lock whole index,
to reduce locking overhead, just lock a relation. Entry and posting trees are
essentially B-tree, so locks are acquired on leaf pages only.
Author: Shubham Barai with some editorization by me and Dmitry Ivanov
Review by: Alexander Korotkov, Dmitry Ivanov, Fedor Sigaev
Discussion: https://www.postgresql.org/message-id/flat/CALxAEPt5sWW+EwTaKUGFL5_XFcZ0MuGBcyJ70oqbWqr42YKR8Q@mail.gmail.com
Diffstat (limited to 'src/test')
| -rw-r--r-- | src/test/isolation/expected/predicate-gin.out | 756 | ||||
| -rw-r--r-- | src/test/isolation/isolation_schedule | 1 | ||||
| -rw-r--r-- | src/test/isolation/specs/predicate-gin.spec | 134 |
3 files changed, 891 insertions, 0 deletions
diff --git a/src/test/isolation/expected/predicate-gin.out b/src/test/isolation/expected/predicate-gin.out new file mode 100644 index 00000000000..4f5501f6f01 --- /dev/null +++ b/src/test/isolation/expected/predicate-gin.out @@ -0,0 +1,756 @@ +Parsed test spec with 2 sessions + +starting permutation: rxy1 wx1 c1 rxy2 wy2 c2 +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step c1: commit; +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10050 +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +step c2: commit; + +starting permutation: rxy2 wy2 c2 rxy1 wx1 c1 +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +step c2: commit; +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10050 +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step c1: commit; + +starting permutation: rxy3 wx3 c1 rxy4 wy4 c2 +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step c1: commit; +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step c2: commit; + +starting permutation: rxy4 wy4 c2 rxy3 wx3 c1 +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step c2: commit; +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step c1: commit; + +starting permutation: rxy1 wx1 rxy2 c1 wy2 c2 +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step c1: commit; +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +ERROR: could not serialize access due to read/write dependencies among transactions +step c2: commit; + +starting permutation: rxy1 wx1 rxy2 wy2 c1 c2 +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +step c1: commit; +step c2: commit; +ERROR: could not serialize access due to read/write dependencies among transactions + +starting permutation: rxy1 wx1 rxy2 wy2 c2 c1 +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +step c2: commit; +step c1: commit; +ERROR: could not serialize access due to read/write dependencies among transactions + +starting permutation: rxy1 rxy2 wx1 c1 wy2 c2 +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step c1: commit; +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +ERROR: could not serialize access due to read/write dependencies among transactions +step c2: commit; + +starting permutation: rxy1 rxy2 wx1 wy2 c1 c2 +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +step c1: commit; +step c2: commit; +ERROR: could not serialize access due to read/write dependencies among transactions + +starting permutation: rxy1 rxy2 wx1 wy2 c2 c1 +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +step c2: commit; +step c1: commit; +ERROR: could not serialize access due to read/write dependencies among transactions + +starting permutation: rxy1 rxy2 wy2 wx1 c1 c2 +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step c1: commit; +step c2: commit; +ERROR: could not serialize access due to read/write dependencies among transactions + +starting permutation: rxy1 rxy2 wy2 wx1 c2 c1 +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step c2: commit; +step c1: commit; +ERROR: could not serialize access due to read/write dependencies among transactions + +starting permutation: rxy1 rxy2 wy2 c2 wx1 c1 +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +step c2: commit; +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +ERROR: could not serialize access due to read/write dependencies among transactions +step c1: commit; + +starting permutation: rxy2 rxy1 wx1 c1 wy2 c2 +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step c1: commit; +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +ERROR: could not serialize access due to read/write dependencies among transactions +step c2: commit; + +starting permutation: rxy2 rxy1 wx1 wy2 c1 c2 +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +step c1: commit; +step c2: commit; +ERROR: could not serialize access due to read/write dependencies among transactions + +starting permutation: rxy2 rxy1 wx1 wy2 c2 c1 +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +step c2: commit; +step c1: commit; +ERROR: could not serialize access due to read/write dependencies among transactions + +starting permutation: rxy2 rxy1 wy2 wx1 c1 c2 +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step c1: commit; +step c2: commit; +ERROR: could not serialize access due to read/write dependencies among transactions + +starting permutation: rxy2 rxy1 wy2 wx1 c2 c1 +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step c2: commit; +step c1: commit; +ERROR: could not serialize access due to read/write dependencies among transactions + +starting permutation: rxy2 rxy1 wy2 c2 wx1 c1 +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +step c2: commit; +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +ERROR: could not serialize access due to read/write dependencies among transactions +step c1: commit; + +starting permutation: rxy2 wy2 rxy1 wx1 c1 c2 +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step c1: commit; +step c2: commit; +ERROR: could not serialize access due to read/write dependencies among transactions + +starting permutation: rxy2 wy2 rxy1 wx1 c2 c1 +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step c2: commit; +step c1: commit; +ERROR: could not serialize access due to read/write dependencies among transactions + +starting permutation: rxy2 wy2 rxy1 c2 wx1 c1 +step rxy2: select count(*) from gin_tbl where p @> array[5,6]; +count + +10000 +step wy2: insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step c2: commit; +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +ERROR: could not serialize access due to read/write dependencies among transactions +step c1: commit; + +starting permutation: rxy3 wx3 rxy4 c1 wy4 c2 +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step c1: commit; +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step c2: commit; + +starting permutation: rxy3 wx3 rxy4 wy4 c1 c2 +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step c1: commit; +step c2: commit; + +starting permutation: rxy3 wx3 rxy4 wy4 c2 c1 +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step c2: commit; +step c1: commit; + +starting permutation: rxy3 rxy4 wx3 c1 wy4 c2 +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step c1: commit; +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step c2: commit; + +starting permutation: rxy3 rxy4 wx3 wy4 c1 c2 +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step c1: commit; +step c2: commit; + +starting permutation: rxy3 rxy4 wx3 wy4 c2 c1 +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step c2: commit; +step c1: commit; + +starting permutation: rxy3 rxy4 wy4 wx3 c1 c2 +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step c1: commit; +step c2: commit; + +starting permutation: rxy3 rxy4 wy4 wx3 c2 c1 +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step c2: commit; +step c1: commit; + +starting permutation: rxy3 rxy4 wy4 c2 wx3 c1 +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step c2: commit; +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step c1: commit; + +starting permutation: rxy4 rxy3 wx3 c1 wy4 c2 +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step c1: commit; +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step c2: commit; + +starting permutation: rxy4 rxy3 wx3 wy4 c1 c2 +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step c1: commit; +step c2: commit; + +starting permutation: rxy4 rxy3 wx3 wy4 c2 c1 +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step c2: commit; +step c1: commit; + +starting permutation: rxy4 rxy3 wy4 wx3 c1 c2 +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step c1: commit; +step c2: commit; + +starting permutation: rxy4 rxy3 wy4 wx3 c2 c1 +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step c2: commit; +step c1: commit; + +starting permutation: rxy4 rxy3 wy4 c2 wx3 c1 +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step c2: commit; +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step c1: commit; + +starting permutation: rxy4 wy4 rxy3 wx3 c1 c2 +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step c1: commit; +step c2: commit; + +starting permutation: rxy4 wy4 rxy3 wx3 c2 c1 +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step c2: commit; +step c1: commit; + +starting permutation: rxy4 wy4 rxy3 c2 wx3 c1 +step rxy4: select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; +count + +4 +step wy4: insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; +step rxy3: select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; +count + +4 +step c2: commit; +step wx3: insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; +step c1: commit; + +starting permutation: rxy1 rxy2fu wx1 c1 wy2fu c2 +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step rxy2fu: select count(*) from gin_tbl where p @> array[10000,10005]; +count + +0 +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step c1: commit; +step wy2fu: insert into gin_tbl select g, array[10000,10005] from + generate_series(20051, 20100) g; +step c2: commit; + +starting permutation: fu1 rxy1 rxy2fu wx1 c1 wy2fu c2 +step fu1: alter index ginidx set (fastupdate = on); + commit; + begin isolation level serializable; + set enable_seqscan=off; +step rxy1: select count(*) from gin_tbl where p @> array[4,5]; +count + +10000 +step rxy2fu: select count(*) from gin_tbl where p @> array[10000,10005]; +count + +0 +step wx1: insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; +step c1: commit; +step wy2fu: insert into gin_tbl select g, array[10000,10005] from + generate_series(20051, 20100) g; +ERROR: could not serialize access due to read/write dependencies among transactions +step c2: commit; diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule index 53e1f192b0b..d3965fe73f7 100644 --- a/src/test/isolation/isolation_schedule +++ b/src/test/isolation/isolation_schedule @@ -67,3 +67,4 @@ test: vacuum-reltuples test: timeouts test: vacuum-concurrent-drop test: predicate-gist +test: predicate-gin diff --git a/src/test/isolation/specs/predicate-gin.spec b/src/test/isolation/specs/predicate-gin.spec new file mode 100644 index 00000000000..9f0cda80573 --- /dev/null +++ b/src/test/isolation/specs/predicate-gin.spec @@ -0,0 +1,134 @@ +# Test for page level predicate locking in gin index +# +# Test to verify serialization failures and to check reduced false positives +# +# To verify serialization failures, queries and permutations are written in such +# a way that an index scan (from one transaction) and an index insert (from +# another transaction) will try to access the same part (sub-tree) of the index +# whereas to check reduced false positives, they will try to access different +# parts (sub-tree) of the index. + + +setup +{ + create table gin_tbl(id int4, p int4[]); + insert into gin_tbl select g, array[g, g*2,g*3] from generate_series(1, 10000) g; + insert into gin_tbl select g, array[4,5,6] from generate_series(10001, 20000) g; + create index ginidx on gin_tbl using gin(p) with (fastupdate = off); +} + +teardown +{ + drop table gin_tbl; +} + +session "s1" +setup +{ + begin isolation level serializable; + set enable_seqscan=off; +} + +# enable pending list for a small subset of tests +step "fu1" { alter index ginidx set (fastupdate = on); + commit; + begin isolation level serializable; + set enable_seqscan=off; } + +step "rxy1" { select count(*) from gin_tbl where p @> array[4,5]; } +step "wx1" { insert into gin_tbl select g, array[5,6] from generate_series + (20001, 20050) g; } +step "rxy3" { select count(*) from gin_tbl where p @> array[1,2] or + p @> array[100,200] or p @> array[500,1000] or p @> array[1000,2000]; } +step "wx3" { insert into gin_tbl select g, array[g,g*2] from generate_series + (1, 50) g; } +step "c1" { commit; } + +session "s2" +setup +{ + begin isolation level serializable; + set enable_seqscan=off; +} + +step "rxy2" { select count(*) from gin_tbl where p @> array[5,6]; } +step "rxy2fu" { select count(*) from gin_tbl where p @> array[10000,10005]; } +step "wy2" { insert into gin_tbl select g, array[4,5] from + generate_series(20051, 20100) g; } +step "wy2fu" { insert into gin_tbl select g, array[10000,10005] from + generate_series(20051, 20100) g; } +step "rxy4" { select count(*) from gin_tbl where p @> array[4000,8000] or + p @> array[5000,10000] or p @> array[6000,12000] or + p @> array[8000,16000]; } +step "wy4" { insert into gin_tbl select g, array[g,g*2] from generate_series + (10000, 10050) g; } +step "c2" { commit; } + + +# An index scan (from one transaction) and an index insert (from another transaction) +# try to access the same part of the index but one transaction commits before other +# transaction begins so no r-w conflict. + +permutation "rxy1" "wx1" "c1" "rxy2" "wy2" "c2" +permutation "rxy2" "wy2" "c2" "rxy1" "wx1" "c1" + +# An index scan (from one transaction) and an index insert (from another transaction) +# try to access different parts of the index and also one transaction commits before +# other transaction begins, so no r-w conflict. + +permutation "rxy3" "wx3" "c1" "rxy4" "wy4" "c2" +permutation "rxy4" "wy4" "c2" "rxy3" "wx3" "c1" + + +# An index scan (from one transaction) and an index insert (from another transaction) +# try to access the same part of the index and one transaction begins before other +# transaction commits so there is a r-w conflict. + +permutation "rxy1" "wx1" "rxy2" "c1" "wy2" "c2" +permutation "rxy1" "wx1" "rxy2" "wy2" "c1" "c2" +permutation "rxy1" "wx1" "rxy2" "wy2" "c2" "c1" +permutation "rxy1" "rxy2" "wx1" "c1" "wy2" "c2" +permutation "rxy1" "rxy2" "wx1" "wy2" "c1" "c2" +permutation "rxy1" "rxy2" "wx1" "wy2" "c2" "c1" +permutation "rxy1" "rxy2" "wy2" "wx1" "c1" "c2" +permutation "rxy1" "rxy2" "wy2" "wx1" "c2" "c1" +permutation "rxy1" "rxy2" "wy2" "c2" "wx1" "c1" +permutation "rxy2" "rxy1" "wx1" "c1" "wy2" "c2" +permutation "rxy2" "rxy1" "wx1" "wy2" "c1" "c2" +permutation "rxy2" "rxy1" "wx1" "wy2" "c2" "c1" +permutation "rxy2" "rxy1" "wy2" "wx1" "c1" "c2" +permutation "rxy2" "rxy1" "wy2" "wx1" "c2" "c1" +permutation "rxy2" "rxy1" "wy2" "c2" "wx1" "c1" +permutation "rxy2" "wy2" "rxy1" "wx1" "c1" "c2" +permutation "rxy2" "wy2" "rxy1" "wx1" "c2" "c1" +permutation "rxy2" "wy2" "rxy1" "c2" "wx1" "c1" + +# An index scan (from one transaction) and an index insert (from another transaction) +# try to access different parts of the index so no r-w conflict. + +permutation "rxy3" "wx3" "rxy4" "c1" "wy4" "c2" +permutation "rxy3" "wx3" "rxy4" "wy4" "c1" "c2" +permutation "rxy3" "wx3" "rxy4" "wy4" "c2" "c1" +permutation "rxy3" "rxy4" "wx3" "c1" "wy4" "c2" +permutation "rxy3" "rxy4" "wx3" "wy4" "c1" "c2" +permutation "rxy3" "rxy4" "wx3" "wy4" "c2" "c1" +permutation "rxy3" "rxy4" "wy4" "wx3" "c1" "c2" +permutation "rxy3" "rxy4" "wy4" "wx3" "c2" "c1" +permutation "rxy3" "rxy4" "wy4" "c2" "wx3" "c1" +permutation "rxy4" "rxy3" "wx3" "c1" "wy4" "c2" +permutation "rxy4" "rxy3" "wx3" "wy4" "c1" "c2" +permutation "rxy4" "rxy3" "wx3" "wy4" "c2" "c1" +permutation "rxy4" "rxy3" "wy4" "wx3" "c1" "c2" +permutation "rxy4" "rxy3" "wy4" "wx3" "c2" "c1" +permutation "rxy4" "rxy3" "wy4" "c2" "wx3" "c1" +permutation "rxy4" "wy4" "rxy3" "wx3" "c1" "c2" +permutation "rxy4" "wy4" "rxy3" "wx3" "c2" "c1" +permutation "rxy4" "wy4" "rxy3" "c2" "wx3" "c1" + +# Test fastupdate = on. First test should pass because fastupdate is off and +# sessions touches different parts of index, second should fail because +# with fastupdate on, then whole index should be under predicate lock. + +permutation "rxy1" "rxy2fu" "wx1" "c1" "wy2fu" "c2" +permutation "fu1" "rxy1" "rxy2fu" "wx1" "c1" "wy2fu" "c2" + |
