summaryrefslogtreecommitdiffstats
path: root/src/test/modules/brin
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/modules/brin')
-rw-r--r--src/test/modules/brin/.gitignore4
-rw-r--r--src/test/modules/brin/Makefile17
-rw-r--r--src/test/modules/brin/expected/summarization-and-inprogress-insertion.out51
-rw-r--r--src/test/modules/brin/specs/summarization-and-inprogress-insertion.spec45
-rw-r--r--src/test/modules/brin/t/01_workitems.pl46
-rw-r--r--src/test/modules/brin/t/02_wal_consistency.pl75
6 files changed, 238 insertions, 0 deletions
diff --git a/src/test/modules/brin/.gitignore b/src/test/modules/brin/.gitignore
new file mode 100644
index 0000000..d6d1aaa
--- /dev/null
+++ b/src/test/modules/brin/.gitignore
@@ -0,0 +1,4 @@
+# Generated subdirectories
+/output_iso/
+/tmp_check/
+/tmp_check_iso/
diff --git a/src/test/modules/brin/Makefile b/src/test/modules/brin/Makefile
new file mode 100644
index 0000000..e74af89
--- /dev/null
+++ b/src/test/modules/brin/Makefile
@@ -0,0 +1,17 @@
+# src/test/modules/brin/Makefile
+
+EXTRA_INSTALL = contrib/pageinspect contrib/pg_walinspect
+
+ISOLATION = summarization-and-inprogress-insertion
+TAP_TESTS = 1
+
+ifdef USE_PGXS
+PG_CONFIG = pg_config
+PGXS := $(shell $(PG_CONFIG) --pgxs)
+include $(PGXS)
+else
+subdir = src/test/modules/brin
+top_builddir = ../../../..
+include $(top_builddir)/src/Makefile.global
+include $(top_srcdir)/contrib/contrib-global.mk
+endif
diff --git a/src/test/modules/brin/expected/summarization-and-inprogress-insertion.out b/src/test/modules/brin/expected/summarization-and-inprogress-insertion.out
new file mode 100644
index 0000000..584ac26
--- /dev/null
+++ b/src/test/modules/brin/expected/summarization-and-inprogress-insertion.out
@@ -0,0 +1,51 @@
+Parsed test spec with 2 sessions
+
+starting permutation: s2check s1b s2b s1i s2summ s1c s2c s2check
+step s2check: SELECT * FROM brin_page_items(get_raw_page('brinidx', 2), 'brinidx'::regclass);
+itemoffset|blknum|attnum|allnulls|hasnulls|placeholder|value
+----------+------+------+--------+--------+-----------+--------
+ 1| 0| 1|f |t |f |{1 .. 1}
+(1 row)
+
+step s1b: BEGIN ISOLATION LEVEL REPEATABLE READ;
+step s2b: BEGIN ISOLATION LEVEL REPEATABLE READ; SELECT 1;
+?column?
+--------
+ 1
+(1 row)
+
+step s1i: INSERT INTO brin_iso VALUES (1000);
+step s2summ: SELECT brin_summarize_new_values('brinidx'::regclass);
+brin_summarize_new_values
+-------------------------
+ 1
+(1 row)
+
+step s1c: COMMIT;
+step s2c: COMMIT;
+step s2check: SELECT * FROM brin_page_items(get_raw_page('brinidx', 2), 'brinidx'::regclass);
+itemoffset|blknum|attnum|allnulls|hasnulls|placeholder|value
+----------+------+------+--------+--------+-----------+-----------
+ 1| 0| 1|f |t |f |{1 .. 1}
+ 2| 1| 1|f |f |f |{1 .. 1000}
+(2 rows)
+
+
+starting permutation: s2check s1b s1i s2vacuum s1c s2check
+step s2check: SELECT * FROM brin_page_items(get_raw_page('brinidx', 2), 'brinidx'::regclass);
+itemoffset|blknum|attnum|allnulls|hasnulls|placeholder|value
+----------+------+------+--------+--------+-----------+--------
+ 1| 0| 1|f |t |f |{1 .. 1}
+(1 row)
+
+step s1b: BEGIN ISOLATION LEVEL REPEATABLE READ;
+step s1i: INSERT INTO brin_iso VALUES (1000);
+step s2vacuum: VACUUM brin_iso;
+step s1c: COMMIT;
+step s2check: SELECT * FROM brin_page_items(get_raw_page('brinidx', 2), 'brinidx'::regclass);
+itemoffset|blknum|attnum|allnulls|hasnulls|placeholder|value
+----------+------+------+--------+--------+-----------+-----------
+ 1| 0| 1|f |t |f |{1 .. 1}
+ 2| 1| 1|f |f |f |{1 .. 1000}
+(2 rows)
+
diff --git a/src/test/modules/brin/specs/summarization-and-inprogress-insertion.spec b/src/test/modules/brin/specs/summarization-and-inprogress-insertion.spec
new file mode 100644
index 0000000..18ba92b
--- /dev/null
+++ b/src/test/modules/brin/specs/summarization-and-inprogress-insertion.spec
@@ -0,0 +1,45 @@
+# This test verifies that values inserted in transactions still in progress
+# are considered during concurrent range summarization (either using the
+# brin_summarize_new_values function or regular VACUUM).
+
+setup
+{
+ CREATE TABLE brin_iso (
+ value int
+ ) WITH (fillfactor=10);
+ CREATE INDEX brinidx ON brin_iso USING brin (value) WITH (pages_per_range=1);
+ -- this fills the first page
+ INSERT INTO brin_iso VALUES (NULL);
+ DO $$
+ DECLARE curtid tid;
+ BEGIN
+ LOOP
+ INSERT INTO brin_iso VALUES (1) RETURNING ctid INTO curtid;
+ EXIT WHEN curtid > tid '(1, 0)';
+ END LOOP;
+ END;
+ $$;
+ CREATE EXTENSION IF NOT EXISTS pageinspect;
+}
+
+teardown
+{
+ DROP TABLE brin_iso;
+}
+
+session "s1"
+step "s1b" { BEGIN ISOLATION LEVEL REPEATABLE READ; }
+step "s1i" { INSERT INTO brin_iso VALUES (1000); }
+step "s1c" { COMMIT; }
+
+session "s2"
+step "s2b" { BEGIN ISOLATION LEVEL REPEATABLE READ; SELECT 1; }
+step "s2summ" { SELECT brin_summarize_new_values('brinidx'::regclass); }
+step "s2c" { COMMIT; }
+
+step "s2vacuum" { VACUUM brin_iso; }
+
+step "s2check" { SELECT * FROM brin_page_items(get_raw_page('brinidx', 2), 'brinidx'::regclass); }
+
+permutation "s2check" "s1b" "s2b" "s1i" "s2summ" "s1c" "s2c" "s2check"
+permutation "s2check" "s1b" "s1i" "s2vacuum" "s1c" "s2check"
diff --git a/src/test/modules/brin/t/01_workitems.pl b/src/test/modules/brin/t/01_workitems.pl
new file mode 100644
index 0000000..3108c02
--- /dev/null
+++ b/src/test/modules/brin/t/01_workitems.pl
@@ -0,0 +1,46 @@
+
+# Copyright (c) 2021-2022, PostgreSQL Global Development Group
+
+# Verify that work items work correctly
+
+use strict;
+use warnings;
+
+use PostgreSQL::Test::Utils;
+use Test::More;
+use PostgreSQL::Test::Cluster;
+
+my $node = PostgreSQL::Test::Cluster->new('tango');
+$node->init;
+$node->append_conf('postgresql.conf', 'autovacuum_naptime=1s');
+$node->start;
+
+$node->safe_psql('postgres', 'create extension pageinspect');
+
+# Create a table with an autosummarizing BRIN index
+$node->safe_psql(
+ 'postgres',
+ 'create table brin_wi (a int) with (fillfactor = 10);
+ create index brin_wi_idx on brin_wi using brin (a) with (pages_per_range=1, autosummarize=on);
+ '
+);
+my $count = $node->safe_psql('postgres',
+ "select count(*) from brin_page_items(get_raw_page('brin_wi_idx', 2), 'brin_wi_idx'::regclass)"
+);
+is($count, '1', "initial index state is correct");
+
+$node->safe_psql('postgres',
+ 'insert into brin_wi select * from generate_series(1, 100)');
+
+$node->poll_query_until(
+ 'postgres',
+ "select count(*) > 1 from brin_page_items(get_raw_page('brin_wi_idx', 2), 'brin_wi_idx'::regclass)",
+ 't');
+
+$count = $node->safe_psql('postgres',
+ "select count(*) > 1 from brin_page_items(get_raw_page('brin_wi_idx', 2), 'brin_wi_idx'::regclass)"
+);
+is($count, 't', "index got summarized");
+$node->stop;
+
+done_testing();
diff --git a/src/test/modules/brin/t/02_wal_consistency.pl b/src/test/modules/brin/t/02_wal_consistency.pl
new file mode 100644
index 0000000..cbc269b
--- /dev/null
+++ b/src/test/modules/brin/t/02_wal_consistency.pl
@@ -0,0 +1,75 @@
+# Copyright (c) 2021-2022, PostgreSQL Global Development Group
+
+# Verify WAL consistency
+
+use strict;
+use warnings;
+
+use PostgreSQL::Test::Utils;
+use Test::More;
+use PostgreSQL::Test::Cluster;
+
+# Set up primary
+my $whiskey = PostgreSQL::Test::Cluster->new('whiskey');
+$whiskey->init(allows_streaming => 1);
+$whiskey->append_conf('postgresql.conf', 'wal_consistency_checking = brin');
+$whiskey->start;
+$whiskey->safe_psql('postgres', 'create extension pageinspect');
+$whiskey->safe_psql('postgres', 'create extension pg_walinspect');
+is( $whiskey->psql(
+ 'postgres',
+ qq[SELECT pg_create_physical_replication_slot('standby_1');]),
+ 0,
+ 'physical slot created on primary');
+
+# Take backup
+my $backup_name = 'brinbkp';
+$whiskey->backup($backup_name);
+
+# Create streaming standby linking to primary
+my $charlie = PostgreSQL::Test::Cluster->new('charlie');
+$charlie->init_from_backup($whiskey, $backup_name, has_streaming => 1);
+$charlie->append_conf('postgresql.conf', 'primary_slot_name = standby_1');
+$charlie->start;
+
+# Now write some WAL in the primary
+
+$whiskey->safe_psql(
+ 'postgres', qq{
+create table tbl_timestamp0 (d1 timestamp(0) without time zone) with (fillfactor=10);
+create index on tbl_timestamp0 using brin (d1) with (pages_per_range = 1, autosummarize=false);
+});
+my $start_lsn = $whiskey->lsn('insert');
+# Run a loop that will end when the second revmap page is created
+$whiskey->safe_psql(
+ 'postgres', q{
+do
+$$
+declare
+ current timestamp with time zone := '2019-03-27 08:14:01.123456789 UTC';
+begin
+ loop
+ insert into tbl_timestamp0 select i from
+ generate_series(current, current + interval '1 day', '28 seconds') i;
+ perform brin_summarize_new_values('tbl_timestamp0_d1_idx');
+ if (brin_metapage_info(get_raw_page('tbl_timestamp0_d1_idx', 0))).lastrevmappage > 1 then
+ exit;
+ end if;
+ current := current + interval '1 day';
+ end loop;
+end
+$$;
+});
+my $end_lsn = $whiskey->lsn('flush');
+
+my ($ret, $out, $err) = $whiskey->psql(
+ 'postgres', qq{
+ select count(*) from pg_get_wal_records_info('$start_lsn', '$end_lsn')
+ where resource_manager = 'BRIN' AND
+ record_type ILIKE '%revmap%'
+ });
+cmp_ok($out, '>=', 1);
+
+$whiskey->wait_for_catchup($charlie, 'replay', $whiskey->lsn('insert'));
+
+done_testing();