diff --git a/contrib/pageinspect/rawpage.c b/contrib/pageinspect/rawpage.c index f51a4e31f5..e8a79401ad 100644 --- a/contrib/pageinspect/rawpage.c +++ b/contrib/pageinspect/rawpage.c @@ -206,7 +206,8 @@ page_header(PG_FUNCTION_ARGS) /* Extract information from the page header */ lsn = PageGetLSN(page); - snprintf(lsnchar, sizeof(lsnchar), "%X/%X", lsn.xlogid, lsn.xrecoff); + snprintf(lsnchar, sizeof(lsnchar), "%X/%X", + (uint32) (lsn >> 32), (uint32) lsn); values[0] = CStringGetTextDatum(lsnchar); values[1] = UInt16GetDatum(PageGetTLI(page)); diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c index 783590ea55..64ad2d749b 100644 --- a/src/backend/access/gist/gist.c +++ b/src/backend/access/gist/gist.c @@ -197,7 +197,7 @@ gistplacetopage(Relation rel, Size freespace, GISTSTATE *giststate, SplitedPageLayout *dist = NULL, *ptr; BlockNumber oldrlink = InvalidBlockNumber; - GistNSN oldnsn = {0, 0}; + GistNSN oldnsn = 0; SplitedPageLayout rootpg; BlockNumber blkno = BufferGetBlockNumber(buffer); bool is_rootsplit; @@ -488,7 +488,7 @@ gistdoinsert(Relation r, IndexTuple itup, Size freespace, GISTSTATE *giststate) /* Start from the root */ firststack.blkno = GIST_ROOT_BLKNO; - firststack.lsn.xrecoff = 0; + firststack.lsn = 0; firststack.parent = NULL; firststack.downlinkoffnum = InvalidOffsetNumber; state.stack = stack = &firststack; diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c index 8039b5d569..df1e2e396f 100644 --- a/src/backend/access/gist/gistutil.c +++ b/src/backend/access/gist/gistutil.c @@ -706,13 +706,7 @@ gistoptions(PG_FUNCTION_ARGS) XLogRecPtr GetXLogRecPtrForTemp(void) { - static XLogRecPtr counter = {0, 1}; - - counter.xrecoff++; - if (counter.xrecoff == 0) - { - counter.xlogid++; - counter.xrecoff++; - } + static XLogRecPtr counter = 1; + counter++; return counter; } diff --git a/src/backend/access/transam/transam.c b/src/backend/access/transam/transam.c index a7214cf34d..ff9dd4beea 100644 --- a/src/backend/access/transam/transam.c +++ b/src/backend/access/transam/transam.c @@ -24,9 +24,6 @@ #include "access/transam.h" #include "utils/snapmgr.h" -/* Handy constant for an invalid xlog recptr */ -const XLogRecPtr InvalidXLogRecPtr = {0, 0}; - /* * Single-item cache for results of TransactionLogFetch. It's worth having * such a cache because we frequently find ourselves repeatedly checking the diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c index b94fae3740..7fbf605761 100644 --- a/src/backend/access/transam/twophase.c +++ b/src/backend/access/transam/twophase.c @@ -333,8 +333,7 @@ MarkAsPreparing(TransactionId xid, const char *gid, gxact->prepared_at = prepared_at; /* initialize LSN to 0 (start of WAL) */ - gxact->prepare_lsn.xlogid = 0; - gxact->prepare_lsn.xrecoff = 0; + gxact->prepare_lsn = 0; gxact->owner = owner; gxact->locking_xid = xid; gxact->valid = false; diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c index 8e4a45568b..4ba13e18ab 100644 --- a/src/backend/access/transam/xact.c +++ b/src/backend/access/transam/xact.c @@ -951,7 +951,7 @@ RecordTransactionCommit(void) if (XLogStandbyInfoActive()) nmsgs = xactGetCommittedInvalidationMessages(&invalMessages, &RelcacheInitFileInval); - wrote_xlog = (XactLastRecEnd.xrecoff != 0); + wrote_xlog = (XactLastRecEnd != 0); /* * If we haven't been assigned an XID yet, we neither can, nor do we want @@ -1200,7 +1200,7 @@ RecordTransactionCommit(void) SyncRepWaitForLSN(XactLastRecEnd); /* Reset XactLastRecEnd until the next transaction writes something */ - XactLastRecEnd.xrecoff = 0; + XactLastRecEnd = 0; cleanup: /* Clean up local data */ @@ -1402,7 +1402,7 @@ RecordTransactionAbort(bool isSubXact) { /* Reset XactLastRecEnd until the next transaction writes something */ if (!isSubXact) - XactLastRecEnd.xrecoff = 0; + XactLastRecEnd = 0; return InvalidTransactionId; } @@ -1501,7 +1501,7 @@ RecordTransactionAbort(bool isSubXact) /* Reset XactLastRecEnd until the next transaction writes something */ if (!isSubXact) - XactLastRecEnd.xrecoff = 0; + XactLastRecEnd = 0; /* And clean up local data */ if (rels) @@ -2170,7 +2170,7 @@ PrepareTransaction(void) */ /* Reset XactLastRecEnd until the next transaction writes something */ - XactLastRecEnd.xrecoff = 0; + XactLastRecEnd = 0; /* * Let others know about no transaction in progress by me. This has to be diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index a144fbb1a2..f0a89ac29a 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) { diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c index bbb87d4d5c..6a446e9688 100644 --- a/src/backend/access/transam/xlogfuncs.c +++ b/src/backend/access/transam/xlogfuncs.c @@ -57,7 +57,7 @@ pg_start_backup(PG_FUNCTION_ARGS) startpoint = do_pg_start_backup(backupidstr, fast, NULL); snprintf(startxlogstr, sizeof(startxlogstr), "%X/%X", - startpoint.xlogid, startpoint.xrecoff); + (uint32) (startpoint >> 32), (uint32) startpoint); PG_RETURN_TEXT_P(cstring_to_text(startxlogstr)); } @@ -83,7 +83,7 @@ pg_stop_backup(PG_FUNCTION_ARGS) stoppoint = do_pg_stop_backup(NULL, true); snprintf(stopxlogstr, sizeof(stopxlogstr), "%X/%X", - stoppoint.xlogid, stoppoint.xrecoff); + (uint32) (stoppoint >> 32), (uint32) stoppoint); PG_RETURN_TEXT_P(cstring_to_text(stopxlogstr)); } @@ -113,7 +113,7 @@ pg_switch_xlog(PG_FUNCTION_ARGS) * As a convenience, return the WAL location of the switch record */ snprintf(location, sizeof(location), "%X/%X", - switchpoint.xlogid, switchpoint.xrecoff); + (uint32) (switchpoint >> 32), (uint32) switchpoint); PG_RETURN_TEXT_P(cstring_to_text(location)); } @@ -158,7 +158,7 @@ pg_create_restore_point(PG_FUNCTION_ARGS) * As a convenience, return the WAL location of the restore point record */ snprintf(location, sizeof(location), "%X/%X", - restorepoint.xlogid, restorepoint.xrecoff); + (uint32) (restorepoint >> 32), (uint32) restorepoint); PG_RETURN_TEXT_P(cstring_to_text(location)); } @@ -184,7 +184,7 @@ pg_current_xlog_location(PG_FUNCTION_ARGS) current_recptr = GetXLogWriteRecPtr(); snprintf(location, sizeof(location), "%X/%X", - current_recptr.xlogid, current_recptr.xrecoff); + (uint32) (current_recptr >> 32), (uint32) current_recptr); PG_RETURN_TEXT_P(cstring_to_text(location)); } @@ -208,7 +208,7 @@ pg_current_xlog_insert_location(PG_FUNCTION_ARGS) current_recptr = GetXLogInsertRecPtr(); snprintf(location, sizeof(location), "%X/%X", - current_recptr.xlogid, current_recptr.xrecoff); + (uint32) (current_recptr >> 32), (uint32) current_recptr); PG_RETURN_TEXT_P(cstring_to_text(location)); } @@ -226,11 +226,11 @@ pg_last_xlog_receive_location(PG_FUNCTION_ARGS) recptr = GetWalRcvWriteRecPtr(NULL); - if (recptr.xlogid == 0 && recptr.xrecoff == 0) + if (recptr == 0) PG_RETURN_NULL(); snprintf(location, sizeof(location), "%X/%X", - recptr.xlogid, recptr.xrecoff); + (uint32) (recptr >> 32), (uint32) recptr); PG_RETURN_TEXT_P(cstring_to_text(location)); } @@ -248,11 +248,11 @@ pg_last_xlog_replay_location(PG_FUNCTION_ARGS) recptr = GetXLogReplayRecPtr(NULL); - if (recptr.xlogid == 0 && recptr.xrecoff == 0) + if (recptr == 0) PG_RETURN_NULL(); snprintf(location, sizeof(location), "%X/%X", - recptr.xlogid, recptr.xrecoff); + (uint32) (recptr >> 32), (uint32) recptr); PG_RETURN_TEXT_P(cstring_to_text(location)); } @@ -269,8 +269,8 @@ pg_xlogfile_name_offset(PG_FUNCTION_ARGS) { text *location = PG_GETARG_TEXT_P(0); char *locationstr; - unsigned int uxlogid; - unsigned int uxrecoff; + uint32 hi, + lo; XLogSegNo xlogsegno; uint32 xrecoff; XLogRecPtr locationpoint; @@ -294,14 +294,12 @@ pg_xlogfile_name_offset(PG_FUNCTION_ARGS) validate_xlog_location(locationstr); - if (sscanf(locationstr, "%X/%X", &uxlogid, &uxrecoff) != 2) + if (sscanf(locationstr, "%X/%X", &hi, &lo) != 2) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("could not parse transaction log location \"%s\"", locationstr))); - - locationpoint.xlogid = uxlogid; - locationpoint.xrecoff = uxrecoff; + locationpoint = ((uint64) hi) << 32 | lo; /* * Construct a tuple descriptor for the result row. This must match this @@ -327,7 +325,7 @@ pg_xlogfile_name_offset(PG_FUNCTION_ARGS) /* * offset */ - xrecoff = locationpoint.xrecoff % XLogSegSize; + xrecoff = locationpoint % XLogSegSize; values[1] = UInt32GetDatum(xrecoff); isnull[1] = false; @@ -351,8 +349,8 @@ pg_xlogfile_name(PG_FUNCTION_ARGS) { text *location = PG_GETARG_TEXT_P(0); char *locationstr; - unsigned int uxlogid; - unsigned int uxrecoff; + uint32 hi, + lo; XLogSegNo xlogsegno; XLogRecPtr locationpoint; char xlogfilename[MAXFNAMELEN]; @@ -367,14 +365,12 @@ pg_xlogfile_name(PG_FUNCTION_ARGS) validate_xlog_location(locationstr); - if (sscanf(locationstr, "%X/%X", &uxlogid, &uxrecoff) != 2) + if (sscanf(locationstr, "%X/%X", &hi, &lo) != 2) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("could not parse transaction log location \"%s\"", locationstr))); - - locationpoint.xlogid = uxlogid; - locationpoint.xrecoff = uxrecoff; + locationpoint = ((uint64) hi) << 32 | lo; XLByteToPrevSeg(locationpoint, xlogsegno); XLogFileName(xlogfilename, ThisTimeLineID, xlogsegno); @@ -514,6 +510,8 @@ pg_xlog_location_diff(PG_FUNCTION_ARGS) Numeric result; uint64 bytes1, bytes2; + uint32 hi, + lo; /* * Read and parse input @@ -524,17 +522,20 @@ pg_xlog_location_diff(PG_FUNCTION_ARGS) validate_xlog_location(str1); validate_xlog_location(str2); - if (sscanf(str1, "%X/%X", &loc1.xlogid, &loc1.xrecoff) != 2) + if (sscanf(str1, "%X/%X", &hi, &lo) != 2) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("could not parse transaction log location \"%s\"", str1))); - if (sscanf(str2, "%X/%X", &loc2.xlogid, &loc2.xrecoff) != 2) + loc1 = ((uint64) hi) << 32 | lo; + + if (sscanf(str2, "%X/%X", &hi, &lo) != 2) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("could not parse transaction log location \"%s\"", str2))); + loc2 = ((uint64) hi) << 32 | lo; - bytes1 = (((uint64)loc1.xlogid) << 32L) + loc1.xrecoff; - bytes2 = (((uint64)loc2.xlogid) << 32L) + loc2.xrecoff; + bytes1 = (uint64) loc1; + bytes2 = (uint64) loc2; /* * result = bytes1 - bytes2. diff --git a/src/backend/postmaster/checkpointer.c b/src/backend/postmaster/checkpointer.c index 7e5db863da..417e3bb0d1 100644 --- a/src/backend/postmaster/checkpointer.c +++ b/src/backend/postmaster/checkpointer.c @@ -631,7 +631,7 @@ CheckArchiveTimeout(void) * If the returned pointer points exactly to a segment boundary, * assume nothing happened. */ - if ((switchpoint.xrecoff % XLogSegSize) != 0) + if ((switchpoint % XLogSegSize) != 0) ereport(DEBUG1, (errmsg("transaction log switch forced (archive_timeout=%d)", XLogArchiveTimeout))); @@ -778,10 +778,7 @@ IsCheckpointOnSchedule(double progress) if (!RecoveryInProgress()) { recptr = GetInsertRecPtr(); - elapsed_xlogs = - (((double) ((uint64) (recptr.xlogid - ckpt_start_recptr.xlogid) << 32L)) + - ((double) recptr.xrecoff - (double) ckpt_start_recptr.xrecoff) / XLogSegSize) / - CheckPointSegments; + elapsed_xlogs = (((double) (recptr - ckpt_start_recptr)) / XLogSegSize) / CheckPointSegments; if (progress < elapsed_xlogs) { diff --git a/src/backend/replication/basebackup.c b/src/backend/replication/basebackup.c index 14c42b46c2..4aaa9e3d08 100644 --- a/src/backend/replication/basebackup.c +++ b/src/backend/replication/basebackup.c @@ -497,7 +497,7 @@ SendXlogRecPtrResult(XLogRecPtr ptr) StringInfoData buf; char str[MAXFNAMELEN]; - snprintf(str, sizeof(str), "%X/%X", ptr.xlogid, ptr.xrecoff); + snprintf(str, sizeof(str), "%X/%X", (uint32) (ptr >> 32), (uint32) ptr); pq_beginmessage(&buf, 'T'); /* RowDescription */ pq_sendint(&buf, 1, 2); /* 1 field */ diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c index 979b66b300..bfaebeae84 100644 --- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c +++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c @@ -156,7 +156,7 @@ libpqrcv_connect(char *conninfo, XLogRecPtr startpoint) /* Start streaming from the point requested by startup process */ snprintf(cmd, sizeof(cmd), "START_REPLICATION %X/%X", - startpoint.xlogid, startpoint.xrecoff); + (uint32) (startpoint >> 32), (uint32) startpoint); res = libpqrcv_PQexec(cmd); if (PQresultStatus(res) != PGRES_COPY_BOTH) { diff --git a/src/backend/replication/repl_scanner.l b/src/backend/replication/repl_scanner.l index 9d4edcfc7a..51f381da00 100644 --- a/src/backend/replication/repl_scanner.l +++ b/src/backend/replication/repl_scanner.l @@ -72,8 +72,11 @@ START_REPLICATION { return K_START_REPLICATION; } " " ; {hexdigit}+\/{hexdigit}+ { - if (sscanf(yytext, "%X/%X", &yylval.recptr.xlogid, &yylval.recptr.xrecoff) != 2) + uint32 hi, + lo; + if (sscanf(yytext, "%X/%X", &hi, &lo) != 2) yyerror("invalid streaming start location"); + yylval.recptr = ((uint64) hi) << 32 | lo; return RECPTR; } diff --git a/src/backend/replication/syncrep.c b/src/backend/replication/syncrep.c index a3319642c6..0bb4145cb0 100644 --- a/src/backend/replication/syncrep.c +++ b/src/backend/replication/syncrep.c @@ -145,7 +145,7 @@ SyncRepWaitForLSN(XLogRecPtr XactCommitLSN) new_status = (char *) palloc(len + 32 + 1); memcpy(new_status, old_status, len); sprintf(new_status + len, " waiting for %X/%X", - XactCommitLSN.xlogid, XactCommitLSN.xrecoff); + (uint32) (XactCommitLSN >> 32), (uint32) XactCommitLSN); set_ps_display(new_status, false); new_status[len] = '\0'; /* truncate off " waiting ..." */ } @@ -255,8 +255,7 @@ SyncRepWaitForLSN(XLogRecPtr XactCommitLSN) */ Assert(SHMQueueIsDetached(&(MyProc->syncRepLinks))); MyProc->syncRepState = SYNC_REP_NOT_WAITING; - MyProc->waitLSN.xlogid = 0; - MyProc->waitLSN.xrecoff = 0; + MyProc->waitLSN = 0; if (new_status) { @@ -440,12 +439,8 @@ SyncRepReleaseWaiters(void) LWLockRelease(SyncRepLock); elog(DEBUG3, "released %d procs up to write %X/%X, %d procs up to flush %X/%X", - numwrite, - MyWalSnd->write.xlogid, - MyWalSnd->write.xrecoff, - numflush, - MyWalSnd->flush.xlogid, - MyWalSnd->flush.xrecoff); + numwrite, (uint32) (MyWalSnd->write >> 32), (uint32) MyWalSnd->write, + numflush, (uint32) (MyWalSnd->flush >> 32), (uint32) MyWalSnd->flush); /* * If we are managing the highest priority standby, though we weren't @@ -630,8 +625,7 @@ SyncRepQueueIsOrderedByLSN(int mode) Assert(mode >= 0 && mode < NUM_SYNC_REP_WAIT_MODE); - lastLSN.xlogid = 0; - lastLSN.xrecoff = 0; + lastLSN = 0; proc = (PGPROC *) SHMQueueNext(&(WalSndCtl->SyncRepQueue[mode]), &(WalSndCtl->SyncRepQueue[mode]), diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index b3ba7089df..d0e92060f1 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -516,7 +516,7 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr) } /* Calculate the start offset of the received logs */ - startoff = recptr.xrecoff % XLogSegSize; + startoff = recptr % XLogSegSize; if (startoff + nbytes > XLogSegSize) segbytes = XLogSegSize - startoff; @@ -601,8 +601,8 @@ XLogWalRcvFlush(bool dying) char activitymsg[50]; snprintf(activitymsg, sizeof(activitymsg), "streaming %X/%X", - LogstreamResult.Write.xlogid, - LogstreamResult.Write.xrecoff); + (uint32) (LogstreamResult.Write >> 32), + (uint32) LogstreamResult.Write); set_ps_display(activitymsg, false); } @@ -657,9 +657,9 @@ XLogWalRcvSendReply(void) reply_message.sendTime = now; elog(DEBUG2, "sending write %X/%X flush %X/%X apply %X/%X", - reply_message.write.xlogid, reply_message.write.xrecoff, - reply_message.flush.xlogid, reply_message.flush.xrecoff, - reply_message.apply.xlogid, reply_message.apply.xrecoff); + (uint32) (reply_message.write >> 32), (uint32) reply_message.write, + (uint32) (reply_message.flush >> 32), (uint32) reply_message.flush, + (uint32) (reply_message.apply >> 32), (uint32) reply_message.apply); /* Prepend with the message type and send it. */ buf[0] = 'r'; diff --git a/src/backend/replication/walreceiverfuncs.c b/src/backend/replication/walreceiverfuncs.c index 876196f9da..b31e964fec 100644 --- a/src/backend/replication/walreceiverfuncs.c +++ b/src/backend/replication/walreceiverfuncs.c @@ -185,8 +185,8 @@ RequestXLogStreaming(XLogRecPtr recptr, const char *conninfo) * being created by XLOG streaming, which might cause trouble later on if * the segment is e.g archived. */ - if (recptr.xrecoff % XLogSegSize != 0) - recptr.xrecoff -= recptr.xrecoff % XLogSegSize; + if (recptr % XLogSegSize != 0) + recptr -= recptr % XLogSegSize; SpinLockAcquire(&walrcv->mutex); @@ -204,8 +204,7 @@ RequestXLogStreaming(XLogRecPtr recptr, const char *conninfo) * If this is the first startup of walreceiver, we initialize receivedUpto * and latestChunkStart to receiveStart. */ - if (walrcv->receiveStart.xlogid == 0 && - walrcv->receiveStart.xrecoff == 0) + if (walrcv->receiveStart == 0) { walrcv->receivedUpto = recptr; walrcv->latestChunkStart = recptr; diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c index 2c04df08ed..0541c24998 100644 --- a/src/backend/replication/walsender.c +++ b/src/backend/replication/walsender.c @@ -94,7 +94,7 @@ static uint32 sendOff = 0; * How far have we sent WAL already? This is also advertised in * MyWalSnd->sentPtr. (Actually, this is the next WAL location to send.) */ -static XLogRecPtr sentPtr = {0, 0}; +static XLogRecPtr sentPtr = 0; /* * Buffer for processing reply messages. @@ -300,8 +300,7 @@ IdentifySystem(void) logptr = am_cascading_walsender ? GetStandbyFlushRecPtr() : GetInsertRecPtr(); - snprintf(xpos, sizeof(xpos), "%X/%X", - logptr.xlogid, logptr.xrecoff); + snprintf(xpos, sizeof(xpos), "%X/%X", (uint32) (logptr >> 32), (uint32) logptr); /* Send a RowDescription message */ pq_beginmessage(&buf, 'T'); @@ -613,9 +612,9 @@ ProcessStandbyReplyMessage(void) pq_copymsgbytes(&reply_message, (char *) &reply, sizeof(StandbyReplyMessage)); elog(DEBUG2, "write %X/%X flush %X/%X apply %X/%X", - reply.write.xlogid, reply.write.xrecoff, - reply.flush.xlogid, reply.flush.xrecoff, - reply.apply.xlogid, reply.apply.xrecoff); + (uint32) (reply.write << 32), (uint32) reply.write, + (uint32) (reply.flush << 32), (uint32) reply.flush, + (uint32) (reply.apply << 32), (uint32) reply.apply); /* * Update shared state for this WalSender process based on reply data from @@ -990,7 +989,7 @@ retry: int segbytes; int readbytes; - startoff = recptr.xrecoff % XLogSegSize; + startoff = recptr % XLogSegSize; if (sendFile < 0 || !XLByteInSeg(recptr, sendSegNo)) { @@ -1156,12 +1155,6 @@ XLogSend(char *msgbuf, bool *caughtup) startptr = sentPtr; endptr = startptr; XLByteAdvance(endptr, MAX_SEND_SIZE); - if (endptr.xlogid != startptr.xlogid) - { - /* Don't cross a logfile boundary within one message */ - Assert(endptr.xlogid == startptr.xlogid + 1); - endptr.xrecoff = 0; - } /* if we went beyond SendRqstPtr, back off */ if (XLByteLE(SendRqstPtr, endptr)) @@ -1172,14 +1165,11 @@ XLogSend(char *msgbuf, bool *caughtup) else { /* round down to page boundary. */ - endptr.xrecoff -= (endptr.xrecoff % XLOG_BLCKSZ); + endptr -= (endptr % XLOG_BLCKSZ); *caughtup = false; } - if (endptr.xrecoff == 0) - nbytes = 0x100000000L - (uint64) startptr.xrecoff; - else - nbytes = endptr.xrecoff - startptr.xrecoff; + nbytes = endptr - startptr; Assert(nbytes <= MAX_SEND_SIZE); /* @@ -1223,7 +1213,7 @@ XLogSend(char *msgbuf, bool *caughtup) char activitymsg[50]; snprintf(activitymsg, sizeof(activitymsg), "streaming %X/%X", - sentPtr.xlogid, sentPtr.xrecoff); + (uint32) (sentPtr >> 32), (uint32) sentPtr); set_ps_display(activitymsg, false); } @@ -1565,25 +1555,25 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS) values[1] = CStringGetTextDatum(WalSndGetStateString(state)); snprintf(location, sizeof(location), "%X/%X", - sentPtr.xlogid, sentPtr.xrecoff); + (uint32) (sentPtr >> 32), (uint32) sentPtr); values[2] = CStringGetTextDatum(location); - if (write.xlogid == 0 && write.xrecoff == 0) + if (write == 0) nulls[3] = true; snprintf(location, sizeof(location), "%X/%X", - write.xlogid, write.xrecoff); + (uint32) (write >> 32), (uint32) write); values[3] = CStringGetTextDatum(location); - if (flush.xlogid == 0 && flush.xrecoff == 0) + if (flush == 0) nulls[4] = true; snprintf(location, sizeof(location), "%X/%X", - flush.xlogid, flush.xrecoff); + (uint32) (flush >> 32), (uint32) flush); values[4] = CStringGetTextDatum(location); - if (apply.xlogid == 0 && apply.xrecoff == 0) + if (apply == 0) nulls[5] = true; snprintf(location, sizeof(location), "%X/%X", - apply.xlogid, apply.xrecoff); + (uint32) (apply >> 32), (uint32) apply); values[5] = CStringGetTextDatum(location); values[6] = Int32GetDatum(sync_priority[i]); diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c index 8863a5c9a7..995b68aae5 100644 --- a/src/backend/storage/ipc/standby.c +++ b/src/backend/storage/ipc/standby.c @@ -936,7 +936,7 @@ LogCurrentRunningXacts(RunningTransactions CurrRunningXacts) elog(trace_recovery(DEBUG2), "snapshot of %u running transactions overflowed (lsn %X/%X oldest xid %u latest complete %u next xid %u)", CurrRunningXacts->xcnt, - recptr.xlogid, recptr.xrecoff, + (uint32) (recptr >> 32), (uint32) recptr, CurrRunningXacts->oldestRunningXid, CurrRunningXacts->latestCompletedXid, CurrRunningXacts->nextXid); @@ -944,7 +944,7 @@ LogCurrentRunningXacts(RunningTransactions CurrRunningXacts) elog(trace_recovery(DEBUG2), "snapshot of %u running transaction ids (lsn %X/%X oldest xid %u latest complete %u next xid %u)", CurrRunningXacts->xcnt, - recptr.xlogid, recptr.xrecoff, + (uint32) (recptr >> 32), (uint32) recptr, CurrRunningXacts->oldestRunningXid, CurrRunningXacts->latestCompletedXid, CurrRunningXacts->nextXid); diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c index 327f43bb35..21598d3c18 100644 --- a/src/backend/storage/lmgr/proc.c +++ b/src/backend/storage/lmgr/proc.c @@ -376,8 +376,7 @@ InitProcess(void) MyProc->recoveryConflictPending = false; /* Initialize fields for sync rep */ - MyProc->waitLSN.xlogid = 0; - MyProc->waitLSN.xrecoff = 0; + MyProc->waitLSN = 0; MyProc->syncRepState = SYNC_REP_NOT_WAITING; SHMQueueElemInit(&(MyProc->syncRepLinks)); diff --git a/src/bin/pg_basebackup/pg_basebackup.c b/src/bin/pg_basebackup/pg_basebackup.c index bc67a3cb4d..a66769871e 100644 --- a/src/bin/pg_basebackup/pg_basebackup.c +++ b/src/bin/pg_basebackup/pg_basebackup.c @@ -162,6 +162,8 @@ reached_end_position(XLogRecPtr segendpos, uint32 timeline, bool segment_finishe if (r == 1) { char xlogend[64]; + uint32 hi, + lo; MemSet(xlogend, 0, sizeof(xlogend)); r = read(bgpipe[0], xlogend, sizeof(xlogend)); @@ -172,12 +174,13 @@ reached_end_position(XLogRecPtr segendpos, uint32 timeline, bool segment_finishe exit(1); } - if (sscanf(xlogend, "%X/%X", &xlogendptr.xlogid, &xlogendptr.xrecoff) != 2) + if (sscanf(xlogend, "%X/%X", &hi, &lo) != 2) { fprintf(stderr, _("%s: could not parse xlog end position \"%s\"\n"), progname, xlogend); exit(1); } + xlogendptr = ((uint64) hi) << 32 | lo; has_xlogendptr = 1; /* @@ -207,9 +210,7 @@ reached_end_position(XLogRecPtr segendpos, uint32 timeline, bool segment_finishe * At this point we have an end pointer, so compare it to the current * position to figure out if it's time to stop. */ - if (segendpos.xlogid > xlogendptr.xlogid || - (segendpos.xlogid == xlogendptr.xlogid && - segendpos.xrecoff >= xlogendptr.xrecoff)) + if (segendpos >= xlogendptr) return true; /* @@ -255,20 +256,23 @@ static void StartLogStreamer(char *startpos, uint32 timeline, char *sysidentifier) { logstreamer_param *param; + uint32 hi, + lo; param = xmalloc0(sizeof(logstreamer_param)); param->timeline = timeline; param->sysidentifier = sysidentifier; /* Convert the starting position */ - if (sscanf(startpos, "%X/%X", ¶m->startptr.xlogid, ¶m->startptr.xrecoff) != 2) + if (sscanf(startpos, "%X/%X", &hi, &lo) != 2) { fprintf(stderr, _("%s: invalid format of xlog location: %s\n"), progname, startpos); disconnect_and_exit(1); } + param->startptr = ((uint64) hi) << 32 | lo; /* Round off to even segment position */ - param->startptr.xrecoff -= param->startptr.xrecoff % XLOG_SEG_SIZE; + param->startptr -= param->startptr % XLOG_SEG_SIZE; #ifndef WIN32 /* Create our background pipe */ diff --git a/src/bin/pg_basebackup/pg_receivexlog.c b/src/bin/pg_basebackup/pg_receivexlog.c index 4b109f4b96..dbc6ecf431 100644 --- a/src/bin/pg_basebackup/pg_receivexlog.c +++ b/src/bin/pg_basebackup/pg_receivexlog.c @@ -77,7 +77,9 @@ stop_streaming(XLogRecPtr segendpos, uint32 timeline, bool segment_finished) { if (verbose && segment_finished) fprintf(stderr, _("%s: finished segment at %X/%X (timeline %u)\n"), - progname, segendpos.xlogid, segendpos.xrecoff, timeline); + progname, + (uint32) (segendpos >> 32), (uint32) segendpos, + timeline); if (time_to_abort) { @@ -212,6 +214,8 @@ StreamLog(void) PGresult *res; uint32 timeline; XLogRecPtr startpos; + uint32 hi, + lo; /* * Connect in replication mode to the server @@ -239,12 +243,13 @@ StreamLog(void) disconnect_and_exit(1); } timeline = atoi(PQgetvalue(res, 0, 1)); - if (sscanf(PQgetvalue(res, 0, 2), "%X/%X", &startpos.xlogid, &startpos.xrecoff) != 2) + if (sscanf(PQgetvalue(res, 0, 2), "%X/%X", &hi, &lo) != 2) { fprintf(stderr, _("%s: could not parse log start position from value \"%s\"\n"), progname, PQgetvalue(res, 0, 2)); disconnect_and_exit(1); } + startpos = ((uint64) hi) << 32 | lo; PQclear(res); /* @@ -255,14 +260,16 @@ StreamLog(void) /* * Always start streaming at the beginning of a segment */ - startpos.xrecoff -= startpos.xrecoff % XLOG_SEG_SIZE; + startpos -= startpos % XLOG_SEG_SIZE; /* * Start the replication */ if (verbose) fprintf(stderr, _("%s: starting log streaming at %X/%X (timeline %u)\n"), - progname, startpos.xlogid, startpos.xrecoff, timeline); + progname, + (uint32) (startpos >> 32), (uint32) startpos, + timeline); ReceiveXlogStream(conn, startpos, timeline, NULL, basedir, stop_streaming, diff --git a/src/bin/pg_basebackup/receivelog.c b/src/bin/pg_basebackup/receivelog.c index 8c6755caa9..064315f8db 100644 --- a/src/bin/pg_basebackup/receivelog.c +++ b/src/bin/pg_basebackup/receivelog.c @@ -38,8 +38,6 @@ #define STREAMING_HEADER_SIZE (1+sizeof(WalDataMessageHeader)) #define STREAMING_KEEPALIVE_SIZE (1+sizeof(PrimaryKeepaliveMessage)) -const XLogRecPtr InvalidXLogRecPtr = {0, 0}; - /* * Open a new WAL file in the specified directory. Store the name * (not including the full directory) in namebuf. Assumes there is @@ -310,7 +308,8 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi } /* Initiate the replication stream at specified location */ - snprintf(query, sizeof(query), "START_REPLICATION %X/%X", startpos.xlogid, startpos.xrecoff); + snprintf(query, sizeof(query), "START_REPLICATION %X/%X", + (uint32) (startpos >> 32), (uint32) startpos); res = PQexec(conn, query); if (PQresultStatus(res) != PGRES_COPY_BOTH) { @@ -471,7 +470,7 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi /* Extract WAL location for this block */ memcpy(&blockpos, copybuf + 1, 8); - xlogoff = blockpos.xrecoff % XLOG_SEG_SIZE; + xlogoff = blockpos % XLOG_SEG_SIZE; /* * Verify that the initial location in the stream matches where we @@ -543,7 +542,7 @@ ReceiveXlogStream(PGconn *conn, XLogRecPtr startpos, uint32 timeline, char *sysi xlogoff += bytes_to_write; /* Did we reach the end of a WAL segment? */ - if (blockpos.xrecoff % XLOG_SEG_SIZE == 0) + if (blockpos % XLOG_SEG_SIZE == 0) { if (!close_walfile(walfile, basedir, current_walfile_name, false)) /* Error message written in close_walfile() */ diff --git a/src/bin/pg_controldata/pg_controldata.c b/src/bin/pg_controldata/pg_controldata.c index 38c263c08b..298f836504 100644 --- a/src/bin/pg_controldata/pg_controldata.c +++ b/src/bin/pg_controldata/pg_controldata.c @@ -193,14 +193,14 @@ main(int argc, char *argv[]) printf(_("pg_control last modified: %s\n"), pgctime_str); printf(_("Latest checkpoint location: %X/%X\n"), - ControlFile.checkPoint.xlogid, - ControlFile.checkPoint.xrecoff); + (uint32) (ControlFile.checkPoint >> 32), + (uint32) ControlFile.checkPoint); printf(_("Prior checkpoint location: %X/%X\n"), - ControlFile.prevCheckPoint.xlogid, - ControlFile.prevCheckPoint.xrecoff); + (uint32) (ControlFile.prevCheckPoint >> 32), + (uint32) ControlFile.prevCheckPoint); printf(_("Latest checkpoint's REDO location: %X/%X\n"), - ControlFile.checkPointCopy.redo.xlogid, - ControlFile.checkPointCopy.redo.xrecoff); + (uint32) (ControlFile.checkPointCopy.redo >> 32), + (uint32) ControlFile.checkPointCopy.redo); printf(_("Latest checkpoint's TimeLineID: %u\n"), ControlFile.checkPointCopy.ThisTimeLineID); printf(_("Latest checkpoint's full_page_writes: %s\n"), @@ -223,14 +223,14 @@ main(int argc, char *argv[]) printf(_("Time of latest checkpoint: %s\n"), ckpttime_str); printf(_("Minimum recovery ending location: %X/%X\n"), - ControlFile.minRecoveryPoint.xlogid, - ControlFile.minRecoveryPoint.xrecoff); + (uint32) (ControlFile.minRecoveryPoint >> 32), + (uint32) ControlFile.minRecoveryPoint); printf(_("Backup start location: %X/%X\n"), - ControlFile.backupStartPoint.xlogid, - ControlFile.backupStartPoint.xrecoff); + (uint32) (ControlFile.backupStartPoint >> 32), + (uint32) ControlFile.backupStartPoint); printf(_("Backup end location: %X/%X\n"), - ControlFile.backupEndPoint.xlogid, - ControlFile.backupEndPoint.xrecoff); + (uint32) (ControlFile.backupEndPoint >> 32), + (uint32) ControlFile.backupEndPoint); printf(_("End-of-backup record required: %s\n"), ControlFile.backupEndRequired ? _("yes") : _("no")); printf(_("Current wal_level setting: %s\n"), diff --git a/src/bin/pg_resetxlog/pg_resetxlog.c b/src/bin/pg_resetxlog/pg_resetxlog.c index 45d9aa3d23..3500c4cf1d 100644 --- a/src/bin/pg_resetxlog/pg_resetxlog.c +++ b/src/bin/pg_resetxlog/pg_resetxlog.c @@ -463,8 +463,7 @@ GuessControlValues(void) ControlFile.system_identifier = sysidentifier; - ControlFile.checkPointCopy.redo.xlogid = 0; - ControlFile.checkPointCopy.redo.xrecoff = SizeOfXLogLongPHD; + ControlFile.checkPointCopy.redo = SizeOfXLogLongPHD; ControlFile.checkPointCopy.ThisTimeLineID = 1; ControlFile.checkPointCopy.fullPageWrites = false; ControlFile.checkPointCopy.nextXidEpoch = 0; @@ -611,14 +610,10 @@ RewriteControlFile(void) ControlFile.state = DB_SHUTDOWNED; ControlFile.time = (pg_time_t) time(NULL); ControlFile.checkPoint = ControlFile.checkPointCopy.redo; - ControlFile.prevCheckPoint.xlogid = 0; - ControlFile.prevCheckPoint.xrecoff = 0; - ControlFile.minRecoveryPoint.xlogid = 0; - ControlFile.minRecoveryPoint.xrecoff = 0; - ControlFile.backupStartPoint.xlogid = 0; - ControlFile.backupStartPoint.xrecoff = 0; - ControlFile.backupEndPoint.xlogid = 0; - ControlFile.backupEndPoint.xrecoff = 0; + ControlFile.prevCheckPoint = 0; + ControlFile.minRecoveryPoint = 0; + ControlFile.backupStartPoint = 0; + ControlFile.backupEndPoint = 0; ControlFile.backupEndRequired = false; /* @@ -714,8 +709,7 @@ FindEndOfXLOG(void) * numbering according to the old xlog seg size. */ segs_per_xlogid = (0x100000000L / ControlFile.xlog_seg_size); - newXlogSegNo = ((uint64) ControlFile.checkPointCopy.redo.xlogid) * segs_per_xlogid - + (ControlFile.checkPointCopy.redo.xrecoff / ControlFile.xlog_seg_size); + newXlogSegNo = ControlFile.checkPointCopy.redo / ControlFile.xlog_seg_size; /* * Scan the pg_xlog directory to find existing WAL segment files. We @@ -919,10 +913,7 @@ WriteEmptyXLOG(void) page->xlp_magic = XLOG_PAGE_MAGIC; page->xlp_info = XLP_LONG_HEADER; page->xlp_tli = ControlFile.checkPointCopy.ThisTimeLineID; - page->xlp_pageaddr.xlogid = - ControlFile.checkPointCopy.redo.xlogid; - page->xlp_pageaddr.xrecoff = - ControlFile.checkPointCopy.redo.xrecoff - SizeOfXLogLongPHD; + page->xlp_pageaddr = ControlFile.checkPointCopy.redo - SizeOfXLogLongPHD; longpage = (XLogLongPageHeader) page; longpage->xlp_sysid = ControlFile.system_identifier; longpage->xlp_seg_size = XLogSegSize; @@ -930,8 +921,7 @@ WriteEmptyXLOG(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); diff --git a/src/include/access/transam.h b/src/include/access/transam.h index 937386575b..228f6a12c3 100644 --- a/src/include/access/transam.h +++ b/src/include/access/transam.h @@ -139,10 +139,6 @@ extern bool TransactionStartedDuringRecovery(void); /* in transam/varsup.c */ extern PGDLLIMPORT VariableCache ShmemVariableCache; -/* in transam/transam.c */ -extern const XLogRecPtr InvalidXLogRecPtr; - - /* * prototypes for functions in transam/transam.c */ diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h index d6e4bc5d7f..4ad4d13699 100644 --- a/src/include/access/xlog_internal.h +++ b/src/include/access/xlog_internal.h @@ -51,7 +51,7 @@ typedef struct BkpBlock /* * Each page of XLOG file has a header like this: */ -#define XLOG_PAGE_MAGIC 0xD074 /* can be used as WAL version indicator */ +#define XLOG_PAGE_MAGIC 0xD075 /* can be used as WAL version indicator */ typedef struct XLogPageHeaderData { @@ -113,10 +113,7 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader; #define XLogSegmentsPerXLogId (0x100000000L / XLOG_SEG_SIZE) #define XLogSegNoOffsetToRecPtr(segno, offset, dest) \ - do { \ - (dest).xlogid = (segno) / XLogSegmentsPerXLogId; \ - (dest).xrecoff = ((segno) % XLogSegmentsPerXLogId) * XLOG_SEG_SIZE + (offset); \ - } while (0) + (dest) = (segno) * XLOG_SEG_SIZE + (offset) /* * Macros for manipulating XLOG pointers @@ -125,8 +122,8 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader; /* Align a record pointer to next page */ #define NextLogPage(recptr) \ do { \ - if ((recptr).xrecoff % XLOG_BLCKSZ != 0) \ - XLByteAdvance(recptr, (XLOG_BLCKSZ - (recptr).xrecoff % XLOG_BLCKSZ)); \ + if ((recptr) % XLOG_BLCKSZ != 0) \ + XLByteAdvance(recptr, (XLOG_BLCKSZ - (recptr) % XLOG_BLCKSZ)); \ } while (0) /* @@ -135,14 +132,13 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader; * For XLByteToSeg, do the computation at face value. For XLByteToPrevSeg, * a boundary byte is taken to be in the previous segment. This is suitable * for deciding which segment to write given a pointer to a record end, - * for example. (We can assume xrecoff is not zero, since no valid recptr - * can have that.) + * for example. */ #define XLByteToSeg(xlrp, logSegNo) \ - logSegNo = ((uint64) (xlrp).xlogid * XLogSegmentsPerXLogId) + (xlrp).xrecoff / XLogSegSize + logSegNo = (xlrp) / XLogSegSize #define XLByteToPrevSeg(xlrp, logSegNo) \ - logSegNo = ((uint64) (xlrp).xlogid * XLogSegmentsPerXLogId) + ((xlrp).xrecoff - 1) / XLogSegSize + logSegNo = ((xlrp) - 1) / XLogSegSize /* * Is an XLogRecPtr within a particular XLOG segment? @@ -151,20 +147,15 @@ typedef XLogLongPageHeaderData *XLogLongPageHeader; * a boundary byte is taken to be in the previous segment. */ #define XLByteInSeg(xlrp, logSegNo) \ - (((xlrp).xlogid) == (logSegNo) / XLogSegmentsPerXLogId && \ - ((xlrp).xrecoff / XLogSegSize) == (logSegNo) % XLogSegmentsPerXLogId) + (((xlrp) / XLogSegSize) == (logSegNo)) #define XLByteInPrevSeg(xlrp, logSegNo) \ - (((xlrp).xrecoff == 0) ? \ - (((xlrp).xlogid - 1) == (logSegNo) / XLogSegmentsPerXLogId && \ - ((uint32) 0xffffffff) / XLogSegSize == (logSegNo) % XLogSegmentsPerXLogId) : \ - ((xlrp).xlogid) == (logSegNo) / XLogSegmentsPerXLogId && \ - (((xlrp).xrecoff - 1) / XLogSegSize) == (logSegNo) % XLogSegmentsPerXLogId) + ((((xlrp) - 1) / XLogSegSize) == (logSegNo)) -/* Check if an xrecoff value is in a plausible range */ -#define XRecOffIsValid(xrecoff) \ - ((xrecoff) % XLOG_BLCKSZ >= SizeOfXLogShortPHD && \ - (XLOG_BLCKSZ - (xrecoff) % XLOG_BLCKSZ) >= SizeOfXLogRecord) +/* Check if an XLogRecPtr value is in a plausible range */ +#define XRecOffIsValid(xlrp) \ + ((xlrp) % XLOG_BLCKSZ >= SizeOfXLogShortPHD && \ + (XLOG_BLCKSZ - (xlrp) % XLOG_BLCKSZ) >= SizeOfXLogRecord) /* * The XLog directory and control file (relative to $PGDATA) diff --git a/src/include/access/xlogdefs.h b/src/include/access/xlogdefs.h index 603854884f..153d0de22a 100644 --- a/src/include/access/xlogdefs.h +++ b/src/include/access/xlogdefs.h @@ -17,55 +17,30 @@ /* * Pointer to a location in the XLOG. These pointers are 64 bits wide, * because we don't want them ever to overflow. - * - * NOTE: xrecoff == 0 is used to indicate an invalid pointer. This is OK - * because we use page headers in the XLOG, so no XLOG record can start - * right at the beginning of a file. - * - * NOTE: the "log file number" is somewhat misnamed, since the actual files - * making up the XLOG are much smaller than 4Gb. Each actual file is an - * XLogSegSize-byte "segment" of a logical log file having the indicated - * xlogid. The log file number and segment number together identify a - * physical XLOG file. Segment number and offset within the physical file - * are computed from xrecoff div and mod XLogSegSize. */ -typedef struct XLogRecPtr -{ - uint32 xlogid; /* log file #, 0 based */ - uint32 xrecoff; /* byte offset of location in log file */ -} XLogRecPtr; - -#define XLogRecPtrIsInvalid(r) ((r).xrecoff == 0) +typedef uint64 XLogRecPtr; +/* + * Zero is used indicate an invalid pointer. Bootstrap skips the first possible + * WAL segment, initializing the first WAL page at XLOG_SEG_SIZE, so no XLOG + * record can begin at zero. + */ +#define InvalidXLogRecPtr 0 +#define XLogRecPtrIsInvalid(r) ((r) == InvalidXLogRecPtr) /* * Macros for comparing XLogRecPtrs - * - * Beware of passing expressions with side-effects to these macros, - * since the arguments may be evaluated multiple times. */ -#define XLByteLT(a, b) \ - ((a).xlogid < (b).xlogid || \ - ((a).xlogid == (b).xlogid && (a).xrecoff < (b).xrecoff)) - -#define XLByteLE(a, b) \ - ((a).xlogid < (b).xlogid || \ - ((a).xlogid == (b).xlogid && (a).xrecoff <= (b).xrecoff)) - -#define XLByteEQ(a, b) \ - ((a).xlogid == (b).xlogid && (a).xrecoff == (b).xrecoff) +#define XLByteLT(a, b) ((a) < (b)) +#define XLByteLE(a, b) ((a) <= (b)) +#define XLByteEQ(a, b) ((a) == (b)) /* * Macro for advancing a record pointer by the specified number of bytes. */ #define XLByteAdvance(recptr, nbytes) \ - do { \ - uint32 oldxrecoff = (recptr).xrecoff; \ - (recptr).xrecoff += nbytes; \ - if ((recptr).xrecoff < oldxrecoff) \ - (recptr).xlogid += 1; /* xrecoff wrapped around */ \ - } while (0) + (recptr) += nbytes \ /* * XLogSegNo - physical log file sequence number. diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h index 5cff39608b..c9ee80531c 100644 --- a/src/include/catalog/pg_control.h +++ b/src/include/catalog/pg_control.h @@ -21,7 +21,7 @@ /* Version identifier for this pg_control format */ -#define PG_CONTROL_VERSION 922 +#define PG_CONTROL_VERSION 931 /* * Body of CheckPoint XLOG records. This is declared here because we keep diff --git a/src/include/storage/bufpage.h b/src/include/storage/bufpage.h index 1ab64e021d..fc3a69b678 100644 --- a/src/include/storage/bufpage.h +++ b/src/include/storage/bufpage.h @@ -119,10 +119,18 @@ typedef uint16 LocationIndex; * On the high end, we can only support pages up to 32KB because lp_off/lp_len * are 15 bits. */ + +/* for historical reasons, the LSN is stored as two 32-bit values. */ +typedef struct +{ + uint32 xlogid; /* high bits */ + uint32 xrecoff; /* low bits */ +} PageXLogRecPtr; + typedef struct PageHeaderData { /* XXX LSN is member of *any* block, not only page-organized ones */ - XLogRecPtr pd_lsn; /* LSN: next byte after last byte of xlog + PageXLogRecPtr pd_lsn; /* LSN: next byte after last byte of xlog * record for last change to this page */ uint16 pd_tli; /* least significant bits of the TimeLineID * containing the LSN */ @@ -314,9 +322,10 @@ typedef PageHeaderData *PageHeader; * Additional macros for access to page headers */ #define PageGetLSN(page) \ - (((PageHeader) (page))->pd_lsn) + ((uint64) ((PageHeader) (page))->pd_lsn.xlogid << 32 | ((PageHeader) (page))->pd_lsn.xrecoff) #define PageSetLSN(page, lsn) \ - (((PageHeader) (page))->pd_lsn = (lsn)) + (((PageHeader) (page))->pd_lsn.xlogid = (uint32) ((lsn) >> 32), \ + ((PageHeader) (page))->pd_lsn.xrecoff = (uint32) (lsn)) /* NOTE: only the 16 least significant bits are stored */ #define PageGetTLI(page) \