aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/access/brin/brin_pageops.c7
-rw-r--r--src/backend/access/brin/brin_xlog.c6
-rw-r--r--src/test/modules/brin/t/02_wal_consistency.pl64
3 files changed, 76 insertions, 1 deletions
diff --git a/src/backend/access/brin/brin_pageops.c b/src/backend/access/brin/brin_pageops.c
index df9ffc2fb86..992b33a8964 100644
--- a/src/backend/access/brin/brin_pageops.c
+++ b/src/backend/access/brin/brin_pageops.c
@@ -541,7 +541,12 @@ brin_start_evacuating_page(Relation idxRel, Buffer buf)
lp = PageGetItemId(page, off);
if (ItemIdIsUsed(lp))
{
- /* prevent other backends from adding more stuff to this page */
+ /*
+ * Prevent other backends from adding more stuff to this page:
+ * BRIN_EVACUATE_PAGE informs br_page_get_freespace that this page
+ * can no longer be used to add new tuples. Note that this flag
+ * is not WAL-logged, except accidentally.
+ */
BrinPageFlags(page) |= BRIN_EVACUATE_PAGE;
MarkBufferDirtyHint(buf, true);
diff --git a/src/backend/access/brin/brin_xlog.c b/src/backend/access/brin/brin_xlog.c
index 39dc130e162..3519038b709 100644
--- a/src/backend/access/brin/brin_xlog.c
+++ b/src/backend/access/brin/brin_xlog.c
@@ -358,4 +358,10 @@ brin_mask(char *pagedata, BlockNumber blkno)
{
mask_unused_space(page);
}
+
+ /*
+ * BRIN_EVACUATE_PAGE is not WAL-logged, since it's of no use in recovery.
+ * Mask it. See brin_start_evacuating_page() for details.
+ */
+ BrinPageFlags(page) &= ~BRIN_EVACUATE_PAGE;
}
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 00000000000..47e8be28960
--- /dev/null
+++ b/src/test/modules/brin/t/02_wal_consistency.pl
@@ -0,0 +1,64 @@
+# 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');
+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);
+});
+# 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 America/Punta_Arenas';
+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
+$$;
+});
+
+$whiskey->wait_for_catchup($charlie, 'replay', $whiskey->lsn('insert'));
+
+done_testing();