Skip to content

Commit 0b8bdb3

Browse files
author
Amit Kapila
committed
Avoid possible deadlock while locking multiple heap pages.
To avoid deadlock, backend acquires a lock on heap pages in block number order. In certain cases, lock on heap pages is dropped and reacquired. In this case, the locks are dropped for reading in corresponding VM page/s. The issue is we re-acquire locks in bufferId order whereas the intention was to acquire in blockid order. This commit ensures that we will always acquire locks on heap pages in blockid order. Reported-by: Nishant Fnu Author: Nishant Fnu Reviewed-by: Amit Kapila and Robert Haas Backpatch-through: 9.4 Discussion: https://postgr.es/m/5883C831-2ED1-47C8-BFAC-2D5BAE5A8CAE@amazon.com
1 parent 3e938a8 commit 0b8bdb3

File tree

1 file changed

+4
-4
lines changed
  • src/backend/access/heap

1 file changed

+4
-4
lines changed

src/backend/access/heap/hio.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ ReadBufferBI(Relation relation, BlockNumber targetBlock,
115115
* visibility map page, if we haven't already got one.
116116
*
117117
* buffer2 may be InvalidBuffer, if only one buffer is involved. buffer1
118-
* must not be InvalidBuffer. If both buffers are specified, buffer1 must
119-
* be less than buffer2.
118+
* must not be InvalidBuffer. If both buffers are specified, block1 must
119+
* be less than block2.
120120
*/
121121
static void
122122
GetVisibilityMapPins(Relation relation, Buffer buffer1, Buffer buffer2,
@@ -127,7 +127,7 @@ GetVisibilityMapPins(Relation relation, Buffer buffer1, Buffer buffer2,
127127
bool need_to_pin_buffer2;
128128

129129
Assert(BufferIsValid(buffer1));
130-
Assert(buffer2 == InvalidBuffer || buffer1 <= buffer2);
130+
Assert(buffer2 == InvalidBuffer || block1 <= block2);
131131

132132
while (1)
133133
{
@@ -465,7 +465,7 @@ RelationGetBufferForTuple(Relation relation, Size len,
465465
* done a bit of extra work for no gain, but there's no real harm
466466
* done.
467467
*/
468-
if (otherBuffer == InvalidBuffer || buffer <= otherBuffer)
468+
if (otherBuffer == InvalidBuffer || targetBlock <= otherBlock)
469469
GetVisibilityMapPins(relation, buffer, otherBuffer,
470470
targetBlock, otherBlock, vmbuffer,
471471
vmbuffer_other);

0 commit comments

Comments
 (0)