aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/replication/walsender.c10
-rw-r--r--src/backend/storage/ipc/pmsignal.c23
-rw-r--r--src/include/storage/pmsignal.h1
3 files changed, 32 insertions, 2 deletions
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index d078501814c..0ad6804e552 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -316,6 +316,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.
*
diff --git a/src/backend/storage/ipc/pmsignal.c b/src/backend/storage/ipc/pmsignal.c
index 155bd751bf2..391d6a6ea04 100644
--- a/src/backend/storage/ipc/pmsignal.c
+++ b/src/backend/storage/ipc/pmsignal.c
@@ -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;
}
/*
diff --git a/src/include/storage/pmsignal.h b/src/include/storage/pmsignal.h
index 2deff728ecd..97bdc7bc86d 100644
--- a/src/include/storage/pmsignal.h
+++ b/src/include/storage/pmsignal.h
@@ -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 */