* in case they don't have a watch.
*
* If the user disables feedback, send one final message to tell sender
- * to forget about the xmin on this standby.
+ * to forget about the xmin on this standby. We also send this message
+ * on first connect because a previous connection might have set xmin
+ * on a replication slot. (If we're not using a slot it's harmless to
+ * send a feedback message explicitly setting InvalidTransactionId).
*/
static void
XLogWalRcvSendHSFeedback(bool immed)
uint32 nextEpoch;
TransactionId xmin;
static TimestampTz sendTime = 0;
- static bool master_has_standby_xmin = false;
+ /* initially true so we always send at least one feedback message */
+ static bool master_has_standby_xmin = true;
/*
* If the user doesn't want status to be reported to the master, be sure
}
/*
- * If Hot Standby is not yet active there is nothing to send. Check this
- * after the interval has expired to reduce number of calls.
+ * If Hot Standby is not yet accepting connections there is nothing to
+ * send. Check this after the interval has expired to reduce number of
+ * calls.
+ *
+ * Bailing out here also ensures that we don't send feedback until we've
+ * read our own replication slot state, so we don't tell the master to
+ * discard needed xmin or catalog_xmin from any slots that may exist
+ * on this replica.
*/
if (!HotStandbyActive())
- {
- Assert(!master_has_standby_xmin);
return;
- }
/*
* Make the expensive call to get the oldest xmin once we are certain
use warnings;
use PostgresNode;
use TestLib;
-use Test::More tests => 22;
+use Test::More tests => 24;
# Initialize master node
my $node_master = get_new_node('master');
($xmin, $catalog_xmin) = get_slot_xmins($node_standby_1, $slotname_2);
is($xmin, '', 'cascaded slot xmin null with hs feedback reset');
is($catalog_xmin, '', 'cascaded slot xmin still null with hs_feedback reset');
+
+diag "re-enabling hot_standby_feedback and disabling while stopped";
+$node_standby_2->safe_psql('postgres', 'ALTER SYSTEM SET hot_standby_feedback = on;');
+$node_standby_2->reload;
+
+$node_master->safe_psql('postgres', qq[INSERT INTO tab_int VALUES (11000);]);
+replay_check();
+
+$node_standby_2->safe_psql('postgres', 'ALTER SYSTEM SET hot_standby_feedback = off;');
+$node_standby_2->stop;
+
+($xmin, $catalog_xmin) = get_slot_xmins($node_standby_1, $slotname_2);
+isnt($xmin, '', 'cascaded slot xmin non-null with postgres shut down');
+
+# Xmin from a previous run should be cleared on startup.
+$node_standby_2->start;
+
+($xmin, $catalog_xmin) = get_slot_xmins($node_standby_1, $slotname_2);
+is($xmin, '', 'cascaded slot xmin reset after startup with hs feedback reset');