0001-A-new-TAP-test-to-test-a-recovery-bug.patch

application/octet-stream

Filename: 0001-A-new-TAP-test-to-test-a-recovery-bug.patch
Type: application/octet-stream
Part: 1
Message: PANIC during crash recovery of a recently promoted standby

Patch

Format: format-patch
Series: patch 0001
Subject: A new TAP test to test a recovery bug.
File+
src/test/recovery/t/014_promotion_bug.pl 72 0
From aa6e9cb102730566ddc1928b9f569d1b29ed7841 Mon Sep 17 00:00:00 2001
From: Pavan Deolasee <pavan.deolasee@gmail.com>
Date: Fri, 2 Mar 2018 17:52:11 +0530
Subject: [PATCH 1/2] A new TAP test to test a recovery bug.

When a standby is promoted to be a master, if the "Minimum recovery ending
location" is left unchanged, a crash in the just promoted standby before the
first checkpoint after promotion is complete, can lead to recovery ending
without references to all invalid pages are resolved. This results in a PANIC
situation.
---
 src/test/recovery/t/014_promotion_bug.pl | 72 ++++++++++++++++++++++++++++++++
 1 file changed, 72 insertions(+)
 create mode 100644 src/test/recovery/t/014_promotion_bug.pl

diff --git a/src/test/recovery/t/014_promotion_bug.pl b/src/test/recovery/t/014_promotion_bug.pl
new file mode 100644
index 0000000000..699de66001
--- /dev/null
+++ b/src/test/recovery/t/014_promotion_bug.pl
@@ -0,0 +1,72 @@
+use strict;
+use warnings;
+use PostgresNode;
+use TestLib;
+use Test::More;
+
+# Initialize master node
+my $alpha = get_new_node('alpha');
+$alpha->init;
+$alpha->append_conf("postgresql.conf", <<EOF);
+max_wal_senders=5
+wal_level=replica
+min_wal_size=1GB
+max_wal_size=16GB
+hot_standby=on
+EOF
+
+$alpha->append_conf("pg_hba.conf", <<EOF);
+local	replication	all	trust
+EOF
+
+# Start the master
+$alpha->start;
+
+# setup/start a standby
+$alpha->backup('bkp');
+my $bravo = get_new_node('bravo');
+$bravo->init_from_backup($alpha, 'bkp', has_streaming => 1);
+$bravo->append_conf('postgresql.conf', <<EOF);
+checkpoint_timeout=1h
+checkpoint_completion_target=0.9
+EOF
+$bravo->start;
+
+$alpha->safe_psql('postgres', 'create table test1 (a int)');
+$alpha->safe_psql('postgres', 'insert into test1 select generate_series(1, 10000)');
+
+# take a checkpoint
+$alpha->safe_psql('postgres', 'checkpoint');
+
+# the following vacuum will set visibility map bits and create problematic WAL
+# records
+$alpha->safe_psql('postgres', 'vacuum verbose test1');
+sleep 10;
+
+# now force a checkpoint on the standby. This seems unnecessary but for "some"
+# reason, the previous checkpoint on the master does not reflect on the standby
+# and without an explicit checkpoint, it may start redo recovery from a much
+# older point (which includes even create table and initial page additions
+$bravo->safe_psql('postgres', 'checkpoint');
+
+# here the original runs pg_controldata
+
+# now just use a dummy table and run some operations to move minRecoveryPoint
+# beyond the previous vacuum
+$alpha->safe_psql('postgres', 'create table test2 (a int, b text)');
+$alpha->safe_psql('postgres', 'insert into test2 select generate_series(1,10000), md5(random()::text)');
+$alpha->safe_psql('postgres', 'truncate test2');
+
+$bravo->promote;
+sleep 2;
+
+# fun time.. truncate the table on the promoted standby, vacuum and extend it
+# again
+$bravo->safe_psql('postgres', 'truncate test1');
+$bravo->safe_psql('postgres', 'vacuum verbose test1');
+$bravo->safe_psql('postgres', 'insert into test1 select generate_series(1,1000)');
+#
+# now crash-stop the promoted standby and restart. If timing is correct, you
+# should see a PANIC 
+$bravo->stop('immediate');
+$bravo->start;
-- 
2.14.3 (Apple Git-98)