v6-0002-isolationtester-showing-broken-index-only-bitmap-.patch
application/octet-stream
Filename: v6-0002-isolationtester-showing-broken-index-only-bitmap-.patch
Type: application/octet-stream
Part: 0
Patch
Format: format-patch
Series: patch v6-0002
Subject: isolationtester showing broken index-only bitmap heap scan
| File | + | − |
|---|---|---|
| src/test/isolation/expected/index-only-bitmapscan.out | 28 | 0 |
| src/test/isolation/isolation_schedule | 1 | 0 |
| src/test/isolation/specs/index-only-bitmapscan.spec | 85 | 0 |
From 14dbf4bd4c03d8610c92cbe7020ec979bd55dd74 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Mon, 2 Dec 2024 14:38:11 -0500
Subject: [PATCH v6 2/2] isolationtester showing broken index-only bitmap heap
scan
---
.../expected/index-only-bitmapscan.out | 28 ++++++
src/test/isolation/isolation_schedule | 1 +
.../specs/index-only-bitmapscan.spec | 85 +++++++++++++++++++
3 files changed, 114 insertions(+)
create mode 100644 src/test/isolation/expected/index-only-bitmapscan.out
create mode 100644 src/test/isolation/specs/index-only-bitmapscan.spec
diff --git a/src/test/isolation/expected/index-only-bitmapscan.out b/src/test/isolation/expected/index-only-bitmapscan.out
new file mode 100644
index 00000000000..132ff1bda70
--- /dev/null
+++ b/src/test/isolation/expected/index-only-bitmapscan.out
@@ -0,0 +1,28 @@
+Parsed test spec with 2 sessions
+
+starting permutation: s2_vacuum s2_mod s1_begin s1_prepare s1_fetch_1 s2_vacuum s1_fetch_all s1_commit
+step s2_vacuum: VACUUM (TRUNCATE false) ios_bitmap;
+step s2_mod:
+ DELETE FROM ios_bitmap WHERE a > 1;
+
+step s1_begin: BEGIN;
+step s1_prepare:
+ DECLARE foo NO SCROLL CURSOR FOR SELECT row_number() OVER () FROM ios_bitmap WHERE a > 0 or b > 0;
+
+step s1_fetch_1:
+ FETCH FROM foo;
+
+row_number
+----------
+ 1
+(1 row)
+
+step s2_vacuum: VACUUM (TRUNCATE false) ios_bitmap;
+step s1_fetch_all:
+ FETCH ALL FROM foo;
+
+row_number
+----------
+(0 rows)
+
+step s1_commit: COMMIT;
diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule
index 143109aa4da..e3c669a29c7 100644
--- a/src/test/isolation/isolation_schedule
+++ b/src/test/isolation/isolation_schedule
@@ -17,6 +17,7 @@ test: partial-index
test: two-ids
test: multiple-row-versions
test: index-only-scan
+test: index-only-bitmapscan
test: predicate-lock-hot-tuple
test: update-conflict-out
test: deadlock-simple
diff --git a/src/test/isolation/specs/index-only-bitmapscan.spec b/src/test/isolation/specs/index-only-bitmapscan.spec
new file mode 100644
index 00000000000..9962b8dc531
--- /dev/null
+++ b/src/test/isolation/specs/index-only-bitmapscan.spec
@@ -0,0 +1,85 @@
+# index-only-bitmapscan test showing wrong results
+#
+setup
+{
+ -- by using a low fillfactor and a wide tuple we can get multiple blocks
+ -- with just few rows
+ CREATE TABLE ios_bitmap (a int NOT NULL, b int not null, pad char(1024) default '')
+ WITH (AUTOVACUUM_ENABLED = false, FILLFACTOR = 10);
+
+ INSERT INTO ios_bitmap SELECT g.i, g.i FROM generate_series(1, 10) g(i);
+
+ CREATE INDEX ios_bitmap_a ON ios_bitmap(a);
+ CREATE INDEX ios_bitmap_b ON ios_bitmap(b);
+}
+
+teardown
+{
+ DROP TABLE ios_bitmap;
+}
+
+
+session s1
+
+setup {
+ SET enable_seqscan = false;
+}
+
+step s1_begin { BEGIN; }
+step s1_commit { COMMIT; }
+
+
+# The test query uses an or between two indexes to ensure make it more likely
+# to use a bitmap index scan
+#
+# The row_number() hack is a way to have something returned (isolationtester
+# doesn't display empty rows) while still allowing for the index-only scan
+# optimization in bitmap heap scans, which requires an empty targetlist.
+step s1_prepare {
+ DECLARE foo NO SCROLL CURSOR FOR SELECT row_number() OVER () FROM ios_bitmap WHERE a > 0 or b > 0;
+}
+
+step s1_fetch_1 {
+ FETCH FROM foo;
+}
+
+step s1_fetch_all {
+ FETCH ALL FROM foo;
+}
+
+
+session s2
+
+# Don't delete row 1 so we have a row for the cursor to "rest" on.
+step s2_mod
+{
+ DELETE FROM ios_bitmap WHERE a > 1;
+}
+
+# Disable truncation, as otherwise we'll just wait for a timeout while trying
+# to acquire the lock
+step s2_vacuum { VACUUM (TRUNCATE false) ios_bitmap; }
+
+permutation
+ # Vacuum first, to ensure VM exists, otherwise the bitmapscan will consider
+ # VM to be size 0, due to caching. Can't do that in setup because
+ s2_vacuum
+
+ # delete nearly all rows, to make issue visible
+ s2_mod
+ # create a cursor
+ s1_begin
+ s1_prepare
+
+ # fetch one row from the cursor, that ensures the index scan portion is done
+ # before the vacuum in the next step
+ s1_fetch_1
+
+ # with the bug this vacuum will mark pages as all-visible that the scan in
+ # the next step then considers all-visible, despite all rows from those
+ # pages having been removed.
+ s2_vacuum
+ # if this returns any rows, we're busted
+ s1_fetch_all
+
+ s1_commit
--
2.45.2