diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2012-05-08 23:05:58 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2012-05-08 23:06:40 -0400 |
commit | acd4c7d58baf09fc278a0f8c1170fba2d56ccdd5 (patch) | |
tree | 67a9b17ba1bfa2b5414460287b6928b77d78f5d8 /src/backend/access/transam/xlog.c | |
parent | 8b77e226fbf4834a03fcef2fa31aa85dac40c941 (diff) | |
download | postgresql-acd4c7d58baf09fc278a0f8c1170fba2d56ccdd5.tar.gz postgresql-acd4c7d58baf09fc278a0f8c1170fba2d56ccdd5.zip |
Fix an issue in recent walwriter hibernation patch.
Users of asynchronous-commit mode expect there to be a guaranteed maximum
delay before an async commit's WAL records get flushed to disk. The
original version of the walwriter hibernation patch broke that. Add an
extra shared-memory flag to allow async commits to kick the walwriter out
of hibernation mode, without adding any noticeable overhead in cases where
no action is needed.
Diffstat (limited to 'src/backend/access/transam/xlog.c')
-rw-r--r-- | src/backend/access/transam/xlog.c | 48 |
1 files changed, 41 insertions, 7 deletions
diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 6d3a4cd3dfe..d3650bdf051 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -427,6 +427,13 @@ typedef struct XLogCtlData bool SharedHotStandbyActive; /* + * WalWriterSleeping indicates whether the WAL writer is currently in + * low-power mode (and hence should be nudged if an async commit occurs). + * Protected by info_lck. + */ + bool WalWriterSleeping; + + /* * recoveryWakeupLatch is used to wake up the startup process to continue * WAL replay, if it is waiting for WAL to arrive or failover trigger file * to appear. @@ -1903,32 +1910,44 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch) /* * Record the LSN for an asynchronous transaction commit/abort - * and nudge the WALWriter if there is a complete page to write. + * and nudge the WALWriter if there is work for it to do. * (This should not be called for synchronous commits.) */ void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN) { XLogRecPtr WriteRqstPtr = asyncXactLSN; + bool sleeping; /* use volatile pointer to prevent code rearrangement */ volatile XLogCtlData *xlogctl = XLogCtl; SpinLockAcquire(&xlogctl->info_lck); LogwrtResult = xlogctl->LogwrtResult; + sleeping = xlogctl->WalWriterSleeping; if (XLByteLT(xlogctl->asyncXactLSN, asyncXactLSN)) xlogctl->asyncXactLSN = asyncXactLSN; SpinLockRelease(&xlogctl->info_lck); - /* back off to last completed page boundary */ - WriteRqstPtr.xrecoff -= WriteRqstPtr.xrecoff % XLOG_BLCKSZ; + /* + * If the WALWriter is sleeping, we should kick it to make it come out of + * low-power mode. Otherwise, determine whether there's a full page of + * WAL available to write. + */ + if (!sleeping) + { + /* back off to last completed page boundary */ + WriteRqstPtr.xrecoff -= WriteRqstPtr.xrecoff % XLOG_BLCKSZ; - /* if we have already flushed that far, we're done */ - if (XLByteLE(WriteRqstPtr, LogwrtResult.Flush)) - return; + /* if we have already flushed that far, we're done */ + if (XLByteLE(WriteRqstPtr, LogwrtResult.Flush)) + return; + } /* - * Nudge the WALWriter if we have a full page of WAL to write. + * Nudge the WALWriter: it has a full page of WAL to write, or we want + * it to come out of low-power mode so that this async commit will reach + * disk within the expected amount of time. */ if (ProcGlobal->walwriterLatch) SetLatch(ProcGlobal->walwriterLatch); @@ -5100,6 +5119,7 @@ XLOGShmemInit(void) XLogCtl->XLogCacheBlck = XLOGbuffers - 1; XLogCtl->SharedRecoveryInProgress = true; XLogCtl->SharedHotStandbyActive = false; + XLogCtl->WalWriterSleeping = false; XLogCtl->Insert.currpage = (XLogPageHeader) (XLogCtl->pages); SpinLockInit(&XLogCtl->info_lck); InitSharedLatch(&XLogCtl->recoveryWakeupLatch); @@ -10479,3 +10499,17 @@ WakeupRecovery(void) { SetLatch(&XLogCtl->recoveryWakeupLatch); } + +/* + * Update the WalWriterSleeping flag. + */ +void +SetWalWriterSleeping(bool sleeping) +{ + /* use volatile pointer to prevent code rearrangement */ + volatile XLogCtlData *xlogctl = XLogCtl; + + SpinLockAcquire(&xlogctl->info_lck); + xlogctl->WalWriterSleeping = sleeping; + SpinLockRelease(&xlogctl->info_lck); +} |