@@ -369,6 +369,16 @@ StartReplication(StartReplicationCmd * cmd)
369
369
(errcode (ERRCODE_CANNOT_CONNECT_NOW ),
370
370
errmsg ("standby connections not allowed because wal_level=minimal" )));
371
371
372
+ /*
373
+ * When we first start replication the standby will be behind the primary.
374
+ * For some applications, for example, synchronous replication, it is
375
+ * important to have a clear state for this initial catchup mode, so we
376
+ * can trigger actions when we change streaming state later. We may stay
377
+ * in this state for a long time, which is exactly why we want to be
378
+ * able to monitor whether or not we are still here.
379
+ */
380
+ WalSndSetState (WALSNDSTATE_CATCHUP );
381
+
372
382
/* Send a CopyBothResponse message, and start streaming */
373
383
pq_beginmessage (& buf , 'W' );
374
384
pq_sendbyte (& buf , 0 );
@@ -752,8 +762,17 @@ WalSndLoop(void)
752
762
break ;
753
763
}
754
764
755
- /* Update our state to indicate if we're behind or not */
756
- WalSndSetState (caughtup ? WALSNDSTATE_STREAMING : WALSNDSTATE_CATCHUP );
765
+ /*
766
+ * If we're in catchup state, see if its time to move to streaming.
767
+ * This is an important state change for users, since before this
768
+ * point data loss might occur if the primary dies and we need to
769
+ * failover to the standby. The state change is also important for
770
+ * synchronous replication, since commits that started to wait at
771
+ * that point might wait for some time.
772
+ */
773
+ if (MyWalSnd -> state == WALSNDSTATE_CATCHUP && caughtup )
774
+ WalSndSetState (WALSNDSTATE_STREAMING );
775
+
757
776
ProcessRepliesIfAny ();
758
777
}
759
778
0 commit comments