Thread
Commits
Same data as JSON:
GET /api/v1/messages/:b64id/commits
the thread's linked commits as JSON, with link sources.
API reference →
-
Do not lock in BufferGetLSNAtomic() on archs with 8 byte atomic reads
- 943e881733ca 19 (unreleased) landed
-
Reduce pinning and buffer content locking for btree scans.
- 2ed5b87f96d4 9.5.0 cited
-
Remove header lock BufferGetLSNAtomic() on architectures with 64 bit atomic operations
Andreas Karlsson <andreas@proxel.se> — 2025-11-23T23:10:03Z
Hi, Andres pointed out this possible optimization on Discord so I hacked up a quick patch which avoids taking a lock when reading the LSN from a page on architectures where we can be sure to not get a torn value. It is always nice to remove a lock from a reasonably hot code path. I thought about using our functions for atomics but did not do so since I did not want to introduce any extra overhead on platforms which do not support 64-bit atomic operations. I decided to just remove the struct to make the code simpler and more consistent but I can also see an argument for keeping it to get some degree of type safety. I have not properly benchmarked it yet but plan to do so when I am back from my vacation. I have also included a cleanup patch where I change a macro into an inline function which I think improves code readability. Feel free to ignore that one if you want. -- Andreas Percona
-
Re: Remove header lock BufferGetLSNAtomic() on architectures with 64 bit atomic operations
Peter Geoghegan <pg@bowt.ie> — 2025-12-14T00:28:36Z
On Sun, Nov 23, 2025 at 6:10 PM Andreas Karlsson <andreas@proxel.se> wrote: > Andres pointed out this possible optimization on Discord so I hacked up > a quick patch which avoids taking a lock when reading the LSN from a > page on architectures where we can be sure to not get a torn value. It > is always nice to remove a lock from a reasonably hot code path. This seems very useful. One reason why I'm interested in this work is that it will facilitate other work (from Tomas Vondra and myself) on the proposed new amgetbatch interface, which enables optimizations such as index prefetching. That work will replace the use of the amgettuple interface with a index page/batch oriented amgetbatch interface. It generalizes nbtree's dropPin optimization (originally added under a different name by commit 2ed5b87f) to work with any index AM that uses the new amgetbatch interface -- which will include both nbtree and hash in the initial version (and possibly other index AMs in the future). This means that there'll be quite a few new BufferGetLSNAtomic calls during scans of hash indexes, where before there were none -- we need to stash an LSN so that we have an alternative way of detecting unsafe concurrent TID recycling when LP_DEAD-marking index tuples as a batch is released (since there'll have been no buffer pin held on the index leaf page while we accessed the heap when the dropPin optimization is applied). With page-level checksums enabled, on the recently posted v4 of our patch set, I find that there's a regression of about 5% of transaction throughput with a variant of pgbench SELECT that uses hash indexes. But with your patch applied on top of our own, that regression completely goes away. FWIW the improvement I see with regular nbtree index scans is still visible, but not quite as good as with hash indexes + the amgetbatch patch set. It should be easy enough to see this for yourself. Standard pgbench SELECT should work well enough -- just make sure that you test with page-level checksums enabled. -- Peter Geoghegan
-
Re: Remove header lock BufferGetLSNAtomic() on architectures with 64 bit atomic operations
Andreas Karlsson <andreas@proxel.se> — 2025-12-31T02:17:11Z
On 11/24/25 12:10 AM, Andreas Karlsson wrote: > Andres pointed out this possible optimization on Discord so I hacked up > a quick patch which avoids taking a lock when reading the LSN from a > page on architectures where we can be sure to not get a torn value. It > is always nice to remove a lock from a reasonably hot code path. > > I thought about using our functions for atomics but did not do so since > I did not want to introduce any extra overhead on platforms which do not > support 64-bit atomic operations. > > I decided to just remove the struct to make the code simpler and more > consistent but I can also see an argument for keeping it to get some > degree of type safety. Noticed that the pageinspect tests in the CI did not like that I increased the alignment requirement of PageHeaderData from 4 to 8 bytes presumably due to a bytea's data being 4 byte aligned. I will need to think how to best fix this. Maybe copying the struct is fine in the the pageinspect code because being able to check for this alignment seems like a nice property for code which is not in pageinspect. It gives us the following backtrace: ../src/include/storage/bufpage.h:397:16: runtime error: member access within misaligned address 0x55d6721e69bc for type 'const struct PageHeaderData', which requires 8 byte alignment 0x55d6721e69bc: note: pointer points here 10 80 00 00 00 00 00 00 00 00 00 00 00 00 04 00 1c 00 e0 1f 00 20 04 20 00 00 00 00 e0 9f 40 00 ^ #0 0x7fb39deb9b07 in PageGetMaxOffsetNumber ../src/include/storage/bufpage.h:397 #1 0x7fb39debac3e in heap_page_items ../contrib/pageinspect/heapfuncs.c:168 #2 0x55d63ff127c7 in ExecMakeTableFunctionResult ../src/backend/executor/execSRF.c:234 #3 0x55d63ff42aa7 in FunctionNext ../src/backend/executor/nodeFunctionscan.c:94 #4 0x55d63ff14157 in ExecScanFetch ../src/include/executor/execScan.h:134 #5 0x55d63ff14157 in ExecScanExtended ../src/include/executor/execScan.h:195 #6 0x55d63ff14157 in ExecScan ../src/backend/executor/execScan.c:59 #7 0x55d63ff427b6 in ExecFunctionScan ../src/backend/executor/nodeFunctionscan.c:269 #8 0x55d63ff0c38c in ExecProcNodeFirst ../src/backend/executor/execProcnode.c:469 #9 0x55d63fef5cee in ExecProcNode ../src/include/executor/executor.h:319 #10 0x55d63fef6465 in ExecutePlan ../src/backend/executor/execMain.c:1707 #11 0x55d63fef7c00 in standard_ExecutorRun ../src/backend/executor/execMain.c:366 #12 0x55d63fef7c60 in ExecutorRun ../src/backend/executor/execMain.c:303 #13 0x55d640322295 in PortalRunSelect ../src/backend/tcop/pquery.c:916 #14 0x55d64032534e in PortalRun ../src/backend/tcop/pquery.c:760 #15 0x55d64031e34a in exec_simple_query ../src/backend/tcop/postgres.c:1279 #16 0x55d6403215ce in PostgresMain ../src/backend/tcop/postgres.c:4775 #17 0x55d640316c6c in BackendMain ../src/backend/tcop/backend_startup.c:124 #18 0x55d6401b2711 in postmaster_child_launch ../src/backend/postmaster/launch_backend.c:268 #19 0x55d6401b7b19 in BackendStartup ../src/backend/postmaster/postmaster.c:3598 #20 0x55d6401ba061 in ServerLoop ../src/backend/postmaster/postmaster.c:1713 #21 0x55d6401bb972 in PostmasterMain ../src/backend/postmaster/postmaster.c:1403 #22 0x55d63ffde07b in main ../src/backend/main/main.c:231 #23 0x7fb39e033ca7 (/lib/x86_64-linux-gnu/libc.so.6+0x29ca7) (BuildId: def5460e3cee00bfee25b429c97bcc4853e5b3a8) #24 0x7fb39e033d64 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x29d64) (BuildId: def5460e3cee00bfee25b429c97bcc4853e5b3a8) #25 0x55d63fb70260 in _start (/tmp/cirrus-ci-build/build/tmp_install/usr/local/pgsql/bin/postgres+0x8b0260) (BuildId: d2e585ffc320b6de4bfce11bb801bb923e7d3484) Links - https://cirrus-ci.com/task/5353983260229632 - https://api.cirrus-ci.com/v1/artifact/task/5353983260229632/testrun/build/testrun/pageinspect/regress/log/postmaster.log Andreas