]> granicus.if.org Git - postgresql/commitdiff
Treat a WAL sender process that hasn't started streaming yet as a regular
authorHeikki Linnakangas <heikki.linnakangas@iki.fi>
Sat, 15 Jan 2011 14:27:40 +0000 (16:27 +0200)
committerHeikki Linnakangas <heikki.linnakangas@iki.fi>
Sat, 15 Jan 2011 14:38:21 +0000 (16:38 +0200)
backend, as far as the postmaster shutdown logic is concerned. That means,
fast shutdown will wait for WAL sender processes to exit before signaling
bgwriter to finish. This avoids race conditions between a base backup stopping
or starting, and bgwriter writing the shutdown checkpoint WAL record. We don't
want e.g the end-of-backup WAL record to be written after the shutdown
checkpoint.

src/backend/replication/walsender.c
src/backend/storage/ipc/pmsignal.c
src/include/storage/pmsignal.h

index d078501814c7a55f6fadac59b2da56921893e3cb..0ad6804e55204355849faa3da273ec3fac7eb6b7 100644 (file)
@@ -315,6 +315,16 @@ StartReplication(StartReplicationCmd * cmd)
 {
        StringInfoData buf;
 
+       /*
+        * Let postmaster know that we're streaming. Once we've declared us as
+        * a WAL sender process, postmaster will let us outlive the bgwriter and
+        * kill us last in the shutdown sequence, so we get a chance to stream
+        * all remaining WAL at shutdown, including the shutdown checkpoint.
+        * Note that there's no going back, and we mustn't write any WAL records
+        * after this.
+        */
+       MarkPostmasterChildWalSender();
+
        /*
         * Check that we're logging enough information in the WAL for
         * log-shipping.
index 155bd751bf2ce6f194a7a0f9024af16ba83bafd8..391d6a6ea046e45b88a8c9bd3d47ea7e25fa18e7 100644 (file)
@@ -49,6 +49,8 @@
  *
  * Actually there is a fourth state, WALSENDER.  This is just like ACTIVE,
  * but carries the extra information that the child is a WAL sender.
+ * WAL senders too start in ACTIVE state, but switch to WALSENDER once they
+ * start streaming the WAL (and they never go back to ACTIVE after that).
  */
 
 #define PM_CHILD_UNUSED                0       /* these values must fit in sig_atomic_t */
@@ -225,8 +227,25 @@ MarkPostmasterChildActive(void)
        Assert(slot > 0 && slot <= PMSignalState->num_child_flags);
        slot--;
        Assert(PMSignalState->PMChildFlags[slot] == PM_CHILD_ASSIGNED);
-       PMSignalState->PMChildFlags[slot] =
-               (am_walsender ? PM_CHILD_WALSENDER : PM_CHILD_ACTIVE);
+       PMSignalState->PMChildFlags[slot] = PM_CHILD_ACTIVE;
+}
+
+/*
+ * MarkPostmasterChildWalSender - mark a postmaster child as a WAL sender
+ * process.  This is called in the child process, sometime after marking the
+ * child as active.
+ */
+void
+MarkPostmasterChildWalSender(void)
+{
+       int                     slot = MyPMChildSlot;
+
+       Assert(am_walsender);
+
+       Assert(slot > 0 && slot <= PMSignalState->num_child_flags);
+       slot--;
+       Assert(PMSignalState->PMChildFlags[slot] == PM_CHILD_ACTIVE);
+       PMSignalState->PMChildFlags[slot] = PM_CHILD_WALSENDER;
 }
 
 /*
index 2deff728ecd3e38fcfa0a8de5b4ac9f677b21e7a..97bdc7bc86d7f5d78e8ede1eee4edd8742e94ad8 100644 (file)
@@ -48,6 +48,7 @@ extern bool ReleasePostmasterChildSlot(int slot);
 extern bool IsPostmasterChildWalSender(int slot);
 extern void MarkPostmasterChildActive(void);
 extern void MarkPostmasterChildInactive(void);
+extern void MarkPostmasterChildWalSender(void);
 extern bool PostmasterIsAlive(bool amDirectChild);
 
 #endif   /* PMSIGNAL_H */