Skip to content

Commit d212957

Browse files
committed
Fix bug in bulk extending temp relation after failure
A ResourceOwnerEnlarge() call was missing. That led to an error: ERROR: ResourceOwnerRemember called but array was full and an assertion failure, if you tried to extend a temp relation again after a failure. Alexander's test case used running out of disk space to trigger the original failure. This bug was introduced in the large ResourceOwner rewrite commit b8bff07. Before that, the UnpinLocalBuffer() call guaranteed that the subsequent PinLocalBuffer() will succeed, but after the rewrite, releasing an old resource doesn't guarantee that there is space for a new one. Add a comment explaining why the UnpinBuffer + PinBuffer calls in BufferAlloc(), with no ResourceOwnerEnlarge() in between, are safe. Reported-by: Alexander Lakhin Discussion: https://www.postgresql.org/message-id/dc574fea-c83e-a600-08cd-10881762e4fa@gmail.com
1 parent 7e0ade0 commit d212957

File tree

2 files changed

+11
-1
lines changed

2 files changed

+11
-1
lines changed

src/backend/storage/buffer/localbuf.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,9 @@ ExtendBufferedRelLocal(BufferManagerRelation bmr,
374374
victim_buf_id = -buffers[i] - 1;
375375
victim_buf_hdr = GetLocalBufferDescriptor(victim_buf_id);
376376

377+
/* in case we need to pin an existing buffer below */
378+
ResourceOwnerEnlarge(CurrentResourceOwner);
379+
377380
InitBufferTag(&tag, &bmr.smgr->smgr_rlocator.locator, fork, first_block + i);
378381

379382
hresult = (LocalBufferLookupEnt *)
@@ -646,6 +649,8 @@ InitLocalBuffers(void)
646649
* XXX: We could have a slightly more efficient version of PinLocalBuffer()
647650
* that does not support adjusting the usagecount - but so far it does not
648651
* seem worth the trouble.
652+
*
653+
* Note that ResourceOwnerEnlarge() must have been done already.
649654
*/
650655
bool
651656
PinLocalBuffer(BufferDesc *buf_hdr, bool adjust_usagecount)

src/backend/utils/resowner/resowner.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -548,8 +548,13 @@ ResourceOwnerRemember(ResourceOwner owner, Datum value, const ResourceOwnerDesc
548548
/*
549549
* Forget that an object is owned by a ResourceOwner
550550
*
551-
* Note: if same resource ID is associated with the ResourceOwner more than
551+
* Note: If same resource ID is associated with the ResourceOwner more than
552552
* once, one instance is removed.
553+
*
554+
* Note: Forgetting a resource does not guarantee that there is room to
555+
* remember a new resource. One exception is when you forget the most
556+
* recently remembered resource; that does make room for a new remember call.
557+
* Some code callers rely on that exception.
553558
*/
554559
void
555560
ResourceOwnerForget(ResourceOwner owner, Datum value, const ResourceOwnerDesc *kind)

0 commit comments

Comments
 (0)