On Fri, May 28, 2010 at 11:12 AM, Fujii Masao <masao.fu...@gmail.com> wrote: > On Thu, May 27, 2010 at 11:13 PM, Robert Haas <robertmh...@gmail.com> wrote: >>> I guess this happens because the frequency of checkpoint on the standby is >>> too lower than that on the master. In the master, checkpoint occurs for >>> every >>> consumption of three segments because of "checkpoint_segments = 3". On the >>> other hand, in the standby, only checkpoint_timeout has effect, so >>> checkpoint >>> occurs for every 30 minutes because of "checkpoint_timeout = 30min". >>> >>> The walreceiver should signal the bgwriter to start checkpoint if it has >>> received more than checkpoint_segments WAL files, like normal processing? >> >> Is this also an issue when using log shipping, or just with SR? > > When using log shipping, checkpoint_segments always doesn't trigger a > checkpoint. So recovery after the standby crashes might take unexpectedly > long since redo starting point might be old. > > But in file-based log shipping, since WAL files don't accumulate in > pg_xlog directory on the standby, even if the frequency of checkpoint > is very low, pg_xlog will not be filled with many WAL files. That > accumulation occurs only when using SR. > > If we should avoid low frequency of checkpoint itself rather than > accumulation of WAL files, the bgwriter instead of the walreceiver > should check if we've consumed too much WAL, I think. Thought?
I attached the patch, which changes the startup process so that it signals bgwriter to perform a restartpoint if we've already replayed too much WAL files. This leads checkpoint_segments to trigger a restartpoint. This patch is worth applying for 9.0? If not, I'll add it into the next CF. Regards, -- Fujii Masao NIPPON TELEGRAPH AND TELEPHONE CORPORATION NTT Open Source Software Center
*** a/src/backend/access/transam/xlog.c --- b/src/backend/access/transam/xlog.c *************** *** 508,513 **** static bool reachedMinRecoveryPoint = false; --- 508,516 ---- static bool InRedo = false; + /* We've already launched bgwriter to perform restartpoint? */ + static bool bgwriterLaunched = false; + /* * Information logged when we detect a change in one of the parameters * important for Hot Standby. *************** *** 550,555 **** static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags); --- 553,559 ---- static bool XLogCheckBuffer(XLogRecData *rdata, bool doPageWrites, XLogRecPtr *lsn, BkpBlock *bkpb); static bool AdvanceXLInsertBuffer(bool new_segment); + static bool XLogCheckpointNeeded(uint32 logid, uint32 logseg); static void XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch); static bool InstallXLogFileSegment(uint32 *log, uint32 *seg, char *tmppath, bool find_free, int *max_advance, *************** *** 1554,1567 **** AdvanceXLInsertBuffer(bool new_segment) /* * Check whether we've consumed enough xlog space that a checkpoint is needed. * ! * Caller must have just finished filling the open log file (so that ! * openLogId/openLogSeg are valid). We measure the distance from RedoRecPtr ! * to the open log file and see if that exceeds CheckPointSegments. * * Note: it is caller's responsibility that RedoRecPtr is up-to-date. */ static bool ! XLogCheckpointNeeded(void) { /* * A straight computation of segment number could overflow 32 bits. Rather --- 1558,1571 ---- /* * Check whether we've consumed enough xlog space that a checkpoint is needed. * ! * Caller must have just finished filling or reading the log file (so that ! * the given logid/logseg are valid). We measure the distance from RedoRecPtr ! * to the log file and see if that exceeds CheckPointSegments. * * Note: it is caller's responsibility that RedoRecPtr is up-to-date. */ static bool ! XLogCheckpointNeeded(uint32 logid, uint32 logseg) { /* * A straight computation of segment number could overflow 32 bits. Rather *************** *** 1577,1584 **** XLogCheckpointNeeded(void) old_segno = (RedoRecPtr.xlogid % XLogSegSize) * XLogSegsPerFile + (RedoRecPtr.xrecoff / XLogSegSize); old_highbits = RedoRecPtr.xlogid / XLogSegSize; ! new_segno = (openLogId % XLogSegSize) * XLogSegsPerFile + openLogSeg; ! new_highbits = openLogId / XLogSegSize; if (new_highbits != old_highbits || new_segno >= old_segno + (uint32) (CheckPointSegments - 1)) return true; --- 1581,1588 ---- old_segno = (RedoRecPtr.xlogid % XLogSegSize) * XLogSegsPerFile + (RedoRecPtr.xrecoff / XLogSegSize); old_highbits = RedoRecPtr.xlogid / XLogSegSize; ! new_segno = (logid % XLogSegSize) * XLogSegsPerFile + logseg; ! new_highbits = logid / XLogSegSize; if (new_highbits != old_highbits || new_segno >= old_segno + (uint32) (CheckPointSegments - 1)) return true; *************** *** 1782,1791 **** XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch) * update RedoRecPtr and recheck. */ if (IsUnderPostmaster && ! XLogCheckpointNeeded()) { (void) GetRedoRecPtr(); ! if (XLogCheckpointNeeded()) RequestCheckpoint(CHECKPOINT_CAUSE_XLOG); } } --- 1786,1795 ---- * update RedoRecPtr and recheck. */ if (IsUnderPostmaster && ! XLogCheckpointNeeded(openLogId, openLogSeg)) { (void) GetRedoRecPtr(); ! if (XLogCheckpointNeeded(openLogId, openLogSeg)) RequestCheckpoint(CHECKPOINT_CAUSE_XLOG); } } *************** *** 5643,5649 **** StartupXLOG(void) XLogRecord *record; uint32 freespace; TransactionId oldestActiveXID; - bool bgwriterLaunched = false; /* * Read control file and check XLOG status looks valid. --- 5647,5652 ---- *************** *** 9185,9190 **** XLogPageRead(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt, --- 9188,9207 ---- */ if (readFile >= 0 && !XLByteInSeg(*RecPtr, readId, readSeg)) { + /* + * Signal bgwriter to start a restartpoint if we've replayed too + * much xlog since the last one. + */ + if (bgwriterLaunched) + { + if (XLogCheckpointNeeded(readId, readSeg)) + { + (void) GetRedoRecPtr(); + if (XLogCheckpointNeeded(readId, readSeg)) + RequestCheckpoint(CHECKPOINT_CAUSE_XLOG); + } + } + close(readFile); readFile = -1; readSource = 0;
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers