Skip to content

Commit a9276a4

Browse files
anarazelCommitfest Bot
authored andcommitted
isolationtester showing broken index-only bitmap heap scan
1 parent 6a780e5 commit a9276a4

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
Parsed test spec with 2 sessions
2+
3+
starting permutation: s2_vacuum s2_mod s1_begin s1_prepare s1_fetch_1 s2_vacuum s1_fetch_all s1_commit
4+
step s2_vacuum: VACUUM (TRUNCATE false) ios_bitmap;
5+
step s2_mod:
6+
DELETE FROM ios_bitmap WHERE a > 1;
7+
8+
step s1_begin: BEGIN;
9+
step s1_prepare:
10+
DECLARE foo NO SCROLL CURSOR FOR SELECT row_number() OVER () FROM ios_bitmap WHERE a > 0 or b > 0;
11+
12+
step s1_fetch_1:
13+
FETCH FROM foo;
14+
15+
row_number
16+
----------
17+
1
18+
(1 row)
19+
20+
step s2_vacuum: VACUUM (TRUNCATE false) ios_bitmap;
21+
step s1_fetch_all:
22+
FETCH ALL FROM foo;
23+
24+
row_number
25+
----------
26+
(0 rows)
27+
28+
step s1_commit: COMMIT;

src/test/isolation/isolation_schedule

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ test: partial-index
1717
test: two-ids
1818
test: multiple-row-versions
1919
test: index-only-scan
20+
test: index-only-bitmapscan
2021
test: predicate-lock-hot-tuple
2122
test: update-conflict-out
2223
test: deadlock-simple
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# index-only-bitmapscan test showing wrong results
2+
#
3+
setup
4+
{
5+
-- by using a low fillfactor and a wide tuple we can get multiple blocks
6+
-- with just few rows
7+
CREATE TABLE ios_bitmap (a int NOT NULL, b int not null, pad char(1024) default '')
8+
WITH (AUTOVACUUM_ENABLED = false, FILLFACTOR = 10);
9+
10+
INSERT INTO ios_bitmap SELECT g.i, g.i FROM generate_series(1, 10) g(i);
11+
12+
CREATE INDEX ios_bitmap_a ON ios_bitmap(a);
13+
CREATE INDEX ios_bitmap_b ON ios_bitmap(b);
14+
}
15+
16+
teardown
17+
{
18+
DROP TABLE ios_bitmap;
19+
}
20+
21+
22+
session s1
23+
24+
setup {
25+
SET enable_seqscan = false;
26+
}
27+
28+
step s1_begin { BEGIN; }
29+
step s1_commit { COMMIT; }
30+
31+
32+
# The test query uses an or between two indexes to ensure make it more likely
33+
# to use a bitmap index scan
34+
#
35+
# The row_number() hack is a way to have something returned (isolationtester
36+
# doesn't display empty rows) while still allowing for the index-only scan
37+
# optimization in bitmap heap scans, which requires an empty targetlist.
38+
step s1_prepare {
39+
DECLARE foo NO SCROLL CURSOR FOR SELECT row_number() OVER () FROM ios_bitmap WHERE a > 0 or b > 0;
40+
}
41+
42+
step s1_fetch_1 {
43+
FETCH FROM foo;
44+
}
45+
46+
step s1_fetch_all {
47+
FETCH ALL FROM foo;
48+
}
49+
50+
51+
session s2
52+
53+
# Don't delete row 1 so we have a row for the cursor to "rest" on.
54+
step s2_mod
55+
{
56+
DELETE FROM ios_bitmap WHERE a > 1;
57+
}
58+
59+
# Disable truncation, as otherwise we'll just wait for a timeout while trying
60+
# to acquire the lock
61+
step s2_vacuum { VACUUM (TRUNCATE false) ios_bitmap; }
62+
63+
permutation
64+
# Vacuum first, to ensure VM exists, otherwise the bitmapscan will consider
65+
# VM to be size 0, due to caching. Can't do that in setup because
66+
s2_vacuum
67+
68+
# delete nearly all rows, to make issue visible
69+
s2_mod
70+
# create a cursor
71+
s1_begin
72+
s1_prepare
73+
74+
# fetch one row from the cursor, that ensures the index scan portion is done
75+
# before the vacuum in the next step
76+
s1_fetch_1
77+
78+
# with the bug this vacuum will mark pages as all-visible that the scan in
79+
# the next step then considers all-visible, despite all rows from those
80+
# pages having been removed.
81+
s2_vacuum
82+
# if this returns any rows, we're busted
83+
s1_fetch_all
84+
85+
s1_commit

0 commit comments

Comments
 (0)