diff options
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r-- | src/backend/access/transam/xlog.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 140f9109a6f..479c14da902 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -391,6 +391,10 @@ typedef struct XLogCtlData XLogRecPtr asyncXactLSN; /* LSN of newest async commit/abort */ XLogSegNo lastRemovedSegNo; /* latest removed/recycled XLOG segment */ + /* Fake LSN counter, for unlogged relations. Protected by ulsn_lck */ + XLogRecPtr unloggedLSN; + slock_t ulsn_lck; + /* Protected by WALWriteLock: */ XLogCtlWrite Write; @@ -3697,6 +3701,31 @@ GetSystemIdentifier(void) } /* + * Returns a fake LSN for unlogged relations. + * + * Each call generates an LSN that is greater than any previous value + * returned. The current counter value is saved and restored across clean + * shutdowns, but like unlogged relations, does not survive a crash. This can + * be used in lieu of real LSN values returned by XLogInsert, if you need an + * LSN-like increasing sequence of numbers without writing any WAL. + */ +XLogRecPtr +GetFakeLSNForUnloggedRel(void) +{ + XLogRecPtr nextUnloggedLSN; + + /* use volatile pointer to prevent code rearrangement */ + volatile XLogCtlData *xlogctl = XLogCtl; + + /* increment the unloggedLSN counter, need SpinLock */ + SpinLockAcquire(&xlogctl->ulsn_lck); + nextUnloggedLSN = xlogctl->unloggedLSN++; + SpinLockRelease(&xlogctl->ulsn_lck); + + return nextUnloggedLSN; +} + +/* * Auto-tune the number of XLOG buffers. * * The preferred setting for wal_buffers is about 3% of shared_buffers, with @@ -3844,6 +3873,7 @@ XLOGShmemInit(void) XLogCtl->WalWriterSleeping = false; XLogCtl->Insert.currpage = (XLogPageHeader) (XLogCtl->pages); SpinLockInit(&XLogCtl->info_lck); + SpinLockInit(&XLogCtl->ulsn_lck); InitSharedLatch(&XLogCtl->recoveryWakeupLatch); /* @@ -3989,6 +4019,7 @@ BootStrapXLOG(void) ControlFile->time = checkPoint.time; ControlFile->checkPoint = checkPoint.redo; ControlFile->checkPointCopy = checkPoint; + ControlFile->unloggedLSN = 1; /* Set important parameter values for use when replaying WAL */ ControlFile->MaxConnections = MaxConnections; @@ -5033,6 +5064,16 @@ StartupXLOG(void) XLogCtl->ckptXid = checkPoint.nextXid; /* + * Initialize unlogged LSN. On a clean shutdown, it's restored from the + * control file. On recovery, all unlogged relations are blown away, so + * the unlogged LSN counter can be reset too. + */ + if (ControlFile->state == DB_SHUTDOWNED) + XLogCtl->unloggedLSN = ControlFile->unloggedLSN; + else + XLogCtl->unloggedLSN = 1; + + /* * We must replay WAL entries using the same TimeLineID they were created * under, so temporarily adopt the TLI indicated by the checkpoint (see * also xlog_redo()). @@ -6916,6 +6957,16 @@ CreateCheckPoint(int flags) /* crash recovery should always recover to the end of WAL */ ControlFile->minRecoveryPoint = InvalidXLogRecPtr; ControlFile->minRecoveryPointTLI = 0; + + /* + * Persist unloggedLSN value. It's reset on crash recovery, so this goes + * unused on non-shutdown checkpoints, but seems useful to store it always + * for debugging purposes. + */ + SpinLockAcquire(&XLogCtl->ulsn_lck); + ControlFile->unloggedLSN = XLogCtl->unloggedLSN; + SpinLockRelease(&XLogCtl->ulsn_lck); + UpdateControlFile(); LWLockRelease(ControlFileLock); |