Re: WIP: WAL prefetch (another approach)
Thomas Munro <thomas.munro@gmail.com>
Attachments
- 0001-Allow-PrefetchBuffer-to-be-called-with-a-SMgrRela-v5.patch (text/x-patch) patch v5-0001
- 0002-Rename-GetWalRcvWriteRecPtr-to-GetWalRcvFlushRecP-v5.patch (text/x-patch) patch v5-0002
- 0003-Add-WalRcvGetWriteRecPtr-new-definition-v5.patch (text/x-patch) patch v5-0003
- 0004-Allow-PrefetchBuffer-to-report-what-happened-v5.patch (text/x-patch) patch v5-0004
- 0005-Prefetch-referenced-blocks-during-recovery-v5.patch (text/x-patch) patch v5-0005
On Wed, Mar 18, 2020 at 2:47 PM Alvaro Herrera <alvherre@2ndquadrant.com> wrote: > On 2020-Mar-17, Thomas Munro wrote: > > I didn't want counters that wrap at ~4 billion, but I did want to be > > able to read and write concurrently without tearing. Instructions > > like "lock xadd" would provide more guarantees that I don't need, > > since only one thread is doing all the writing and there's no ordering > > requirement. It's basically just counter++, but some platforms need a > > spinlock to perform atomic read and write of 64 bit wide numbers, so > > more hoop jumping is required. > > Ah, I see, you don't want lock xadd ... That's non-obvious. I suppose > the function could use more commentary on *why* you're doing it that way > then. I updated the comment: +/* + * On modern systems this is really just *counter++. On some older systems + * there might be more to it, due to inability to read and write 64 bit values + * atomically. The counters will only be written to by one process, and there + * is no ordering requirement, so there's no point in using higher overhead + * pg_atomic_fetch_add_u64(). + */ +static inline void inc_counter(pg_atomic_uint64 *counter) > > > Umm, I would keep the return values of both these functions in sync. > > > It's really strange that PrefetchBuffer does not return > > > PrefetchBufferResult, don't you think? > > > > Agreed, and changed. I suspect that other users of the main > > PrefetchBuffer() call will eventually want that, to do a better job of > > keeping the request queue full, for example bitmap heap scan and > > (hypothetical) btree scan with prefetch. > > LGTM. Here's a new version that changes that part just a bit more, after a brief chat with Andres about his async I/O plans. It seems clear that returning an enum isn't very extensible, so I decided to try making PrefetchBufferResult a struct whose contents can be extended in the future. In this patch set it's still just used to distinguish 3 cases (hit, miss, no file), but it's now expressed as a buffer and a flag to indicate whether I/O was initiated. You could imagine that the second thing might be replaced by a pointer to an async I/O handle you can wait on or some other magical thing from the future. The concept here is that eventually we'll have just one XLogReader for both read ahead and recovery, and we could attach the prefetch results to the decoded records, and then recovery would try to use already looked up buffers to avoid a bit of work (and then recheck). In other words, the WAL would be decoded only once, and the buffers would hopefully be looked up only once, so you'd claw back all of the overheads of this patch. For now that's not done, and the buffer in the result is only compared with InvalidBuffer to check if there was a hit or not. Similar things could be done for bitmap heap scan and btree prefetch with this interface: their prefetch machinery could hold onto these results in their block arrays and try to avoid a more expensive ReadBuffer() call if they already have a buffer (though as before, there's a small chance it turns out to be the wrong one and they need to fall back to ReadBuffer()). > As before, I didn't get to reading 0005 in depth. Updated to account for the above-mentioned change, and with a couple of elog() calls changed to ereport().
Commits
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Fix recovery_prefetch docs.
- dafae9707ab7 15.0 landed
-
Prefetch data referenced by the WAL, take II.
- 5dc0418fab28 15.0 landed
-
Add circular WAL decoding buffer, take II.
- 3f1ce973467a 15.0 landed
-
Fix generation of ./INSTALL for the distribution tarball
- 45aa88fe1d40 14.0 cited
-
Revert recovery prefetching feature.
- c2dc19342e05 14.0 landed
-
Sync guc.c and postgresql.conf.sample with the SGML docs.
- a55a98477b69 14.0 cited
-
Add information of total data processed to replication slot stats.
- f5fc2f5b23d1 14.0 cited
-
Doc: Review for "Optionally prefetch referenced data in recovery."
- dc88460c24ed 14.0 landed
-
Add circular WAL decoding buffer.
- f003d9f8721b 14.0 landed
-
Optionally prefetch referenced data in recovery.
- 1d257577e08d 14.0 landed
-
Remove read_page callback from XLogReader.
- 323cbe7c7ddc 14.0 cited
-
Provide ReadRecentBuffer() to re-pin buffers by ID.
- 2f27f8c51149 14.0 landed
-
Provide recovery_init_sync_method=syncfs.
- 61752afb2640 14.0 cited
-
Mark factorial operator, and postfix operators in general, as deprecated.
- 6ca547cf75ef 14.0 cited
-
Rationalize GetWalRcv{Write,Flush}RecPtr().
- d140f2f3e225 13.0 landed
-
Support PrefetchBuffer() in recovery.
- 3985b600f57d 13.0 landed
-
Prevent hard failures of standbys caused by recycled WAL segments
- 70b4f82a4b5c 11.0 cited