Reset hot standby xmin after restart
authorSimon Riggs
Thu, 26 Jan 2017 20:06:44 +0000 (20:06 +0000)
committerSimon Riggs
Thu, 26 Jan 2017 20:06:44 +0000 (20:06 +0000)
Hot_standby_feedback could be reset by reload and worked correctly, but if
the server was restarted rather than reloaded the xmin was not reset.
Force reset always if hot_standby_feedback is enabled at startup.

Ants Aasma, Craig Ringer

Reported-by: Ants Aasma
src/backend/replication/walreceiver.c

index 413ee3a5c18e756e2bc083b92d1593c97dc0bcb2..e0ab112d3138cbe2ff8f32fb4be922cb3bd52163 100644 (file)
@@ -1154,7 +1154,10 @@ XLogWalRcvSendReply(bool force, bool requestReply)
  * 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)
@@ -1164,7 +1167,8 @@ 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
@@ -1189,14 +1193,17 @@ XLogWalRcvSendHSFeedback(bool immed)
    }
 
    /*
-    * 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