diff options
author | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2012-06-24 18:51:37 +0300 |
---|---|---|
committer | Heikki Linnakangas <heikki.linnakangas@iki.fi> | 2012-06-24 19:19:45 +0300 |
commit | 0ab9d1c4b31622e9176472b4276f3e9831e3d6ba (patch) | |
tree | b8e9e5337338ba3010e00af50e1a33adb906a212 /src/backend/access/transam/xlog.c | |
parent | 061e7efb1b4c5b8a5d02122b7780531b8d5bf23d (diff) | |
download | postgresql-0ab9d1c4b31622e9176472b4276f3e9831e3d6ba.tar.gz postgresql-0ab9d1c4b31622e9176472b4276f3e9831e3d6ba.zip |
Replace XLogRecPtr struct with a 64-bit integer.
This simplifies code that needs to do arithmetic on XLogRecPtrs.
To avoid changing on-disk format of data pages, the LSN on data pages is
still stored in the old format. That should keep pg_upgrade happy. However,
we have XLogRecPtrs embedded in the control file, and in the structs that
are sent over the replication protocol, so this changes breaks compatibility
of pg_basebackup and server. I didn't do anything about this in this patch,
per discussion on -hackers, the right thing to do would to be to change the
replication protocol to be architecture-independent, so that you could use
a newer version of pg_receivexlog, for example, against an older server
version.
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r-- | src/backend/access/transam/xlog.c | 253 |
1 files changed, 115 insertions, 138 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index a144fbb1a2c..f0a89ac29a2 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -252,9 +252,9 @@ static TimeLineID curFileTLI; * or start a new one; so it can be used to tell if the current transaction has * created any XLOG records. */ -static XLogRecPtr ProcLastRecPtr = {0, 0}; +static XLogRecPtr ProcLastRecPtr = InvalidXLogRecPtr; -XLogRecPtr XactLastRecEnd = {0, 0}; +XLogRecPtr XactLastRecEnd = InvalidXLogRecPtr; /* * RedoRecPtr is this backend's local copy of the REDO record pointer @@ -278,7 +278,7 @@ static XLogRecPtr RedoRecPtr; * backwards to the REDO location after reading the checkpoint record, * because the REDO record can precede the checkpoint record. */ -static XLogRecPtr RedoStartLSN = {0, 0}; +static XLogRecPtr RedoStartLSN = InvalidXLogRecPtr; /*---------- * Shared-memory data structures for XLOG control @@ -493,13 +493,7 @@ static ControlFileData *ControlFile = NULL; /* Construct XLogRecPtr value for current insertion point */ #define INSERT_RECPTR(recptr,Insert,curridx) \ - do { \ - (recptr).xlogid = XLogCtl->xlblocks[curridx].xlogid; \ - (recptr).xrecoff = \ - XLogCtl->xlblocks[curridx].xrecoff - INSERT_FREESPACE(Insert); \ - if (XLogCtl->xlblocks[curridx].xrecoff == 0) \ - (recptr).xlogid = XLogCtl->xlblocks[curridx].xlogid - 1; \ - } while(0) + (recptr) = XLogCtl->xlblocks[curridx] - INSERT_FREESPACE(Insert) #define PrevBufIdx(idx) \ (((idx) == 0) ? XLogCtl->XLogCacheBlck : ((idx) - 1)) @@ -511,7 +505,7 @@ static ControlFileData *ControlFile = NULL; * Private, possibly out-of-date copy of shared LogwrtResult. * See discussion above. */ -static XLogwrtResult LogwrtResult = {{0, 0}, {0, 0}}; +static XLogwrtResult LogwrtResult = {0, 0}; /* * Codes indicating where we got a WAL file from during recovery, or where @@ -745,8 +739,7 @@ XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata) */ if (IsBootstrapProcessingMode() && rmid != RM_XLOG_ID) { - RecPtr.xlogid = 0; - RecPtr.xrecoff = SizeOfXLogLongPHD; /* start of 1st chkpt record */ + RecPtr = SizeOfXLogLongPHD; /* start of 1st chkpt record */ return RecPtr; } @@ -1011,13 +1004,12 @@ begin:; * everything is written and flushed through the end of the prior segment, * and return the prior segment's end address. */ - if (isLogSwitch && - (RecPtr.xrecoff % XLogSegSize) == SizeOfXLogLongPHD) + if (isLogSwitch && (RecPtr % XLogSegSize) == SizeOfXLogLongPHD) { /* We can release insert lock immediately */ LWLockRelease(WALInsertLock); - RecPtr.xrecoff -= SizeOfXLogLongPHD; + RecPtr -= SizeOfXLogLongPHD; LWLockAcquire(WALWriteLock, LW_EXCLUSIVE); LogwrtResult = XLogCtl->LogwrtResult; @@ -1051,7 +1043,7 @@ begin:; initStringInfo(&buf); appendStringInfo(&buf, "INSERT @ %X/%X: ", - RecPtr.xlogid, RecPtr.xrecoff); + (uint32) (RecPtr >> 32), (uint32) RecPtr); xlog_outrec(&buf, rechdr); if (rdata->data != NULL) { @@ -1152,12 +1144,7 @@ begin:; /* Compute end address of old segment */ OldSegEnd = XLogCtl->xlblocks[curridx]; - if (OldSegEnd.xrecoff == 0) - { - /* crossing a logid boundary */ - OldSegEnd.xlogid -= 1; - } - OldSegEnd.xrecoff -= XLOG_BLCKSZ; + OldSegEnd -= XLOG_BLCKSZ; /* Make it look like we've written and synced all of old segment */ LogwrtResult.Write = OldSegEnd; @@ -1523,8 +1510,7 @@ AdvanceXLInsertBuffer(bool new_segment) */ TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_START(); WriteRqst.Write = OldPageRqstPtr; - WriteRqst.Flush.xlogid = 0; - WriteRqst.Flush.xrecoff = 0; + WriteRqst.Flush = 0; XLogWrite(WriteRqst, false, false); LWLockRelease(WALWriteLock); TRACE_POSTGRESQL_WAL_BUFFER_WRITE_DIRTY_DONE(); @@ -1541,9 +1527,9 @@ AdvanceXLInsertBuffer(bool new_segment) if (new_segment) { /* force it to a segment start point */ - if (NewPageBeginPtr.xrecoff % XLogSegSize != 0) + if (NewPageBeginPtr % XLogSegSize != 0) XLByteAdvance(NewPageBeginPtr, - XLogSegSize - NewPageBeginPtr.xrecoff % XLogSegSize); + XLogSegSize - NewPageBeginPtr % XLogSegSize); } NewPageEndPtr = NewPageBeginPtr; @@ -1589,7 +1575,7 @@ AdvanceXLInsertBuffer(bool new_segment) /* * If first page of an XLOG segment file, make it a long header. */ - if ((NewPage->xlp_pageaddr.xrecoff % XLogSegSize) == 0) + if ((NewPage->xlp_pageaddr % XLogSegSize) == 0) { XLogLongPageHeader NewLongPage = (XLogLongPageHeader) NewPage; @@ -1693,9 +1679,9 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch) */ if (!XLByteLT(LogwrtResult.Write, XLogCtl->xlblocks[curridx])) elog(PANIC, "xlog write request %X/%X is past end of log %X/%X", - LogwrtResult.Write.xlogid, LogwrtResult.Write.xrecoff, - XLogCtl->xlblocks[curridx].xlogid, - XLogCtl->xlblocks[curridx].xrecoff); + (uint32) (LogwrtResult.Write >> 32), (uint32) LogwrtResult.Write, + (uint32) (XLogCtl->xlblocks[curridx] >> 32), + (uint32) XLogCtl->xlblocks[curridx]); /* Advance LogwrtResult.Write to end of current buffer page */ LogwrtResult.Write = XLogCtl->xlblocks[curridx]; @@ -1731,7 +1717,7 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch) { /* first of group */ startidx = curridx; - startoffset = (LogwrtResult.Write.xrecoff - XLOG_BLCKSZ) % XLogSegSize; + startoffset = (LogwrtResult.Write - XLOG_BLCKSZ) % XLogSegSize; } npages++; @@ -1923,7 +1909,7 @@ XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN) if (!sleeping) { /* back off to last completed page boundary */ - WriteRqstPtr.xrecoff -= WriteRqstPtr.xrecoff % XLOG_BLCKSZ; + WriteRqstPtr -= WriteRqstPtr % XLOG_BLCKSZ; /* if we have already flushed that far, we're done */ if (XLByteLE(WriteRqstPtr, LogwrtResult.Flush)) @@ -1965,7 +1951,7 @@ UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force) * i.e., we're doing crash recovery. We never modify the control file's * value in that case, so we can short-circuit future checks here too. */ - if (minRecoveryPoint.xlogid == 0 && minRecoveryPoint.xrecoff == 0) + if (minRecoveryPoint == 0) updateMinRecoveryPoint = false; else if (force || XLByteLT(minRecoveryPoint, lsn)) { @@ -1993,8 +1979,9 @@ UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force) if (!force && XLByteLT(newMinRecoveryPoint, lsn)) elog(WARNING, "xlog min recovery request %X/%X is past current point %X/%X", - lsn.xlogid, lsn.xrecoff, - newMinRecoveryPoint.xlogid, newMinRecoveryPoint.xrecoff); + (uint32) (lsn >> 32) , (uint32) lsn, + (uint32) (newMinRecoveryPoint >> 32), + (uint32) newMinRecoveryPoint); /* update control file */ if (XLByteLT(ControlFile->minRecoveryPoint, newMinRecoveryPoint)) @@ -2005,7 +1992,8 @@ UpdateMinRecoveryPoint(XLogRecPtr lsn, bool force) ereport(DEBUG2, (errmsg("updated min recovery point to %X/%X", - minRecoveryPoint.xlogid, minRecoveryPoint.xrecoff))); + (uint32) (minRecoveryPoint >> 32), + (uint32) minRecoveryPoint))); } } LWLockRelease(ControlFileLock); @@ -2043,9 +2031,9 @@ XLogFlush(XLogRecPtr record) #ifdef WAL_DEBUG if (XLOG_DEBUG) elog(LOG, "xlog flush request %X/%X; write %X/%X; flush %X/%X", - record.xlogid, record.xrecoff, - LogwrtResult.Write.xlogid, LogwrtResult.Write.xrecoff, - LogwrtResult.Flush.xlogid, LogwrtResult.Flush.xrecoff); + (uint32) (record >> 32), (uint32) record, + (uint32) (LogwrtResult.Write >> 32), (uint32) LogwrtResult.Write, + (uint32) (LogwrtResult.Flush >> 32), (uint32) LogwrtResult.Flush); #endif START_CRIT_SECTION(); @@ -2112,9 +2100,7 @@ XLogFlush(XLogRecPtr record) else { WriteRqstPtr = XLogCtl->xlblocks[Insert->curridx]; - if (WriteRqstPtr.xrecoff == 0) - WriteRqstPtr.xlogid--; - WriteRqstPtr.xrecoff -= freespace; + WriteRqstPtr -= freespace; } LWLockRelease(WALInsertLock); WriteRqst.Write = WriteRqstPtr; @@ -2158,8 +2144,8 @@ XLogFlush(XLogRecPtr record) if (XLByteLT(LogwrtResult.Flush, record)) elog(ERROR, "xlog flush request %X/%X is not satisfied --- flushed only to %X/%X", - record.xlogid, record.xrecoff, - LogwrtResult.Flush.xlogid, LogwrtResult.Flush.xrecoff); + (uint32) (record >> 32), (uint32) record, + (uint32) (LogwrtResult.Flush >> 32), (uint32) LogwrtResult.Flush); } /* @@ -2202,7 +2188,7 @@ XLogBackgroundFlush(void) } /* back off to last completed page boundary */ - WriteRqstPtr.xrecoff -= WriteRqstPtr.xrecoff % XLOG_BLCKSZ; + WriteRqstPtr -= WriteRqstPtr % XLOG_BLCKSZ; /* if we have already flushed that far, consider async commit records */ if (XLByteLE(WriteRqstPtr, LogwrtResult.Flush)) @@ -2236,9 +2222,9 @@ XLogBackgroundFlush(void) #ifdef WAL_DEBUG if (XLOG_DEBUG) elog(LOG, "xlog bg flush request %X/%X; write %X/%X; flush %X/%X", - WriteRqstPtr.xlogid, WriteRqstPtr.xrecoff, - LogwrtResult.Write.xlogid, LogwrtResult.Write.xrecoff, - LogwrtResult.Flush.xlogid, LogwrtResult.Flush.xrecoff); + (uint32) (WriteRqstPtr >> 32), (uint32) WriteRqstPtr, + (uint32) (LogwrtResult.Write >> 32), (uint32) LogwrtResult.Write, + (uint32) (LogwrtResult.Flush >> 32), (uint32) LogwrtResult.Flush); #endif START_CRIT_SECTION(); @@ -2305,7 +2291,7 @@ XLogNeedsFlush(XLogRecPtr record) * file's value in that case, so we can short-circuit future checks * here too. */ - if (minRecoveryPoint.xlogid == 0 && minRecoveryPoint.xrecoff == 0) + if (minRecoveryPoint == 0) updateMinRecoveryPoint = false; /* check again */ @@ -3319,8 +3305,7 @@ PreallocXlogFiles(XLogRecPtr endptr) bool use_existent; XLByteToPrevSeg(endptr, _logSegNo); - if ((endptr.xrecoff - 1) % XLogSegSize >= - (uint32) (0.75 * XLogSegSize)) + if ((endptr - 1) % XLogSegSize >= (uint32) (0.75 * XLogSegSize)) { _logSegNo++; use_existent = true; @@ -3704,7 +3689,7 @@ RecordIsValid(XLogRecord *record, XLogRecPtr recptr, int emode) { ereport(emode_for_corrupt_record(emode, recptr), (errmsg("incorrect hole size in record at %X/%X", - recptr.xlogid, recptr.xrecoff))); + (uint32) (recptr >> 32), (uint32) recptr))); return false; } blen = sizeof(BkpBlock) + BLCKSZ - bkpb.hole_length; @@ -3717,7 +3702,7 @@ RecordIsValid(XLogRecord *record, XLogRecPtr recptr, int emode) { ereport(emode_for_corrupt_record(emode, recptr), (errmsg("incorrect total length in record at %X/%X", - recptr.xlogid, recptr.xrecoff))); + (uint32) (recptr >> 32), (uint32) recptr))); return false; } @@ -3729,7 +3714,7 @@ RecordIsValid(XLogRecord *record, XLogRecPtr recptr, int emode) { ereport(emode_for_corrupt_record(emode, recptr), (errmsg("incorrect resource manager data checksum in record at %X/%X", - recptr.xlogid, recptr.xrecoff))); + (uint32) (recptr >> 32), (uint32) recptr))); return false; } @@ -3790,10 +3775,10 @@ ReadRecord(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt) * In this case, the passed-in record pointer should already be * pointing to a valid record starting position. */ - if (!XRecOffIsValid(RecPtr->xrecoff)) + if (!XRecOffIsValid(*RecPtr)) ereport(PANIC, (errmsg("invalid record offset at %X/%X", - RecPtr->xlogid, RecPtr->xrecoff))); + (uint32) (*RecPtr >> 32), (uint32) *RecPtr))); /* * Since we are going to a random position in WAL, forget any prior @@ -3814,7 +3799,7 @@ retry: return NULL; pageHeaderSize = XLogPageHeaderSize((XLogPageHeader) readBuf); - targetRecOff = RecPtr->xrecoff % XLOG_BLCKSZ; + targetRecOff = (*RecPtr) % XLOG_BLCKSZ; if (targetRecOff == 0) { /* @@ -3824,14 +3809,14 @@ retry: * XRecOffIsValid rejected the zero-page-offset case otherwise. */ Assert(RecPtr == &tmpRecPtr); - RecPtr->xrecoff += pageHeaderSize; + (*RecPtr) += pageHeaderSize; targetRecOff = pageHeaderSize; } else if (targetRecOff < pageHeaderSize) { ereport(emode_for_corrupt_record(emode, *RecPtr), (errmsg("invalid record offset at %X/%X", - RecPtr->xlogid, RecPtr->xrecoff))); + (uint32) ((*RecPtr) >> 32), (uint32) *RecPtr))); goto next_record_is_invalid; } if ((((XLogPageHeader) readBuf)->xlp_info & XLP_FIRST_IS_CONTRECORD) && @@ -3839,7 +3824,7 @@ retry: { ereport(emode_for_corrupt_record(emode, *RecPtr), (errmsg("contrecord is requested by %X/%X", - RecPtr->xlogid, RecPtr->xrecoff))); + (uint32) ((*RecPtr) >> 32), (uint32) *RecPtr))); goto next_record_is_invalid; } @@ -3849,7 +3834,7 @@ retry: * struct, so it must be on this page, but we cannot safely access any * other fields yet. */ - record = (XLogRecord *) (readBuf + RecPtr->xrecoff % XLOG_BLCKSZ); + record = (XLogRecord *) (readBuf + (*RecPtr) % XLOG_BLCKSZ); total_len = record->xl_tot_len; /* @@ -3874,7 +3859,7 @@ retry: /* We treat this as a "bogus data" condition */ ereport(emode_for_corrupt_record(emode, *RecPtr), (errmsg("record length %u at %X/%X too long", - total_len, RecPtr->xlogid, RecPtr->xrecoff))); + total_len, (uint32) ((*RecPtr) >> 32), (uint32) *RecPtr))); goto next_record_is_invalid; } readRecordBufSize = newSize; @@ -3893,7 +3878,7 @@ retry: else gotheader = false; - len = XLOG_BLCKSZ - RecPtr->xrecoff % XLOG_BLCKSZ; + len = XLOG_BLCKSZ - (*RecPtr) % XLOG_BLCKSZ; if (total_len > len) { /* Need to reassemble record */ @@ -3904,11 +3889,10 @@ retry: uint32 gotlen; /* Initialize pagelsn to the beginning of the page this record is on */ - pagelsn = *RecPtr; - pagelsn.xrecoff = (pagelsn.xrecoff / XLOG_BLCKSZ) * XLOG_BLCKSZ; + pagelsn = ((*RecPtr) / XLOG_BLCKSZ) * XLOG_BLCKSZ; /* Copy the first fragment of the record from the first page. */ - memcpy(readRecordBuf, readBuf + RecPtr->xrecoff % XLOG_BLCKSZ, len); + memcpy(readRecordBuf, readBuf + (*RecPtr) % XLOG_BLCKSZ, len); buffer = readRecordBuf + len; gotlen = len; @@ -3980,8 +3964,7 @@ retry: /* Record does not cross a page boundary */ if (!RecordIsValid(record, *RecPtr, emode)) goto next_record_is_invalid; - EndRecPtr.xlogid = RecPtr->xlogid; - EndRecPtr.xrecoff = RecPtr->xrecoff + MAXALIGN(total_len); + EndRecPtr = *RecPtr + MAXALIGN(total_len); ReadRecPtr = *RecPtr; memcpy(readRecordBuf, record, total_len); @@ -3993,8 +3976,8 @@ retry: if (record->xl_rmid == RM_XLOG_ID && record->xl_info == XLOG_SWITCH) { /* Pretend it extends to end of segment */ - EndRecPtr.xrecoff += XLogSegSize - 1; - EndRecPtr.xrecoff -= EndRecPtr.xrecoff % XLogSegSize; + EndRecPtr += XLogSegSize - 1; + EndRecPtr -= EndRecPtr % XLogSegSize; /* * Pretend that readBuf contains the last page of the segment. This is @@ -4105,7 +4088,7 @@ ValidXLogPageHeader(XLogPageHeader hdr, int emode) { ereport(emode_for_corrupt_record(emode, recaddr), (errmsg("unexpected pageaddr %X/%X in log segment %s, offset %u", - hdr->xlp_pageaddr.xlogid, hdr->xlp_pageaddr.xrecoff, + (uint32) (hdr->xlp_pageaddr >> 32), (uint32) hdr->xlp_pageaddr, XLogFileNameP(curFileTLI, readSegNo), readOff))); return false; @@ -4166,7 +4149,7 @@ ValidXLogRecordHeader(XLogRecPtr *RecPtr, XLogRecord *record, int emode, { ereport(emode_for_corrupt_record(emode, *RecPtr), (errmsg("invalid xlog switch record at %X/%X", - RecPtr->xlogid, RecPtr->xrecoff))); + (uint32) ((*RecPtr) >> 32), (uint32) *RecPtr))); return false; } } @@ -4174,7 +4157,7 @@ ValidXLogRecordHeader(XLogRecPtr *RecPtr, XLogRecord *record, int emode, { ereport(emode_for_corrupt_record(emode, *RecPtr), (errmsg("record with zero length at %X/%X", - RecPtr->xlogid, RecPtr->xrecoff))); + (uint32) ((*RecPtr) >> 32), (uint32) *RecPtr))); return false; } if (record->xl_tot_len < SizeOfXLogRecord + record->xl_len || @@ -4183,14 +4166,14 @@ ValidXLogRecordHeader(XLogRecPtr *RecPtr, XLogRecord *record, int emode, { ereport(emode_for_corrupt_record(emode, *RecPtr), (errmsg("invalid record length at %X/%X", - RecPtr->xlogid, RecPtr->xrecoff))); + (uint32) ((*RecPtr) >> 32), (uint32) *RecPtr))); return false; } if (record->xl_rmid > RM_MAX_ID) { ereport(emode_for_corrupt_record(emode, *RecPtr), (errmsg("invalid resource manager ID %u at %X/%X", - record->xl_rmid, RecPtr->xlogid, RecPtr->xrecoff))); + record->xl_rmid, (uint32) ((*RecPtr) >> 32), (uint32) *RecPtr))); return false; } if (randAccess) @@ -4203,8 +4186,8 @@ ValidXLogRecordHeader(XLogRecPtr *RecPtr, XLogRecord *record, int emode, { ereport(emode_for_corrupt_record(emode, *RecPtr), (errmsg("record with incorrect prev-link %X/%X at %X/%X", - record->xl_prev.xlogid, record->xl_prev.xrecoff, - RecPtr->xlogid, RecPtr->xrecoff))); + (uint32) (record->xl_prev >> 32), (uint32) record->xl_prev, + (uint32) ((*RecPtr) >> 32), (uint32) *RecPtr))); return false; } } @@ -4219,8 +4202,8 @@ ValidXLogRecordHeader(XLogRecPtr *RecPtr, XLogRecord *record, int emode, { ereport(emode_for_corrupt_record(emode, *RecPtr), (errmsg("record with incorrect prev-link %X/%X at %X/%X", - record->xl_prev.xlogid, record->xl_prev.xrecoff, - RecPtr->xlogid, RecPtr->xrecoff))); + (uint32) (record->xl_prev >> 32), (uint32) record->xl_prev, + (uint32) ((*RecPtr) >> 32), (uint32) *RecPtr))); return false; } } @@ -5193,8 +5176,7 @@ BootStrapXLOG(void) * segment with logid=0 logseg=1. The very first WAL segment, 0/0, is not * used, so that we can use 0/0 to mean "before any valid WAL segment". */ - checkPoint.redo.xlogid = 0; - checkPoint.redo.xrecoff = XLogSegSize + SizeOfXLogLongPHD; + checkPoint.redo = XLogSegSize + SizeOfXLogLongPHD; checkPoint.ThisTimeLineID = ThisTimeLineID; checkPoint.fullPageWrites = fullPageWrites; checkPoint.nextXidEpoch = 0; @@ -5217,8 +5199,7 @@ BootStrapXLOG(void) page->xlp_magic = XLOG_PAGE_MAGIC; page->xlp_info = XLP_LONG_HEADER; page->xlp_tli = ThisTimeLineID; - page->xlp_pageaddr.xlogid = 0; - page->xlp_pageaddr.xrecoff = XLogSegSize; + page->xlp_pageaddr = XLogSegSize; longpage = (XLogLongPageHeader) page; longpage->xlp_sysid = sysidentifier; longpage->xlp_seg_size = XLogSegSize; @@ -5226,8 +5207,7 @@ BootStrapXLOG(void) /* Insert the initial checkpoint record */ record = (XLogRecord *) ((char *) page + SizeOfXLogLongPHD); - record->xl_prev.xlogid = 0; - record->xl_prev.xrecoff = 0; + record->xl_prev = 0; record->xl_xid = InvalidTransactionId; record->xl_tot_len = SizeOfXLogRecord + sizeof(checkPoint); record->xl_len = sizeof(checkPoint); @@ -6021,7 +6001,7 @@ StartupXLOG(void) if (ControlFile->state < DB_SHUTDOWNED || ControlFile->state > DB_IN_PRODUCTION || - !XRecOffIsValid(ControlFile->checkPoint.xrecoff)) + !XRecOffIsValid(ControlFile->checkPoint)) ereport(FATAL, (errmsg("control file contains invalid data"))); @@ -6157,7 +6137,7 @@ StartupXLOG(void) wasShutdown = (record->xl_info == XLOG_CHECKPOINT_SHUTDOWN); ereport(DEBUG1, (errmsg("checkpoint record is at %X/%X", - checkPointLoc.xlogid, checkPointLoc.xrecoff))); + (uint32) (checkPointLoc >> 32), (uint32) checkPointLoc))); InRecovery = true; /* force recovery even if SHUTDOWNED */ /* @@ -6197,7 +6177,7 @@ StartupXLOG(void) { ereport(DEBUG1, (errmsg("checkpoint record is at %X/%X", - checkPointLoc.xlogid, checkPointLoc.xrecoff))); + (uint32) (checkPointLoc >> 32), (uint32) checkPointLoc))); } else if (StandbyMode) { @@ -6216,7 +6196,7 @@ StartupXLOG(void) { ereport(LOG, (errmsg("using previous checkpoint record at %X/%X", - checkPointLoc.xlogid, checkPointLoc.xrecoff))); + (uint32) (checkPointLoc >> 32), (uint32) checkPointLoc))); InRecovery = true; /* force recovery even if SHUTDOWNED */ } else @@ -6231,7 +6211,7 @@ StartupXLOG(void) ereport(DEBUG1, (errmsg("redo record is at %X/%X; shutdown %s", - checkPoint.redo.xlogid, checkPoint.redo.xrecoff, + (uint32) (checkPoint.redo >> 32), (uint32) checkPoint.redo, wasShutdown ? "TRUE" : "FALSE"))); ereport(DEBUG1, (errmsg("next transaction ID: %u/%u; next OID: %u", @@ -6542,7 +6522,7 @@ StartupXLOG(void) ereport(LOG, (errmsg("redo starts at %X/%X", - ReadRecPtr.xlogid, ReadRecPtr.xrecoff))); + (uint32) (ReadRecPtr >> 32), (uint32) ReadRecPtr))); /* * main redo apply loop @@ -6558,8 +6538,8 @@ StartupXLOG(void) initStringInfo(&buf); appendStringInfo(&buf, "REDO @ %X/%X; LSN %X/%X: ", - ReadRecPtr.xlogid, ReadRecPtr.xrecoff, - EndRecPtr.xlogid, EndRecPtr.xrecoff); + (uint32) (ReadRecPtr >> 32), (uint32) ReadRecPtr, + (uint32) (EndRecPtr >> 32), (uint32) EndRecPtr); xlog_outrec(&buf, record); appendStringInfo(&buf, " - "); RmgrTable[record->xl_rmid].rm_desc(&buf, @@ -6687,7 +6667,7 @@ StartupXLOG(void) ereport(LOG, (errmsg("redo done at %X/%X", - ReadRecPtr.xlogid, ReadRecPtr.xrecoff))); + (uint32) (ReadRecPtr >> 32), (uint32) ReadRecPtr))); xtime = GetLatestXTime(); if (xtime) ereport(LOG, @@ -6820,19 +6800,17 @@ StartupXLOG(void) openLogOff = 0; Insert = &XLogCtl->Insert; Insert->PrevRecord = LastRec; - XLogCtl->xlblocks[0].xlogid = (openLogSegNo * XLOG_SEG_SIZE) >> 32; - XLogCtl->xlblocks[0].xrecoff = - ((EndOfLog.xrecoff - 1) / XLOG_BLCKSZ + 1) * XLOG_BLCKSZ; + XLogCtl->xlblocks[0] = ((EndOfLog - 1) / XLOG_BLCKSZ + 1) * XLOG_BLCKSZ; /* * Tricky point here: readBuf contains the *last* block that the LastRec * record spans, not the one it starts in. The last block is indeed the * one we want to use. */ - Assert(readOff == (XLogCtl->xlblocks[0].xrecoff - XLOG_BLCKSZ) % XLogSegSize); + Assert(readOff == (XLogCtl->xlblocks[0] - XLOG_BLCKSZ) % XLogSegSize); memcpy((char *) Insert->currpage, readBuf, XLOG_BLCKSZ); Insert->currpos = (char *) Insert->currpage + - (EndOfLog.xrecoff + XLOG_BLCKSZ - XLogCtl->xlblocks[0].xrecoff); + (EndOfLog + XLOG_BLCKSZ - XLogCtl->xlblocks[0]); LogwrtResult.Write = LogwrtResult.Flush = EndOfLog; @@ -7053,7 +7031,7 @@ CheckRecoveryConsistency(void) reachedConsistency = true; ereport(LOG, (errmsg("consistent recovery state reached at %X/%X", - EndRecPtr.xlogid, EndRecPtr.xrecoff))); + (uint32) (EndRecPtr >> 32), (uint32) EndRecPtr))); } /* @@ -7212,7 +7190,7 @@ ReadCheckpointRecord(XLogRecPtr RecPtr, int whichChkpt) { XLogRecord *record; - if (!XRecOffIsValid(RecPtr.xrecoff)) + if (!XRecOffIsValid(RecPtr)) { switch (whichChkpt) { @@ -7738,13 +7716,9 @@ CreateCheckPoint(int flags) XLogRecPtr curInsert; INSERT_RECPTR(curInsert, Insert, Insert->curridx); - if (curInsert.xlogid == ControlFile->checkPoint.xlogid && - curInsert.xrecoff == ControlFile->checkPoint.xrecoff + + if (curInsert == ControlFile->checkPoint + MAXALIGN(SizeOfXLogRecord + sizeof(CheckPoint)) && - ControlFile->checkPoint.xlogid == - ControlFile->checkPointCopy.redo.xlogid && - ControlFile->checkPoint.xrecoff == - ControlFile->checkPointCopy.redo.xrecoff) + ControlFile->checkPoint == ControlFile->checkPointCopy.redo) { LWLockRelease(WALInsertLock); LWLockRelease(CheckpointLock); @@ -8074,8 +8048,8 @@ RecoveryRestartPoint(const CheckPoint *checkPoint) elog(trace_recovery(DEBUG2), "RM %d not safe to record restart point at %X/%X", rmid, - checkPoint->redo.xlogid, - checkPoint->redo.xrecoff); + (uint32) (checkPoint->redo >> 32), + (uint32) checkPoint->redo); return; } } @@ -8092,8 +8066,8 @@ RecoveryRestartPoint(const CheckPoint *checkPoint) elog(trace_recovery(DEBUG2), "could not record restart point at %X/%X because there " "are unresolved references to invalid pages", - checkPoint->redo.xlogid, - checkPoint->redo.xrecoff); + (uint32) (checkPoint->redo >> 32), + (uint32) checkPoint->redo); return; } @@ -8172,7 +8146,7 @@ CreateRestartPoint(int flags) { ereport(DEBUG2, (errmsg("skipping restartpoint, already performed at %X/%X", - lastCheckPoint.redo.xlogid, lastCheckPoint.redo.xrecoff))); + (uint32) (lastCheckPoint.redo >> 32), (uint32) lastCheckPoint.redo))); UpdateMinRecoveryPoint(InvalidXLogRecPtr, true); if (flags & CHECKPOINT_IS_SHUTDOWN) @@ -8282,7 +8256,7 @@ CreateRestartPoint(int flags) xtime = GetLatestXTime(); ereport((log_checkpoints ? LOG : DEBUG2), (errmsg("recovery restart point at %X/%X", - lastCheckPoint.redo.xlogid, lastCheckPoint.redo.xrecoff), + (uint32) (lastCheckPoint.redo >> 32), (uint32) lastCheckPoint.redo), xtime ? errdetail("last completed transaction was at log time %s", timestamptz_to_str(xtime)) : 0)); @@ -8408,7 +8382,7 @@ XLogRestorePoint(const char *rpName) ereport(LOG, (errmsg("restore point \"%s\" created at %X/%X", - rpName, RecPtr.xlogid, RecPtr.xrecoff))); + rpName, (uint32) (RecPtr >> 32), (uint32) RecPtr))); return RecPtr; } @@ -8757,8 +8731,7 @@ xlog_redo(XLogRecPtr lsn, XLogRecord *record) * decreasing max_* settings. */ minRecoveryPoint = ControlFile->minRecoveryPoint; - if ((minRecoveryPoint.xlogid != 0 || minRecoveryPoint.xrecoff != 0) - && XLByteLT(minRecoveryPoint, lsn)) + if (minRecoveryPoint != 0 && XLByteLT(minRecoveryPoint, lsn)) { ControlFile->minRecoveryPoint = lsn; } @@ -8808,7 +8781,7 @@ xlog_desc(StringInfo buf, uint8 xl_info, char *rec) appendStringInfo(buf, "checkpoint: redo %X/%X; " "tli %u; fpw %s; xid %u/%u; oid %u; multi %u; offset %u; " "oldest xid %u in DB %u; oldest running xid %u; %s", - checkpoint->redo.xlogid, checkpoint->redo.xrecoff, + (uint32) (checkpoint->redo >> 32), (uint32) checkpoint->redo, checkpoint->ThisTimeLineID, checkpoint->fullPageWrites ? "true" : "false", checkpoint->nextXidEpoch, checkpoint->nextXid, @@ -8848,7 +8821,7 @@ xlog_desc(StringInfo buf, uint8 xl_info, char *rec) memcpy(&startpoint, rec, sizeof(XLogRecPtr)); appendStringInfo(buf, "backup end: %X/%X", - startpoint.xlogid, startpoint.xrecoff); + (uint32) (startpoint >> 32), (uint32) startpoint); } else if (info == XLOG_PARAMETER_CHANGE) { @@ -8894,7 +8867,7 @@ xlog_outrec(StringInfo buf, XLogRecord *record) int i; appendStringInfo(buf, "prev %X/%X; xid %u", - record->xl_prev.xlogid, record->xl_prev.xrecoff, + (uint32) (record->xl_prev >> 32), (uint32) record->xl_prev, record->xl_xid); appendStringInfo(buf, "; len %u", @@ -9294,9 +9267,9 @@ do_pg_start_backup(const char *backupidstr, bool fast, char **labelfile) "%Y-%m-%d %H:%M:%S %Z", pg_localtime(&stamp_time, log_timezone)); appendStringInfo(&labelfbuf, "START WAL LOCATION: %X/%X (file %s)\n", - startpoint.xlogid, startpoint.xrecoff, xlogfilename); + (uint32) (startpoint >> 32), (uint32) startpoint, xlogfilename); appendStringInfo(&labelfbuf, "CHECKPOINT LOCATION: %X/%X\n", - checkpointloc.xlogid, checkpointloc.xrecoff); + (uint32) (checkpointloc >> 32), (uint32) checkpointloc); appendStringInfo(&labelfbuf, "BACKUP METHOD: %s\n", exclusive ? "pg_start_backup" : "streamed"); appendStringInfo(&labelfbuf, "BACKUP FROM: %s\n", @@ -9416,6 +9389,8 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive) bool reported_waiting = false; char *remaining; char *ptr; + uint32 hi, + lo; backup_started_in_recovery = RecoveryInProgress(); @@ -9520,11 +9495,12 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive) * but we are not expecting any variability in the file format). */ if (sscanf(labelfile, "START WAL LOCATION: %X/%X (file %24s)%c", - &startpoint.xlogid, &startpoint.xrecoff, startxlogfilename, + &hi, &lo, startxlogfilename, &ch) != 4 || ch != '\n') ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE))); + startpoint = ((uint64) hi) << 32 | lo; remaining = strchr(labelfile, '\n') + 1; /* %n is not portable enough */ /* @@ -9632,7 +9608,7 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive) */ XLByteToSeg(startpoint, _logSegNo); BackupHistoryFilePath(histfilepath, ThisTimeLineID, _logSegNo, - startpoint.xrecoff % XLogSegSize); + (uint32) (startpoint % XLogSegSize)); fp = AllocateFile(histfilepath, "w"); if (!fp) ereport(ERROR, @@ -9640,9 +9616,9 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive) errmsg("could not create file \"%s\": %m", histfilepath))); fprintf(fp, "START WAL LOCATION: %X/%X (file %s)\n", - startpoint.xlogid, startpoint.xrecoff, startxlogfilename); + (uint32) (startpoint >> 32), (uint32) startpoint, startxlogfilename); fprintf(fp, "STOP WAL LOCATION: %X/%X (file %s)\n", - stoppoint.xlogid, stoppoint.xrecoff, stopxlogfilename); + (uint32) (stoppoint >> 32), (uint32) stoppoint, stopxlogfilename); /* transfer remaining lines from label to history file */ fprintf(fp, "%s", remaining); fprintf(fp, "STOP TIME: %s\n", strfbuf); @@ -9685,7 +9661,7 @@ do_pg_stop_backup(char *labelfile, bool waitforarchive) XLByteToSeg(startpoint, _logSegNo); BackupHistoryFileName(histfilename, ThisTimeLineID, _logSegNo, - startpoint.xrecoff % XLogSegSize); + (uint32) (startpoint % XLogSegSize)); seconds_before_warning = 60; waits = 0; @@ -9861,6 +9837,8 @@ read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired, char ch; char backuptype[20]; char backupfrom[20]; + uint32 hi, + lo; *backupEndRequired = false; *backupFromStandby = false; @@ -9885,17 +9863,17 @@ read_backup_label(XLogRecPtr *checkPointLoc, bool *backupEndRequired, * format). */ if (fscanf(lfp, "START WAL LOCATION: %X/%X (file %08X%16s)%c", - &RedoStartLSN.xlogid, &RedoStartLSN.xrecoff, &tli, - startxlogfilename, &ch) != 5 || ch != '\n') + &hi, &lo, &tli, startxlogfilename, &ch) != 5 || ch != '\n') ereport(FATAL, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE))); + RedoStartLSN = ((uint64) hi) << 32 | lo; if (fscanf(lfp, "CHECKPOINT LOCATION: %X/%X%c", - &checkPointLoc->xlogid, &checkPointLoc->xrecoff, - &ch) != 3 || ch != '\n') + &hi, &lo, &ch) != 3 || ch != '\n') ereport(FATAL, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("invalid data in file \"%s\"", BACKUP_LABEL_FILE))); + *checkPointLoc = ((uint64) hi) << 32 | lo; /* * BACKUP METHOD and BACKUP FROM lines are new in 9.2. We can't restore @@ -10018,7 +9996,7 @@ static bool XLogPageRead(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt, bool randAccess) { - static XLogRecPtr receivedUpto = {0, 0}; + static XLogRecPtr receivedUpto = 0; bool switched_segment = false; uint32 targetPageOff; uint32 targetRecOff; @@ -10026,8 +10004,8 @@ XLogPageRead(XLogRecPtr *RecPtr, int emode, bool fetching_ckpt, static pg_time_t last_fail_time = 0; XLByteToSeg(*RecPtr, targetSegNo); - targetPageOff = ((RecPtr->xrecoff % XLogSegSize) / XLOG_BLCKSZ) * XLOG_BLCKSZ; - targetRecOff = RecPtr->xrecoff % XLOG_BLCKSZ; + targetPageOff = (((*RecPtr) % XLogSegSize) / XLOG_BLCKSZ) * XLOG_BLCKSZ; + targetRecOff = (*RecPtr) % XLOG_BLCKSZ; /* Fast exit if we have read the record in the current buffer already */ if (failedSources == 0 && targetSegNo == readSegNo && @@ -10308,13 +10286,12 @@ retry: */ if (readSource == XLOG_FROM_STREAM) { - if (RecPtr->xlogid != receivedUpto.xlogid || - (RecPtr->xrecoff / XLOG_BLCKSZ) != (receivedUpto.xrecoff / XLOG_BLCKSZ)) + if (((*RecPtr) / XLOG_BLCKSZ) != (receivedUpto / XLOG_BLCKSZ)) { readLen = XLOG_BLCKSZ; } else - readLen = receivedUpto.xrecoff % XLogSegSize - targetPageOff; + readLen = receivedUpto % XLogSegSize - targetPageOff; } else readLen = XLOG_BLCKSZ; @@ -10420,7 +10397,7 @@ triggered: static int emode_for_corrupt_record(int emode, XLogRecPtr RecPtr) { - static XLogRecPtr lastComplaint = {0, 0}; + static XLogRecPtr lastComplaint = 0; if (readSource == XLOG_FROM_PG_XLOG && emode == LOG) { |