diff options
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r-- | src/backend/access/transam/xlog.c | 100 |
1 files changed, 42 insertions, 58 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 98c610dcadd..4d4a17a3aa5 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.258 2006/11/30 18:29:11 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.259 2006/12/08 19:50:53 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1538,54 +1538,6 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch) openLogFile = XLogFileInit(openLogId, openLogSeg, &use_existent, true); openLogOff = 0; - - /* update pg_control, unless someone else already did */ - LWLockAcquire(ControlFileLock, LW_EXCLUSIVE); - if (ControlFile->logId < openLogId || - (ControlFile->logId == openLogId && - ControlFile->logSeg < openLogSeg + 1)) - { - ControlFile->logId = openLogId; - ControlFile->logSeg = openLogSeg + 1; - ControlFile->time = time(NULL); - UpdateControlFile(); - - /* - * Signal bgwriter to start a checkpoint if it's been too long - * since the last one. (We look at local copy of RedoRecPtr - * which might be a little out of date, but should be close - * enough for this purpose.) - * - * A straight computation of segment number could overflow 32 - * bits. Rather than assuming we have working 64-bit - * arithmetic, we compare the highest-order bits separately, - * and force a checkpoint immediately when they change. - */ - if (IsUnderPostmaster) - { - uint32 old_segno, - new_segno; - uint32 old_highbits, - new_highbits; - - 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) - { -#ifdef WAL_DEBUG - if (XLOG_DEBUG) - elog(LOG, "time for a checkpoint, signaling bgwriter"); -#endif - RequestCheckpoint(false, true); - } - } - } - LWLockRelease(ControlFileLock); } /* Make sure we have the current logfile open */ @@ -1669,7 +1621,9 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch) * * This is also the right place to notify the Archiver that the * segment is ready to copy to archival storage, and to update the - * timer for archive_timeout. + * timer for archive_timeout, and to signal for a checkpoint if + * too many logfile segments have been used since the last + * checkpoint. */ if (finishing_seg || (xlog_switch && last_iteration)) { @@ -1680,6 +1634,41 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch) XLogArchiveNotifySeg(openLogId, openLogSeg); Write->lastSegSwitchTime = time(NULL); + + /* + * Signal bgwriter to start a checkpoint if it's been too long + * since the last one. (We look at local copy of RedoRecPtr + * which might be a little out of date, but should be close + * enough for this purpose.) + * + * A straight computation of segment number could overflow 32 + * bits. Rather than assuming we have working 64-bit + * arithmetic, we compare the highest-order bits separately, + * and force a checkpoint immediately when they change. + */ + if (IsUnderPostmaster) + { + uint32 old_segno, + new_segno; + uint32 old_highbits, + new_highbits; + + 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)) + { +#ifdef WAL_DEBUG + if (XLOG_DEBUG) + elog(LOG, "time for a checkpoint, signaling bgwriter"); +#endif + RequestCheckpoint(false, true); + } + } } } @@ -4199,8 +4188,6 @@ BootStrapXLOG(void) ControlFile->system_identifier = sysidentifier; ControlFile->state = DB_SHUTDOWNED; ControlFile->time = checkPoint.time; - ControlFile->logId = 0; - ControlFile->logSeg = 1; ControlFile->checkPoint = checkPoint.redo; ControlFile->checkPointCopy = checkPoint; /* some additional ControlFile fields are set in WriteControlFile() */ @@ -4659,8 +4646,7 @@ StartupXLOG(void) */ ReadControlFile(); - if (ControlFile->logSeg == 0 || - ControlFile->state < DB_SHUTDOWNED || + if (ControlFile->state < DB_SHUTDOWNED || ControlFile->state > DB_IN_PRODUCTION || !XRecOffIsValid(ControlFile->checkPoint.xrecoff)) ereport(FATAL, @@ -4672,7 +4658,7 @@ StartupXLOG(void) str_time(ControlFile->time)))); else if (ControlFile->state == DB_SHUTDOWNING) ereport(LOG, - (errmsg("database system shutdown was interrupted at %s", + (errmsg("database system shutdown was interrupted; last known up at %s", str_time(ControlFile->time)))); else if (ControlFile->state == DB_IN_CRASH_RECOVERY) ereport(LOG, @@ -4688,7 +4674,7 @@ StartupXLOG(void) " and you may need to choose an earlier recovery target."))); else if (ControlFile->state == DB_IN_PRODUCTION) ereport(LOG, - (errmsg("database system was interrupted at %s", + (errmsg("database system was interrupted; last known up at %s", str_time(ControlFile->time)))); /* This is just to allow attaching to startup process with a debugger */ @@ -5064,8 +5050,6 @@ StartupXLOG(void) openLogSeg = endLogSeg; openLogFile = XLogFileOpen(openLogId, openLogSeg); openLogOff = 0; - ControlFile->logId = openLogId; - ControlFile->logSeg = openLogSeg + 1; Insert = &XLogCtl->Insert; Insert->PrevRecord = LastRec; XLogCtl->xlblocks[0].xlogid = openLogId; |