diff options
author | Andres Freund | 2023-04-05 23:21:09 +0000 |
---|---|---|
committer | Andres Freund | 2023-04-05 23:21:09 +0000 |
commit | 31966b151e6ab7a6284deab6e8fe5faddaf2ae4c (patch) | |
tree | 76deeba4e15702f9596a6d935a8bd185554b8b45 /doc/src | |
parent | 8eda7314652703a2ae30d6c4a69c378f6813a7f2 (diff) |
bufmgr: Introduce infrastructure for faster relation extension
The primary bottlenecks for relation extension are:
1) The extension lock is held while acquiring a victim buffer for the new
page. Acquiring a victim buffer can require writing out the old page
contents including possibly needing to flush WAL.
2) When extending via ReadBuffer() et al, we write a zero page during the
extension, and then later write out the actual page contents. This can
nearly double the write rate.
3) The existing bulk relation extension infrastructure in hio.c just amortized
the cost of acquiring the relation extension lock, but none of the other
costs.
Unfortunately 1) cannot currently be addressed in a central manner as the
callers to ReadBuffer() need to acquire the extension lock. To address that,
this this commit moves the responsibility for acquiring the extension lock
into bufmgr.c functions. That allows to acquire the relation extension lock
for just the required time. This will also allow us to improve relation
extension further, without changing callers.
The reason we write all-zeroes pages during relation extension is that we hope
to get ENOSPC errors earlier that way (largely works, except for CoW
filesystems). It is easier to handle out-of-space errors gracefully if the
page doesn't yet contain actual tuples. This commit addresses 2), by using the
recently introduced smgrzeroextend(), which extends the relation, without
dirtying the kernel page cache for all the extended pages.
To address 3), this commit introduces a function to extend a relation by
multiple blocks at a time.
There are three new exposed functions: ExtendBufferedRel() for extending the
relation by a single block, ExtendBufferedRelBy() to extend a relation by
multiple blocks at once, and ExtendBufferedRelTo() for extending a relation up
to a certain size.
To avoid duplicating code between ReadBuffer(P_NEW) and the new functions,
ReadBuffer(P_NEW) now implements relation extension with
ExtendBufferedRel(), using a flag to tell ExtendBufferedRel() that the
relation lock is already held.
Note that this commit does not yet lead to a meaningful performance or
scalability improvement - for that uses of ReadBuffer(P_NEW) will need to be
converted to ExtendBuffered*(), which will be done in subsequent commits.
Reviewed-by: Heikki Linnakangas <[email protected]>
Reviewed-by: Melanie Plageman <[email protected]>
Discussion: https://postgr.es/m/[email protected]
Diffstat (limited to 'doc/src')
-rw-r--r-- | doc/src/sgml/monitoring.sgml | 43 |
1 files changed, 31 insertions, 12 deletions
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml index fd0ffbb1e0..bce9ae4661 100644 --- a/doc/src/sgml/monitoring.sgml +++ b/doc/src/sgml/monitoring.sgml @@ -7777,32 +7777,51 @@ FROM pg_stat_get_backend_idset() AS backendid; complete.</entry> </row> <row> + <entry><literal>buffer-extend-start</literal></entry> + <entry><literal>(ForkNumber, BlockNumber, Oid, Oid, Oid, int, unsigned int)</literal></entry> + <entry>Probe that fires when a relation extension starts. + arg0 contains the fork to be extended. arg1, arg2, and arg3 contain the + tablespace, database, and relation OIDs identifying the relation. arg4 + is the ID of the backend which created the temporary relation for a + local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared + buffer. arg5 is the number of blocks the caller would like to extend + by.</entry> + </row> + <row> + <entry><literal>buffer-extend-done</literal></entry> + <entry><literal>(ForkNumber, BlockNumber, Oid, Oid, Oid, int, unsigned int, BlockNumber)</literal></entry> + <entry>Probe that fires when a relation extension is complete. + arg0 contains the fork to be extended. arg1, arg2, and arg3 contain the + tablespace, database, and relation OIDs identifying the relation. arg4 + is the ID of the backend which created the temporary relation for a + local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared + buffer. arg5 is the number of blocks the relation was extended by, this + can be less than the number in the + <literal>buffer-extend-start</literal> due to resource + constraints. arg6 contains the BlockNumber of the first new + block.</entry> + </row> + <row> <entry><literal>buffer-read-start</literal></entry> - <entry><literal>(ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool)</literal></entry> + <entry><literal>(ForkNumber, BlockNumber, Oid, Oid, Oid, int)</literal></entry> <entry>Probe that fires when a buffer read is started. - arg0 and arg1 contain the fork and block numbers of the page (but - arg1 will be -1 if this is a relation extension request). + arg0 and arg1 contain the fork and block numbers of the page. arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs identifying the relation. arg5 is the ID of the backend which created the temporary relation for a local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared buffer. - arg6 is true for a relation extension request, false for normal - read.</entry> + </entry> </row> <row> <entry><literal>buffer-read-done</literal></entry> - <entry><literal>(ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool, bool)</literal></entry> + <entry><literal>(ForkNumber, BlockNumber, Oid, Oid, Oid, int, bool)</literal></entry> <entry>Probe that fires when a buffer read is complete. - arg0 and arg1 contain the fork and block numbers of the page (if this - is a relation extension request, arg1 now contains the block number - of the newly added block). + arg0 and arg1 contain the fork and block numbers of the page. arg2, arg3, and arg4 contain the tablespace, database, and relation OIDs identifying the relation. arg5 is the ID of the backend which created the temporary relation for a local buffer, or <symbol>InvalidBackendId</symbol> (-1) for a shared buffer. - arg6 is true for a relation extension request, false for normal - read. - arg7 is true if the buffer was found in the pool, false if not.</entry> + arg6 is true if the buffer was found in the pool, false if not.</entry> </row> <row> <entry><literal>buffer-flush-start</literal></entry> |