Re: Buffer locking is special (hints, checksums, AIO writes)

Alexander Lakhin <exclusion@gmail.com>

From: Alexander Lakhin <exclusion@gmail.com>
To: Tom Lane <tgl@sss.pgh.pa.us>, Andres Freund <andres@anarazel.de>
Cc: Chao Li <li.evan.chao@gmail.com>, Kirill Reshke <reshkekirill@gmail.com>, Heikki Linnakangas <hlinnaka@iki.fi>, Melanie Plageman <melanieplageman@gmail.com>, Matthias van de Meent <boekewurm+postgres@gmail.com>, pgsql-hackers@postgresql.org, Thomas Munro <thomas.munro@gmail.com>, Noah Misch <noah@leadboat.com>, Robert Haas <robertmhaas@gmail.com>, Michael Paquier <michael.paquier@gmail.com>
Date: 2026-01-24T19:00:00Z
Lists: pgsql-hackers
Hello Andres,

16.01.2026 01:02, Tom Lane wrote:
> Various buildfarm animals are complaining about fcb9c977a,
> similarly to this from calliphoridae [1]:

I've discovered another anomaly introduced with fcb9c977a, this time
run-time:
for i in `seq 300`; do
echo "iteration $i"

echo "
create table t(f1 text);
create index on t using spgist(f1);
insert into t select 'a' from generate_series(1, 9000) g(i);
vacuum analyze t;
insert into t select 'b' from generate_series(1, 1000) g(i);
drop table t;
" | psql >/dev/null -v ON_ERROR_STOP=1 || break;
done

fails for me as below:
...
iteration 39
server closed the connection unexpectedly

Core was generated by `postgres: law regression [local] INSERT                 '.
Program terminated with signal SIGABRT, Aborted.
#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:44

warning: 44     ./nptl/pthread_kill.c: Нет такого файла или каталога
(gdb) bt
#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=<optimized out>, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3  0x000073625aa4527e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x000073625aa288ff in __GI_abort () at ./stdlib/abort.c:79
#5  0x00005a479e2f685f in ExceptionalCondition (conditionName=conditionName@entry=0x5a479e403cb8 "entry->data.lockmode 
== BUFFER_LOCK_UNLOCK", fileName=fileName@entry=0x5a479e37a84f "bufmgr.c", lineNumber=lineNumber@entry=5908) at assert.c:65
#6  0x00005a479e14d87c in BufferLockConditional (buffer=<optimized out>, buf_hdr=0x73624e882b40, 
mode=mode@entry=BUFFER_LOCK_EXCLUSIVE) at bufmgr.c:5908
#7  0x00005a479e14f4d5 in ConditionalLockBuffer (buffer=buffer@entry=13500) at bufmgr.c:6474
#8  0x00005a479de44da9 in SpGistNewBuffer (index=index@entry=0x73625b1f6ce8) at spgutils.c:420
#9  0x00005a479de45397 in allocNewBuffer (index=index@entry=0x73625b1f6ce8, flags=flags@entry=3) at spgutils.c:528
#10 0x00005a479de456a0 in SpGistGetBuffer (index=index@entry=0x73625b1f6ce8, flags=flags@entry=3, needSpace=<optimized 
out>, needSpace@entry=4088, isNew=isNew@entry=0x7ffd8fa1b2a7) at spgutils.c:663
#11 0x00005a479de3c913 in doPickSplit (index=index@entry=0x73625b1f6ce8, state=state@entry=0x7ffd8fa1b740, 
current=current@entry=0x7ffd8fa1b510, parent=parent@entry=0x7ffd8fa1b530, 
newLeafTuple=newLeafTuple@entry=0x5a47cbd7adc8, level=level@entry=4, isNulls=false, isNew=false) at spgdoinsert.c:1046
#12 0x00005a479de3e542 in spgdoinsert (index=index@entry=0x73625b1f6ce8, state=state@entry=0x7ffd8fa1b740, 
heapPtr=heapPtr@entry=0x5a47cbe0b248, datums=datums@entry=0x7ffd8fa1b8d0, isnulls=isnulls@entry=0x7ffd8fa1b8b0) at 
spgdoinsert.c:2134
#13 0x00005a479de40137 in spginsert (index=0x73625b1f6ce8, values=0x7ffd8fa1b8d0, isnull=0x7ffd8fa1b8b0, 
ht_ctid=0x5a47cbe0b248, heapRel=<optimized out>, checkUnique=<optimized out>, indexUnchanged=false, 
indexInfo=0x5a47cbe0b0b8) at spginsert.c:206
#14 0x00005a479df981d8 in ExecInsertIndexTuples (resultRelInfo=resultRelInfo@entry=0x5a47cbe07120, 
slot=slot@entry=0x5a47cbe0b218, estate=estate@entry=0x5a47cbe06c10, update=update@entry=false, 
noDupErr=noDupErr@entry=false, specConflict=specConflict@entry=0x0, arbiterIndexes=0x0, onlySummarizing=false) at 
execIndexing.c:449
#15 0x00005a479dfcc6a9 in ExecInsert (context=context@entry=0x7ffd8fa1bb70, 
resultRelInfo=resultRelInfo@entry=0x5a47cbe07120, slot=slot@entry=0x5a47cbe0b218, canSetTag=<optimized out>, 
inserted_tuple=inserted_tuple@entry=0x0, insert_destrel=insert_destrel@entry=0x0) at nodeModifyTable.c:1240
#16 0x00005a479dfcdf67 in ExecModifyTable (pstate=0x5a47cbe06f10) at nodeModifyTable.c:4485
...

Best regards,
Alexander

Commits

Same data as JSON: GET /api/v1/messages/:b64id/commits the thread's linked commits as JSON, with link sources. API reference →
  1. bufmgr: Fix ordering of checks in PinBuffer()

  2. Use UnlockReleaseBuffer() in more places

  3. bufmgr: Make UnlockReleaseBuffer() more efficient

  4. bufmgr: Don't copy pages while writing out

  5. Fix use of wrong variable in _hash_kill_items()

  6. Fix bug due to confusion about what IsMVCCSnapshot means

  7. bufmgr: Switch to standard order in MarkBufferDirtyHint()

  8. bufmgr: Remove the, now obsolete, BM_JUST_DIRTIED

  9. Require share-exclusive lock to set hint bits and to flush

  10. heapam: Don't mimic MarkBufferDirtyHint() in inplace updates

  11. bufmgr: Allow conditionally locking of already locked buffer

  12. bufmgr: Avoid spurious compiler warning after fcb9c977aa5

  13. lwlock: Remove ForEachLWLockHeldByMe

  14. lwlock: Remove support for disowned lwlwocks

  15. bufmgr: Implement buffer content locks independently of lwlocks

  16. bufmgr: Change BufferDesc.state to be a 64-bit atomic

  17. lwlock: Improve local variable name

  18. lwlock: Invert meaning of LW_FLAG_RELEASE_OK

  19. bufmgr: Make definitions related to buffer descriptor easier to modify

  20. heapam: Add batch mode mvcc check and use it in page mode

  21. freespace: Don't modify page without any lock

  22. heapam: Move logic to handle HEAP_MOVED into a helper function

  23. bufmgr: Optimize & harmonize LockBufHdr(), LWLockWaitListLock()

  24. bufmgr: Add one-entry cache for private refcount

  25. bufmgr: Separate keys for private refcount infrastructure

  26. Add pg_atomic_unlocked_write_u64

  27. Rename BUFFERPIN wait event class to BUFFER

  28. bufmgr: Turn BUFFER_LOCK_* into an enum

  29. lwlock: Fix, currently harmless, bug in LWLockWakeup()

  30. bufmgr: Use atomic sub for unpinning buffers

  31. bufmgr: Allow some buffer state modifications while holding header lock

  32. bufmgr: Fix valgrind checking for buffers pinned in StrategyGetBuffer()

  33. bufmgr: Don't lock buffer header in StrategyGetBuffer()

  34. bufmgr: fewer calls to BufferDescriptorGetContentLock

  35. bufmgr: Fix signedness of mask variable in BufferSync()

  36. bufmgr: Introduce FlushUnlockedBuffer

  37. Improve ReadRecentBuffer() scalability