Skip to content

Commit bba9003

Browse files
committed
hio: Relax rules for calling GetVisibilityMapPins()
GetVisibilityMapPins() insisted on the buffer1/buffer2 being in a specific order. This required checks at the callsite. As a subsequent patch will add another callsite, move related logic into GetVisibilityMapPins(). Discussion: https://postgr.es/m/20230403190030.fk2frxv6faklrseb@awork3.anarazel.de
1 parent 00beecf commit bba9003

File tree

1 file changed

+26
-11
lines changed
  • src/backend/access/heap

1 file changed

+26
-11
lines changed

src/backend/access/heap/hio.c

Lines changed: 26 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,9 @@ ReadBufferBI(Relation relation, BlockNumber targetBlock,
131131
* For each heap page which is all-visible, acquire a pin on the appropriate
132132
* visibility map page, if we haven't already got one.
133133
*
134-
* buffer2 may be InvalidBuffer, if only one buffer is involved. buffer1
135-
* must not be InvalidBuffer. If both buffers are specified, block1 must
136-
* be less than block2.
134+
* To avoid complexity in the callers, either buffer1 or buffer2 may be
135+
* InvalidBuffer if only one buffer is involved. For the same reason, block2
136+
* may be smaller than block1.
137137
*/
138138
static void
139139
GetVisibilityMapPins(Relation relation, Buffer buffer1, Buffer buffer2,
@@ -143,6 +143,26 @@ GetVisibilityMapPins(Relation relation, Buffer buffer1, Buffer buffer2,
143143
bool need_to_pin_buffer1;
144144
bool need_to_pin_buffer2;
145145

146+
/*
147+
* Swap buffers around to handle case of a single block/buffer, and to
148+
* handle if lock ordering rules require to lock block2 first.
149+
*/
150+
if (!BufferIsValid(buffer1) ||
151+
(BufferIsValid(buffer2) && block1 > block2))
152+
{
153+
Buffer tmpbuf = buffer1;
154+
Buffer *tmpvmbuf = vmbuffer1;
155+
BlockNumber tmpblock = block1;
156+
157+
buffer1 = buffer2;
158+
vmbuffer1 = vmbuffer2;
159+
block1 = block2;
160+
161+
buffer2 = tmpbuf;
162+
vmbuffer2 = tmpvmbuf;
163+
block2 = tmpblock;
164+
}
165+
146166
Assert(BufferIsValid(buffer1));
147167
Assert(buffer2 == InvalidBuffer || block1 <= block2);
148168

@@ -502,14 +522,9 @@ RelationGetBufferForTuple(Relation relation, Size len,
502522
* done a bit of extra work for no gain, but there's no real harm
503523
* done.
504524
*/
505-
if (otherBuffer == InvalidBuffer || targetBlock <= otherBlock)
506-
GetVisibilityMapPins(relation, buffer, otherBuffer,
507-
targetBlock, otherBlock, vmbuffer,
508-
vmbuffer_other);
509-
else
510-
GetVisibilityMapPins(relation, otherBuffer, buffer,
511-
otherBlock, targetBlock, vmbuffer_other,
512-
vmbuffer);
525+
GetVisibilityMapPins(relation, buffer, otherBuffer,
526+
targetBlock, otherBlock, vmbuffer,
527+
vmbuffer_other);
513528

514529
/*
515530
* Now we can check to see if there's enough free space here. If so,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy