mirror of
https://github.com/postgres/postgres.git
synced 2025-06-29 10:41:53 +03:00
Support an optional asynchronous commit mode, in which we don't flush WAL
before reporting a transaction committed. Data consistency is still guaranteed (unlike setting fsync = off), but a crash may lose the effects of the last few transactions. Patch by Simon, some editorialization by Tom.
This commit is contained in:
@ -7,7 +7,7 @@
|
||||
* Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
|
||||
* Portions Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.275 2007/07/24 04:54:08 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.276 2007/08/01 22:45:08 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -305,6 +305,7 @@ typedef struct XLogCtlData
|
||||
XLogwrtResult LogwrtResult;
|
||||
uint32 ckptXidEpoch; /* nextXID & epoch of latest checkpoint */
|
||||
TransactionId ckptXid;
|
||||
XLogRecPtr asyncCommitLSN; /* LSN of newest async commit */
|
||||
|
||||
/* Protected by WALWriteLock: */
|
||||
XLogCtlWrite Write;
|
||||
@ -1643,6 +1644,22 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible, bool xlog_switch)
|
||||
Write->LogwrtResult = LogwrtResult;
|
||||
}
|
||||
|
||||
/*
|
||||
* Record the LSN for an asynchronous transaction commit.
|
||||
* (This should not be called for aborts, nor for synchronous commits.)
|
||||
*/
|
||||
void
|
||||
XLogSetAsyncCommitLSN(XLogRecPtr asyncCommitLSN)
|
||||
{
|
||||
/* use volatile pointer to prevent code rearrangement */
|
||||
volatile XLogCtlData *xlogctl = XLogCtl;
|
||||
|
||||
SpinLockAcquire(&xlogctl->info_lck);
|
||||
if (XLByteLT(xlogctl->asyncCommitLSN, asyncCommitLSN))
|
||||
xlogctl->asyncCommitLSN = asyncCommitLSN;
|
||||
SpinLockRelease(&xlogctl->info_lck);
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure that all XLOG data through the given position is flushed to disk.
|
||||
*
|
||||
@ -1797,19 +1814,17 @@ XLogBackgroundFlush(void)
|
||||
/* back off to last completed page boundary */
|
||||
WriteRqstPtr.xrecoff -= WriteRqstPtr.xrecoff % XLOG_BLCKSZ;
|
||||
|
||||
#ifdef NOT_YET /* async commit patch is still to come */
|
||||
/* if we have already flushed that far, consider async commit records */
|
||||
if (XLByteLE(WriteRqstPtr, LogwrtResult.Flush))
|
||||
{
|
||||
/* use volatile pointer to prevent code rearrangement */
|
||||
volatile XLogCtlData *xlogctl = XLogCtl;
|
||||
|
||||
SpinLockAcquire(&xlogctl->async_commit_lck);
|
||||
SpinLockAcquire(&xlogctl->info_lck);
|
||||
WriteRqstPtr = xlogctl->asyncCommitLSN;
|
||||
SpinLockRelease(&xlogctl->async_commit_lck);
|
||||
SpinLockRelease(&xlogctl->info_lck);
|
||||
flexible = false; /* ensure it all gets written */
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Done if already known flushed */
|
||||
if (XLByteLE(WriteRqstPtr, LogwrtResult.Flush))
|
||||
@ -1841,6 +1856,23 @@ XLogBackgroundFlush(void)
|
||||
END_CRIT_SECTION();
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush any previous asynchronously-committed transactions' commit records.
|
||||
*/
|
||||
void
|
||||
XLogAsyncCommitFlush(void)
|
||||
{
|
||||
XLogRecPtr WriteRqstPtr;
|
||||
/* use volatile pointer to prevent code rearrangement */
|
||||
volatile XLogCtlData *xlogctl = XLogCtl;
|
||||
|
||||
SpinLockAcquire(&xlogctl->info_lck);
|
||||
WriteRqstPtr = xlogctl->asyncCommitLSN;
|
||||
SpinLockRelease(&xlogctl->info_lck);
|
||||
|
||||
XLogFlush(WriteRqstPtr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test whether XLOG data has been flushed up to (at least) the given position.
|
||||
*
|
||||
@ -5466,7 +5498,7 @@ ShutdownXLOG(int code, Datum arg)
|
||||
(errmsg("database system is shut down")));
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Log start of a checkpoint.
|
||||
*/
|
||||
static void
|
||||
@ -5481,7 +5513,7 @@ LogCheckpointStart(int flags)
|
||||
(flags & CHECKPOINT_CAUSE_TIME) ? " time" : "");
|
||||
}
|
||||
|
||||
/*
|
||||
/*
|
||||
* Log end of a checkpoint.
|
||||
*/
|
||||
static void
|
||||
@ -5523,7 +5555,7 @@ LogCheckpointEnd(void)
|
||||
* flags is a bitwise OR of the following:
|
||||
* CHECKPOINT_IS_SHUTDOWN: checkpoint is for database shutdown.
|
||||
* CHECKPOINT_IMMEDIATE: finish the checkpoint ASAP,
|
||||
* ignoring checkpoint_completion_target parameter.
|
||||
* ignoring checkpoint_completion_target parameter.
|
||||
* CHECKPOINT_FORCE: force a checkpoint even if no XLOG activity has occured
|
||||
* since the last one (implied by CHECKPOINT_IS_SHUTDOWN).
|
||||
*
|
||||
|
Reference in New Issue
Block a user