standby_checkpoint_segments_9.2dev_fix_20120516.patch
application/octet-stream
Filename: standby_checkpoint_segments_9.2dev_fix_20120516.patch
Type: application/octet-stream
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 | 43 | 10 |
diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c
index c9473f7..babb874 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"
@@ -157,6 +158,8 @@ static bool am_checkpointer = false;
static bool ckpt_active = false;
+static bool walreceiver_started = false;
+
/* these values are valid when ckpt_active is true: */
static pg_time_t ckpt_start_time;
static XLogRecPtr ckpt_start_recptr;
@@ -168,6 +171,7 @@ static pg_time_t last_xlog_switch_time;
/* Prototypes for private functions */
static void CheckArchiveTimeout(void);
+static bool WalRcvStarted(void);
static bool IsCheckpointOnSchedule(double progress);
static bool ImmediateCheckpointRequested(void);
static bool CompactCheckpointerRequestQueue(void);
@@ -491,8 +495,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;
@@ -638,6 +642,25 @@ ImmediateCheckpointRequested(void)
}
/*
+ * WalRcvStarted -- Return whether WAL is coming via streaming
+ *
+ * WalRcvInProgress() indicates simply whether wal receiver is running or not
+ * at the moment this function is called. This natuer is not suitable to
+ * determine current source of WAL. WalRcvStarted() returns false before
+ * wal receiver is found running and true after that regardless whether wal
+ * receiver is actually running or not at the moment.
+ */
+bool
+WalRcvStarted()
+{
+ if (!walreceiver_started && WalRcvInProgress())
+ walreceiver_started = true;
+
+ return walreceiver_started;
+}
+
+
+/*
* CheckpointWriteDelay -- control rate of checkpoint
*
* This function is called after each page write performed by BufferSync().
@@ -715,6 +738,7 @@ IsCheckpointOnSchedule(double progress)
struct timeval now;
double elapsed_xlogs,
elapsed_time;
+ bool recovery_in_progress;
Assert(ckpt_active);
@@ -731,18 +755,27 @@ 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.
+ * computed before calling CreateCheckPoint. The code in
+ * XLogInsert that actually triggers a checkpoint when
+ * checkpoint_segments is exceeded 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) /