@@ -291,16 +291,15 @@ static bool doPageWrites;
291291 *
292292 * LogwrtRqst indicates a byte position that we need to write and/or fsync
293293 * the log up to (all records before that point must be written or fsynced).
294- * LogwrtResult indicates the byte positions we have already written/fsynced.
295- * These structs are identical but are declared separately to indicate their
296- * slightly different functions.
294+ * The positions already written/fsynced are maintained in logWriteResult
295+ * and logFlushResult.
297296 *
298- * To read XLogCtl->LogwrtResult , you must hold either info_lck or
299- * WALWriteLock. To updateit , you need to hold both locks. The point of
300- * this arrangement is that the value can be examined by code that already
301- * holds WALWriteLock without needing to grab info_lck as well. In addition
302- * to the shared variable, each backend has a private copy of LogwrtResult,
303- * which is updated when convenient.
297+ * To read XLogCtl->logWriteResult or ->logFlushResult , you must hold either
298+ *info_lck or WALWriteLock. To updatethem , you need to hold both locks.
299+ *The point of this arrangement is that the value can be examined by code
300+ *that already holds WALWriteLock without needing to grab info_lck as well.
301+ *In addition to the shared variable, each backend has a private copy of
302+ *both in LogwrtResult, which is updated when convenient.
304303 *
305304 * The request bookkeeping is simpler: there is a shared XLogCtl->LogwrtRqst
306305 * (protected by info_lck), but we don't need to cache any copies of it.
@@ -478,7 +477,8 @@ typedef struct XLogCtlData
478477 * Protected by info_lck and WALWriteLock (you must hold either lock to
479478 * read it, but both to update)
480479 */
481- XLogwrtResult LogwrtResult ;
480+ XLogRecPtr logWriteResult ;/* last byte + 1 written out */
481+ XLogRecPtr logFlushResult ;/* last byte + 1 flushed */
482482
483483/*
484484 * Latest initialized page in the cache (last byte position + 1).
@@ -614,6 +614,15 @@ static intUsableBytesInSegment;
614614 */
615615static XLogwrtResult LogwrtResult = {0 ,0 };
616616
617+ /*
618+ * Update local copy of shared XLogCtl->log{Write,Flush}Result
619+ */
620+ #define RefreshXLogWriteResult (_target ) \
621+ do { \
622+ _target.Write = XLogCtl->logWriteResult; \
623+ _target.Flush = XLogCtl->logFlushResult; \
624+ } while (0)
625+
617626/*
618627 * openLogFile is -1 or a kernel FD for an open log file segment.
619628 * openLogSegNo identifies the segment, and openLogTLI the corresponding TLI.
@@ -960,7 +969,7 @@ XLogInsertRecord(XLogRecData *rdata,
960969if (XLogCtl -> LogwrtRqst .Write < EndPos )
961970XLogCtl -> LogwrtRqst .Write = EndPos ;
962971/* update local result copy while I have the chance */
963- LogwrtResult = XLogCtl -> LogwrtResult ;
972+ RefreshXLogWriteResult ( LogwrtResult ) ;
964973SpinLockRelease (& XLogCtl -> info_lck );
965974}
966975
@@ -1984,7 +1993,7 @@ AdvanceXLInsertBuffer(XLogRecPtr upto, TimeLineID tli, bool opportunistic)
19841993SpinLockAcquire (& XLogCtl -> info_lck );
19851994if (XLogCtl -> LogwrtRqst .Write < OldPageRqstPtr )
19861995XLogCtl -> LogwrtRqst .Write = OldPageRqstPtr ;
1987- LogwrtResult = XLogCtl -> LogwrtResult ;
1996+ RefreshXLogWriteResult ( LogwrtResult ) ;
19881997SpinLockRelease (& XLogCtl -> info_lck );
19891998
19901999/*
@@ -2005,7 +2014,7 @@ AdvanceXLInsertBuffer(XLogRecPtr upto, TimeLineID tli, bool opportunistic)
20052014
20062015LWLockAcquire (WALWriteLock ,LW_EXCLUSIVE );
20072016
2008- LogwrtResult = XLogCtl -> LogwrtResult ;
2017+ RefreshXLogWriteResult ( LogwrtResult ) ;
20092018if (LogwrtResult .Write >=OldPageRqstPtr )
20102019{
20112020/* OK, someone wrote it already */
@@ -2289,7 +2298,7 @@ XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
22892298/*
22902299 * Update local LogwrtResult (caller probably did this already, but...)
22912300 */
2292- LogwrtResult = XLogCtl -> LogwrtResult ;
2301+ RefreshXLogWriteResult ( LogwrtResult ) ;
22932302
22942303/*
22952304 * Since successive pages in the xlog cache are consecutively allocated,
@@ -2549,7 +2558,8 @@ XLogWrite(XLogwrtRqst WriteRqst, TimeLineID tli, bool flexible)
25492558 */
25502559{
25512560SpinLockAcquire (& XLogCtl -> info_lck );
2552- XLogCtl -> LogwrtResult = LogwrtResult ;
2561+ XLogCtl -> logWriteResult = LogwrtResult .Write ;
2562+ XLogCtl -> logFlushResult = LogwrtResult .Flush ;
25532563if (XLogCtl -> LogwrtRqst .Write < LogwrtResult .Write )
25542564XLogCtl -> LogwrtRqst .Write = LogwrtResult .Write ;
25552565if (XLogCtl -> LogwrtRqst .Flush < LogwrtResult .Flush )
@@ -2572,7 +2582,7 @@ XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
25722582XLogRecPtr prevAsyncXactLSN ;
25732583
25742584SpinLockAcquire (& XLogCtl -> info_lck );
2575- LogwrtResult = XLogCtl -> LogwrtResult ;
2585+ RefreshXLogWriteResult ( LogwrtResult ) ;
25762586sleeping = XLogCtl -> WalWriterSleeping ;
25772587prevAsyncXactLSN = XLogCtl -> asyncXactLSN ;
25782588if (XLogCtl -> asyncXactLSN < asyncXactLSN )
@@ -2784,7 +2794,7 @@ XLogFlush(XLogRecPtr record)
27842794SpinLockAcquire (& XLogCtl -> info_lck );
27852795if (WriteRqstPtr < XLogCtl -> LogwrtRqst .Write )
27862796WriteRqstPtr = XLogCtl -> LogwrtRqst .Write ;
2787- LogwrtResult = XLogCtl -> LogwrtResult ;
2797+ RefreshXLogWriteResult ( LogwrtResult ) ;
27882798SpinLockRelease (& XLogCtl -> info_lck );
27892799
27902800/* done already? */
@@ -2815,7 +2825,7 @@ XLogFlush(XLogRecPtr record)
28152825}
28162826
28172827/* Got the lock; recheck whether request is satisfied */
2818- LogwrtResult = XLogCtl -> LogwrtResult ;
2828+ RefreshXLogWriteResult ( LogwrtResult ) ;
28192829if (record <=LogwrtResult .Flush )
28202830{
28212831LWLockRelease (WALWriteLock );
@@ -2939,7 +2949,7 @@ XLogBackgroundFlush(void)
29392949
29402950/* read LogwrtResult and update local state */
29412951SpinLockAcquire (& XLogCtl -> info_lck );
2942- LogwrtResult = XLogCtl -> LogwrtResult ;
2952+ RefreshXLogWriteResult ( LogwrtResult ) ;
29432953WriteRqst = XLogCtl -> LogwrtRqst ;
29442954SpinLockRelease (& XLogCtl -> info_lck );
29452955
@@ -3027,7 +3037,7 @@ XLogBackgroundFlush(void)
30273037/* now wait for any in-progress insertions to finish and get write lock */
30283038WaitXLogInsertionsToFinish (WriteRqst .Write );
30293039LWLockAcquire (WALWriteLock ,LW_EXCLUSIVE );
3030- LogwrtResult = XLogCtl -> LogwrtResult ;
3040+ RefreshXLogWriteResult ( LogwrtResult ) ;
30313041if (WriteRqst .Write > LogwrtResult .Write ||
30323042WriteRqst .Flush > LogwrtResult .Flush )
30333043{
@@ -3116,7 +3126,7 @@ XLogNeedsFlush(XLogRecPtr record)
31163126
31173127/* read LogwrtResult and update local state */
31183128SpinLockAcquire (& XLogCtl -> info_lck );
3119- LogwrtResult = XLogCtl -> LogwrtResult ;
3129+ RefreshXLogWriteResult ( LogwrtResult ) ;
31203130SpinLockRelease (& XLogCtl -> info_lck );
31213131
31223132/* check again */
@@ -5953,7 +5963,8 @@ StartupXLOG(void)
59535963
59545964LogwrtResult .Write = LogwrtResult .Flush = EndOfLog ;
59555965
5956- XLogCtl -> LogwrtResult = LogwrtResult ;
5966+ XLogCtl -> logWriteResult = LogwrtResult .Write ;
5967+ XLogCtl -> logFlushResult = LogwrtResult .Flush ;
59575968
59585969XLogCtl -> LogwrtRqst .Write = EndOfLog ;
59595970XLogCtl -> LogwrtRqst .Flush = EndOfLog ;
@@ -6400,7 +6411,7 @@ GetFlushRecPtr(TimeLineID *insertTLI)
64006411Assert (XLogCtl -> SharedRecoveryState == RECOVERY_STATE_DONE );
64016412
64026413SpinLockAcquire (& XLogCtl -> info_lck );
6403- LogwrtResult = XLogCtl -> LogwrtResult ;
6414+ RefreshXLogWriteResult ( LogwrtResult ) ;
64046415SpinLockRelease (& XLogCtl -> info_lck );
64056416
64066417/*
@@ -9316,7 +9327,7 @@ XLogRecPtr
93169327GetXLogWriteRecPtr (void )
93179328{
93189329SpinLockAcquire (& XLogCtl -> info_lck );
9319- LogwrtResult = XLogCtl -> LogwrtResult ;
9330+ RefreshXLogWriteResult ( LogwrtResult ) ;
93209331SpinLockRelease (& XLogCtl -> info_lck );
93219332
93229333return LogwrtResult .Write ;