From fa7d62f088e90b3d1c3a2e656dacd174299f538f Mon Sep 17 00:00:00 2001 From: John Morris Date: Mon, 6 Nov 2023 15:53:07 -0800 Subject: [PATCH] atomic_lsn_v5 --- src/backend/access/transam/xlog.c | 36 +++++++++++++++---------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index b541be8eec..8f033749b3 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -469,9 +469,8 @@ typedef struct XLogCtlData XLogSegNo lastRemovedSegNo; /* latest removed/recycled XLOG segment */ - /* Fake LSN counter, for unlogged relations. Protected by ulsn_lck. */ - XLogRecPtr unloggedLSN; - slock_t ulsn_lck; + /* Fake LSN counter, for unlogged relations. */ + pg_atomic_uint64 unloggedLSN; /* Time and LSN of last xlog segment switch. Protected by WALWriteLock. */ pg_time_t lastSegSwitchTime; @@ -4294,13 +4293,8 @@ DataChecksumsEnabled(void) XLogRecPtr GetFakeLSNForUnloggedRel(void) { - XLogRecPtr nextUnloggedLSN; - - /* increment the unloggedLSN counter, need SpinLock */ - SpinLockAcquire(&XLogCtl->ulsn_lck); - nextUnloggedLSN = XLogCtl->unloggedLSN++; - SpinLockRelease(&XLogCtl->ulsn_lck); - + XLogRecPtr nextUnloggedLSN = pg_atomic_fetch_add_u64(&XLogCtl->unloggedLSN, 1); + Assert(nextUnloggedLSN != 0); return nextUnloggedLSN; } @@ -4714,7 +4708,7 @@ XLOGShmemInit(void) SpinLockInit(&XLogCtl->Insert.insertpos_lck); SpinLockInit(&XLogCtl->info_lck); - SpinLockInit(&XLogCtl->ulsn_lck); + pg_atomic_init_u64(&XLogCtl->unloggedLSN, 0); } /* @@ -5319,9 +5313,9 @@ StartupXLOG(void) * the unlogged LSN counter can be reset too. */ if (ControlFile->state == DB_SHUTDOWNED) - XLogCtl->unloggedLSN = ControlFile->unloggedLSN; + pg_atomic_write_u64(&XLogCtl->unloggedLSN, ControlFile->unloggedLSN); else - XLogCtl->unloggedLSN = FirstNormalUnloggedLSN; + pg_atomic_write_u64(&XLogCtl->unloggedLSN, FirstNormalUnloggedLSN); /* * Copy any missing timeline history files between 'now' and the recovery @@ -6899,13 +6893,17 @@ CreateCheckPoint(int flags) 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. + * On shutdown, persist the unlogged LSN and reset the counter to zero. + * if somebody tries to allocate another unlogged LSN, we should get an Assert() error. + * On a regular checkpoint, write a zero to the control file so we + * get an Assert() error if somebody accidentally uses the value in the control file. + * The unlogged LSN counter should be quiescent, but we use an atomic exchange + * just in case it isn't. */ - SpinLockAcquire(&XLogCtl->ulsn_lck); - ControlFile->unloggedLSN = XLogCtl->unloggedLSN; - SpinLockRelease(&XLogCtl->ulsn_lck); + if (shutdown) + ControlFile->unloggedLSN = pg_atomic_exchange_u64(&XLogCtl->unloggedLSN, 0); + else + ControlFile->unloggedLSN = 0; UpdateControlFile(); LWLockRelease(ControlFileLock); -- 2.33.0