Additional write barrier in AdvanceXLInsertBuffer().
authorJeff Davis <[email protected]>
Wed, 20 Dec 2023 01:35:54 +0000 (17:35 -0800)
committerJeff Davis <[email protected]>
Wed, 20 Dec 2023 01:35:54 +0000 (17:35 -0800)
First, mark the xlblocks member with InvalidXLogRecPtr, then issue a
write barrier, then initialize it. That ensures that the xlblocks
member doesn't appear valid while the contents are being initialized.

In preparation for reading WAL buffer contents without a lock.

Author: Bharath Rupireddy
Discussion: https://postgr.es/m/CALj2ACVfFMfqD5oLzZSQQZWfXiJqd-NdX0_317veP6FuB31QWA@mail.gmail.com
Reviewed-by: Andres Freund
src/backend/access/transam/xlog.c

index 1c77daa611a1d4974a8e3d9af935f0f54e9223d7..56e4d6fb0225a455206cc904b3debb238dc18ffb 100644 (file)
@@ -1932,6 +1932,14 @@ AdvanceXLInsertBuffer(XLogRecPtr upto, TimeLineID tli, bool opportunistic)
 
        NewPage = (XLogPageHeader) (XLogCtl->pages + nextidx * (Size) XLOG_BLCKSZ);
 
+       /*
+        * Mark the xlblock with InvalidXLogRecPtr and issue a write barrier
+        * before initializing. Otherwise, the old page may be partially
+        * zeroed but look valid.
+        */
+       pg_atomic_write_u64(&XLogCtl->xlblocks[nextidx], InvalidXLogRecPtr);
+       pg_write_barrier();
+
        /*
         * Be sure to re-zero the buffer so that bytes beyond what we've
         * written will look like zeroes and not valid XLOG records...