Re: Improve WALRead() to suck data directly from WAL buffers when possible
Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>
From: Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com>
To: Andres Freund <andres@anarazel.de>
Cc: Jeff Davis <pgsql@j-davis.com>, Dilip Kumar <dilipbalaut@gmail.com>, Kyotaro Horiguchi <horikyota.ntt@gmail.com>,
pgsql-hackers@lists.postgresql.org, Nathan Bossart <nathandbossart@gmail.com>,
Masahiko Sawada <sawada.mshk@gmail.com>
Date: 2023-12-07T10:29:00Z
Lists: pgsql-hackers
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Add XLogCtl->logInsertResult
- f3ff7bf83bce 17.0 cited
-
Add assert to WALReadFromBuffers().
- 9ecbf54075a9 17.0 landed
-
Read WAL directly from WAL buffers.
- 91f2cae7a4e6 17.0 landed
-
Additional write barrier in AdvanceXLInsertBuffer().
- 766571be1659 17.0 landed
-
Use 64-bit atomics for xlblocks array elements.
- c3a8e2a7cb16 17.0 landed
-
Don't trust unvalidated xl_tot_len.
- bae868caf222 17.0 cited
Attachments
- v17-0001-Use-64-bit-atomics-for-xlblocks-array-elements.patch (application/octet-stream) patch v17-0001
- v17-0002-Allow-WAL-reading-from-WAL-buffers.patch (application/octet-stream) patch v17-0002
- v17-0003-Add-test-module-for-verifying-WAL-read-from-WAL-.patch (application/octet-stream) patch v17-0003
On Mon, Nov 13, 2023 at 7:02 PM Bharath Rupireddy <bharath.rupireddyforpostgres@gmail.com> wrote: > > On Fri, Nov 10, 2023 at 2:28 AM Andres Freund <andres@anarazel.de> wrote: > > > I think the code needs to make sure that *never* happens. That seems unrelated > > to holding or not holding WALBufMappingLock. Even if the page header is > > already valid, I don't think it's ok to just read/parse WAL data that's > > concurrently being modified. > > > > We can never allow WAL being read that's past > > XLogBytePosToRecPtr(XLogCtl->Insert->CurrBytePos) > > as it does not exist. > > Agreed. Erroring out in XLogReadFromBuffers() if passed in WAL is past > the CurrBytePos is an option. Another cleaner way is to just let the > caller decide what it needs to do (retry or error out) - fill an error > message in XLogReadFromBuffers() and return as-if nothing was read or > return a special negative error code like XLogDecodeNextRecord so that > the caller can deal with it. In the attached v17 patch, I've ensured that the XLogReadFromBuffers returns when the caller requests a WAL that's past the current insert position at the moment. > Also, reading CurrBytePos with insertpos_lck spinlock can come in the > way of concurrent inserters. A possible way is to turn both > CurrBytePos and PrevBytePos 64-bit atomics so that > XLogReadFromBuffers() can read CurrBytePos without any lock atomically > and leave it to the caller to deal with non-existing WAL reads. > > > And if the to-be-read LSN is between > > XLogCtl->LogwrtResult->Write and XLogBytePosToRecPtr(Insert->CurrBytePos) > > we need to call WaitXLogInsertionsToFinish() before copying the data. > > Agree to wait for all in-flight insertions to the pages we're about to > read to finish. But, reading XLogCtl->LogwrtRqst.Write requires either > XLogCtl->info_lck spinlock or WALWriteLock. Maybe turn > XLogCtl->LogwrtRqst.Write a 64-bit atomic and read it without any > lock, rely on > WaitXLogInsertionsToFinish()'s return value i.e. if > WaitXLogInsertionsToFinish() returns a value >= Insert->CurrBytePos, > then go read that page from WAL buffers. In the attached v17 patch, I've ensured that the XLogReadFromBuffers waits for all in-progress insertions to finish when the caller requests WAL that's past the current write position and before the current insert position. I've also ensured that the XLogReadFromBuffers returns special return codes for various scenarios (when asked to read in recovery, read on a different TLI, read a non-existent WAL and so on.) instead of it erroring out. This gives flexibility to the caller to decide what to do. -- Bharath Rupireddy PostgreSQL Contributors Team RDS Open Source Databases Amazon Web Services: https://aws.amazon.com