chkpt_segs_for_standby_20120608_1.patch
text/x-patch
Filename: chkpt_segs_for_standby_20120608_1.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| src/backend/postmaster/checkpointer.c | 18 | 8 |
| src/backend/replication/walreceiver.c | 1 | 0 |
| src/backend/replication/walreceiverfuncs.c | 20 | 0 |
| src/include/replication/walreceiver.h | 2 | 0 |
diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c
index 6aeade9..cb2509a 100644
--- a/src/backend/postmaster/checkpointer.c
+++ b/src/backend/postmaster/checkpointer.c
@@ -46,6 +46,7 @@
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/bgwriter.h"
+#include "replication/walreceiver.h"
#include "replication/syncrep.h"
#include "storage/bufmgr.h"
#include "storage/ipc.h"
@@ -493,8 +494,8 @@ CheckpointerMain(void)
* Initialize checkpointer-private variables used during checkpoint
*/
ckpt_active = true;
- if (!do_restartpoint)
- ckpt_start_recptr = GetInsertRecPtr();
+ ckpt_start_recptr =
+ do_restartpoint ? GetXLogReplayRecPtr(NULL) : GetInsertRecPtr();
ckpt_start_time = now;
ckpt_cached_elapsed = 0;
@@ -747,6 +748,7 @@ IsCheckpointOnSchedule(double progress)
struct timeval now;
double elapsed_xlogs,
elapsed_time;
+ bool recovery_in_progress;
Assert(ckpt_active);
@@ -763,18 +765,26 @@ IsCheckpointOnSchedule(double progress)
return false;
/*
- * Check progress against WAL segments written and checkpoint_segments.
+ * Check progress against WAL segments written, or replayed for
+ * hot standby, and checkpoint_segments.
*
* We compare the current WAL insert location against the location
* computed before calling CreateCheckPoint. The code in XLogInsert that
* actually triggers a checkpoint when checkpoint_segments is exceeded
- * compares against RedoRecptr, so this is not completely accurate.
- * However, it's good enough for our purposes, we're only calculating an
- * estimate anyway.
+ * compares against RedoRecPtr. Similarly, we consult WAL replay location
+ * instead on hot standbys and XLogPageRead compares it aganst RedoRecPtr,
+ * too. Altough these are not completely accurate, it's good enough for
+ * our purposes, we're only calculating an estimate anyway.
+ */
+
+ /*
+ * Inhibit governing progress by segments in archive recovery.
*/
- if (!RecoveryInProgress())
+ recovery_in_progress = RecoveryInProgress();
+ if (!recovery_in_progress || WalRcvStarted())
{
- recptr = GetInsertRecPtr();
+ recptr = recovery_in_progress ? GetXLogReplayRecPtr(NULL) :
+ GetInsertRecPtr();
elapsed_xlogs =
(((double) (int32) (recptr.xlogid - ckpt_start_recptr.xlogid)) * XLogSegsPerFile +
((double) recptr.xrecoff - (double) ckpt_start_recptr.xrecoff) / XLogSegSize) /
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c
index d63ff29..7d57ad7 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -215,6 +215,7 @@ WalReceiverMain(void)
/* Advertise our PID so that the startup process can kill us */
walrcv->pid = MyProcPid;
walrcv->walRcvState = WALRCV_RUNNING;
+ walrcv->started = true;
/* Fetch information required to start streaming */
strlcpy(conninfo, (char *) walrcv->conninfo, MAXCONNINFO);
diff --git a/src/backend/replication/walreceiverfuncs.c b/src/backend/replication/walreceiverfuncs.c
index f8dd523..c3b26e9 100644
--- a/src/backend/replication/walreceiverfuncs.c
+++ b/src/backend/replication/walreceiverfuncs.c
@@ -31,6 +31,7 @@
#include "utils/timestamp.h"
WalRcvData *WalRcv = NULL;
+static bool localWalRcvStarted = false;
/*
* How long to wait for walreceiver to start up after requesting
@@ -167,6 +168,25 @@ ShutdownWalRcv(void)
}
/*
+ * Returns true if WAL receiver has been launced so far regardless of current
+ * state.
+ */
+bool
+WalRcvStarted(void)
+{
+ /* WalRcv->started changes one way throughout the server life */
+ if (!localWalRcvStarted)
+ {
+ volatile WalRcvData *walrcv = WalRcv;
+
+ SpinLockAcquire(&walrcv->mutex);
+ localWalRcvStarted = walrcv->started;
+ SpinLockRelease(&walrcv->mutex);
+ }
+ return localWalRcvStarted;
+}
+
+/*
* Request postmaster to start walreceiver.
*
* recptr indicates the position where streaming should begin, and conninfo
diff --git a/src/include/replication/walreceiver.h b/src/include/replication/walreceiver.h
index 68c8647..24901be 100644
--- a/src/include/replication/walreceiver.h
+++ b/src/include/replication/walreceiver.h
@@ -53,6 +53,7 @@ typedef struct
*/
pid_t pid;
WalRcvState walRcvState;
+ bool started;
pg_time_t startTime;
/*
@@ -116,6 +117,7 @@ extern Size WalRcvShmemSize(void);
extern void WalRcvShmemInit(void);
extern void ShutdownWalRcv(void);
extern bool WalRcvInProgress(void);
+extern bool WalRcvStarted(void);
extern void RequestXLogStreaming(XLogRecPtr recptr, const char *conninfo);
extern XLogRecPtr GetWalRcvWriteRecPtr(XLogRecPtr *latestChunkStart);
extern int GetReplicationApplyDelay(void);