diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2006-12-08 19:50:53 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2006-12-08 19:50:53 +0000 |
commit | 0cb91ccba93038c57a7dda6388c9f6bcd5cc52c0 (patch) | |
tree | 7b6d7b2ee9fe0e371717540d1d0354e8a54788b0 /src/backend/access/transam/xlog.c | |
parent | 98cacd1a0aa8486f21b18827c556b50936222d3e (diff) | |
download | postgresql-0cb91ccba93038c57a7dda6388c9f6bcd5cc52c0.tar.gz postgresql-0cb91ccba93038c57a7dda6388c9f6bcd5cc52c0.zip |
Remove the logId/logSeg fields from pg_control, because they are not needed
in normal operation, and we can avoid rewriting pg_control at every log
segment switch if we don't insist that these values be valid. Reducing
the number of pg_control updates is a good idea for both performance and
reliability. It does make pg_resetxlog's life a bit harder, but that seems
a good tradeoff; and anyway the change to pg_resetxlog amounts to automating
something people formerly needed to do by hand, namely look at the existing
pg_xlog files to make sure the new WAL start point was past them.
In passing, change the wording of xlog.c's "database system was interrupted"
messages: describe the pg_control timestamp as "last known up at" rather than
implying it is the exact time of service interruption. With this change the
timestamp will generally be the time of the last checkpoint, which could be
many minutes before the failure; and we've already seen indications that
people tend to misinterpret the old wording.
initdb forced due to change in pg_control layout. Simon Riggs and Tom Lane
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; |