mirror of
https://github.com/postgres/postgres.git
synced 2026-05-28 04:35:45 -04:00
Use barrier semantics when reading/writing writtenUpto
The walreceiver publishes its write position lock-free via writtenUpto. On weakly-ordered architectures (ARM, PowerPC), both sides of this handshake need explicit barriers so that the lock-less reader sees a consistent state. Use pg_atomic_write_membarrier_u64() at both write sites and pg_atomic_read_membarrier_u64() in GetWalRcvWriteRecPtr(). This matches the barrier semantics that GetWalRcvFlushRecPtr() and other LSN-position functions get implicitly from their spinlock acquire/release, and protects from bugs caused by expectations of similar barrier guarantees from different LSN-position functions. Reported-by: Andres Freund <andres@anarazel.de> Discussion: https://postgr.es/m/zqbppucpmkeqecfy4s5kscnru4tbk6khp3ozqz6ad2zijz354k%40w4bdf4z3wqoz Author: Xuneng Zhou <xunengzhou@gmail.com> Reviewed-by: Andres Freund <andres@anarazel.de> Reviewed-by: Alexander Korotkov <aekorotkov@gmail.com>
This commit is contained in:
parent
c34a280c85
commit
dfb690dd52
2 changed files with 12 additions and 4 deletions
|
|
@ -978,7 +978,7 @@ XLogWalRcvWrite(char *buf, Size nbytes, XLogRecPtr recptr, TimeLineID tli)
|
|||
}
|
||||
|
||||
/* Update shared-memory status */
|
||||
pg_atomic_write_u64(&WalRcv->writtenUpto, LogstreamResult.Write);
|
||||
pg_atomic_write_membarrier_u64(&WalRcv->writtenUpto, LogstreamResult.Write);
|
||||
|
||||
/*
|
||||
* If we wrote an LSN that someone was waiting for, notify the waiters.
|
||||
|
|
|
|||
|
|
@ -321,7 +321,12 @@ RequestXLogStreaming(TimeLineID tli, XLogRecPtr recptr, const char *conninfo,
|
|||
walrcv->flushedUpto = recptr;
|
||||
walrcv->receivedTLI = tli;
|
||||
walrcv->latestChunkStart = recptr;
|
||||
pg_atomic_write_u64(&walrcv->writtenUpto, recptr);
|
||||
|
||||
/*
|
||||
* Pairs with pg_atomic_read_membarrier_u64() in
|
||||
* GetWalRcvWriteRecPtr().
|
||||
*/
|
||||
pg_atomic_write_membarrier_u64(&walrcv->writtenUpto, recptr);
|
||||
}
|
||||
walrcv->receiveStart = recptr;
|
||||
walrcv->receiveStartTLI = tli;
|
||||
|
|
@ -363,14 +368,17 @@ GetWalRcvFlushRecPtr(XLogRecPtr *latestChunkStart, TimeLineID *receiveTLI)
|
|||
|
||||
/*
|
||||
* Returns the last+1 byte position that walreceiver has written.
|
||||
* This returns a recently written value without taking a lock.
|
||||
*
|
||||
* Use pg_atomic_read_membarrier_u64() to ensure that callers see up-to-date
|
||||
* shared memory state, matching the barrier semantics provided by the
|
||||
* spinlock in GetWalRcvFlushRecPtr() and other LSN-position functions.
|
||||
*/
|
||||
XLogRecPtr
|
||||
GetWalRcvWriteRecPtr(void)
|
||||
{
|
||||
WalRcvData *walrcv = WalRcv;
|
||||
|
||||
return pg_atomic_read_u64(&walrcv->writtenUpto);
|
||||
return pg_atomic_read_membarrier_u64(&walrcv->writtenUpto);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue