From 4b97fd15fb497d2810a29cd30bfacd89400b596c Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 21 Oct 2026 23:40:46 +0900 Subject: [PATCH] Report shared buffer exhaustion as insufficient resources When all shared buffers examined are pinned, a query can fail with "no unpinned buffers available". This can happen when shared_buffers is too small for the workload, but the error was reported as an internal error, making a resource shortage look like a server bug. Replace elog() with ereport() to report this condition with SQLSTATE 53000 (insufficient_resources) instead of XX000 (internal_error), matching the corresponding local-buffer error. Reword both messages to clarify whether shared or local buffers are involved. Author: Ma Xueting Reviewed-by: Pierre Forstmann Reviewed-by: Matthias van de Meent Reviewed-by: solai v Reviewed-by: Fujii Masao Discussion: https://postgr.es/m/TYWP286MB2571C92032EE9D1B8F2BFACFEF812@TYWP286MB2571.JPNP286.PROD.OUTLOOK.COM --- src/backend/storage/buffer/freelist.c | 4 +++- src/backend/storage/buffer/localbuf.c | 2 +- src/test/regress/expected/temp.out | 4 ++-- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/backend/storage/buffer/freelist.c b/src/backend/storage/buffer/freelist.c index fdb5bad7910..9971287aff6 100644 --- a/src/backend/storage/buffer/freelist.c +++ b/src/backend/storage/buffer/freelist.c @@ -271,7 +271,9 @@ StrategyGetBuffer(BufferAccessStrategy strategy, uint64 *buf_state, bool *from_r * one eventually, but it's probably better to fail than * to risk getting stuck in an infinite loop. */ - elog(ERROR, "no unpinned buffers available"); + ereport(ERROR, + errcode(ERRCODE_INSUFFICIENT_RESOURCES), + errmsg("could not find an unpinned shared buffer")); } break; } diff --git a/src/backend/storage/buffer/localbuf.c b/src/backend/storage/buffer/localbuf.c index 4870c8e13d0..dd5351552d1 100644 --- a/src/backend/storage/buffer/localbuf.c +++ b/src/backend/storage/buffer/localbuf.c @@ -271,7 +271,7 @@ GetLocalVictimBuffer(void) else if (--trycounter == 0) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_RESOURCES), - errmsg("no empty local buffer available"))); + errmsg("could not find an unpinned local buffer"))); } /* diff --git a/src/test/regress/expected/temp.out b/src/test/regress/expected/temp.out index bd4653aed27..e6f14b5f5b8 100644 --- a/src/test/regress/expected/temp.out +++ b/src/test/regress/expected/temp.out @@ -456,7 +456,7 @@ SELECT test_temp_pin(0, 9); -- should fail, too many buffers pinned SELECT test_temp_pin(10, 105); -ERROR: no empty local buffer available +ERROR: could not find an unpinned local buffer ROLLBACK; BEGIN; -- have some working cursors to test after errors @@ -475,7 +475,7 @@ FETCH NEXT FROM c_3; -- exhaust buffer pins in subtrans, check things work after SAVEPOINT rescue_me; SELECT test_temp_pin(10, 105); -ERROR: no empty local buffer available +ERROR: could not find an unpinned local buffer ROLLBACK TO SAVEPOINT rescue_me; -- pre-subtrans cursors continue to work FETCH NEXT FROM c_3;