7
7
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
8
8
* Portions Copyright (c) 1994, Regents of the University of California
9
9
*
10
- * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.418 2010/06/09 10:54:45 mha Exp $
10
+ * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.419 2010/06/09 15:04:06 heikki Exp $
11
11
*
12
12
*-------------------------------------------------------------------------
13
13
*/
@@ -508,6 +508,9 @@ static bool reachedMinRecoveryPoint = false;
508
508
509
509
static bool InRedo = false;
510
510
511
+ /* Have we launched bgwriter during recovery? */
512
+ static bool bgwriterLaunched = false;
513
+
511
514
/*
512
515
* Information logged when we detect a change in one of the parameters
513
516
* important for Hot Standby.
@@ -550,6 +553,7 @@ static void CheckPointGuts(XLogRecPtr checkPointRedo, int flags);
550
553
static bool XLogCheckBuffer (XLogRecData * rdata , bool doPageWrites ,
551
554
XLogRecPtr * lsn , BkpBlock * bkpb );
552
555
static bool AdvanceXLInsertBuffer (bool new_segment );
556
+ static bool XLogCheckpointNeeded (uint32 logid , uint32 logseg );
553
557
static void XLogWrite (XLogwrtRqst WriteRqst , bool flexible , bool xlog_switch );
554
558
static bool InstallXLogFileSegment (uint32 * log , uint32 * seg , char * tmppath ,
555
559
bool find_free , int * max_advance ,
@@ -1554,14 +1558,14 @@ AdvanceXLInsertBuffer(bool new_segment)
1554
1558
/*
1555
1559
* Check whether we've consumed enough xlog space that a checkpoint is needed.
1556
1560
*
1557
- * Caller must have just finished filling the open log file (so that
1558
- * openLogId/openLogSeg are valid ). We measure the distance from RedoRecPtr
1559
- * to the open log file and see if that exceeds CheckPointSegments.
1561
+ * logid/logseg indicate a log file that has just been filled up (or read
1562
+ * during recovery ). We measure the distance from RedoRecPtr to logid/logseg
1563
+ * and see if that exceeds CheckPointSegments.
1560
1564
*
1561
1565
* Note: it is caller's responsibility that RedoRecPtr is up-to-date.
1562
1566
*/
1563
1567
static bool
1564
- XLogCheckpointNeeded (void )
1568
+ XLogCheckpointNeeded (uint32 logid , uint32 logseg )
1565
1569
{
1566
1570
/*
1567
1571
* A straight computation of segment number could overflow 32 bits. Rather
@@ -1577,8 +1581,8 @@ XLogCheckpointNeeded(void)
1577
1581
old_segno = (RedoRecPtr .xlogid % XLogSegSize ) * XLogSegsPerFile +
1578
1582
(RedoRecPtr .xrecoff / XLogSegSize );
1579
1583
old_highbits = RedoRecPtr .xlogid / XLogSegSize ;
1580
- new_segno = (openLogId % XLogSegSize ) * XLogSegsPerFile + openLogSeg ;
1581
- new_highbits = openLogId / XLogSegSize ;
1584
+ new_segno = (logid % XLogSegSize ) * XLogSegsPerFile + logseg ;
1585
+ new_highbits = logid / XLogSegSize ;
1582
1586
if (new_highbits != old_highbits ||
1583
1587
new_segno >= old_segno + (uint32 ) (CheckPointSegments - 1 ))
1584
1588
return true;
@@ -1782,10 +1786,10 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch)
1782
1786
* update RedoRecPtr and recheck.
1783
1787
*/
1784
1788
if (IsUnderPostmaster &&
1785
- XLogCheckpointNeeded ())
1789
+ XLogCheckpointNeeded (openLogId , openLogSeg ))
1786
1790
{
1787
1791
(void ) GetRedoRecPtr ();
1788
- if (XLogCheckpointNeeded ())
1792
+ if (XLogCheckpointNeeded (openLogId , openLogSeg ))
1789
1793
RequestCheckpoint (CHECKPOINT_CAUSE_XLOG );
1790
1794
}
1791
1795
}
@@ -5653,7 +5657,6 @@ StartupXLOG(void)
5653
5657
XLogRecord * record ;
5654
5658
uint32 freespace ;
5655
5659
TransactionId oldestActiveXID ;
5656
- bool bgwriterLaunched = false;
5657
5660
5658
5661
/*
5659
5662
* Read control file and check XLOG status looks valid.
@@ -7576,6 +7579,21 @@ CreateRestartPoint(int flags)
7576
7579
return false;
7577
7580
}
7578
7581
7582
+ /*
7583
+ * Update the shared RedoRecPtr so that the startup process can
7584
+ * calculate the number of segments replayed since last restartpoint,
7585
+ * and request a restartpoint if it exceeds checkpoint_segments.
7586
+ *
7587
+ * You need to hold WALInsertLock and info_lck to update it, although
7588
+ * during recovery acquiring WALInsertLock is just pro forma, because
7589
+ * there is no other processes updating Insert.RedoRecPtr.
7590
+ */
7591
+ LWLockAcquire (WALInsertLock , LW_EXCLUSIVE );
7592
+ SpinLockAcquire (& xlogctl -> info_lck );
7593
+ xlogctl -> Insert .RedoRecPtr = lastCheckPoint .redo ;
7594
+ SpinLockRelease (& xlogctl -> info_lck );
7595
+ LWLockRelease (WALInsertLock );
7596
+
7579
7597
if (log_checkpoints )
7580
7598
{
7581
7599
/*
@@ -9209,6 +9227,20 @@ XLogPageRead(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt,
9209
9227
*/
9210
9228
if (readFile >= 0 && !XLByteInSeg (* RecPtr , readId , readSeg ))
9211
9229
{
9230
+ /*
9231
+ * Signal bgwriter to start a restartpoint if we've replayed too
9232
+ * much xlog since the last one.
9233
+ */
9234
+ if (StandbyMode && bgwriterLaunched )
9235
+ {
9236
+ if (XLogCheckpointNeeded (readId , readSeg ))
9237
+ {
9238
+ (void ) GetRedoRecPtr ();
9239
+ if (XLogCheckpointNeeded (readId , readSeg ))
9240
+ RequestCheckpoint (CHECKPOINT_CAUSE_XLOG );
9241
+ }
9242
+ }
9243
+
9212
9244
close (readFile );
9213
9245
readFile = -1 ;
9214
9246
readSource = 0 ;
0 commit comments