lock-order.patch

application/octet-stream

Filename: lock-order.patch
Type: application/octet-stream
Part: 0
Message: Re: possible deadlock: different lock ordering for heap pages

Patch

Format: format-patch
Subject: possible deadlock locking multiple heap pages
File+
src/backend/access/heap/hio.c 2 2
From 870e2520aa7b9881e2619d85fa46bac8a27817e4 Mon Sep 17 00:00:00 2001
From: Fnu Nishant <nishantf@amazon.com>
Date: Mon, 28 Jan 2019 19:48:47 +0000
Subject: [PATCH] possible deadlock locking multiple heap pages

To avoid deadlock, Postgres backend acquire lock on heap pages in
blockid order. In certain cases, lock on heap pages are dropped and
reacquired. In this case the locks are dropped for reading in
corresponding VM page/s. The bug is we re-acquire locks in bufferId
order where as the intention was to acquire in blockid order. Post this
patch we will always acquire locks in blockid order.
---
 src/backend/access/heap/hio.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c
index 3da0b49ccc..98dfca6cc9 100644
--- a/src/backend/access/heap/hio.c
+++ b/src/backend/access/heap/hio.c
@@ -127,7 +127,7 @@ GetVisibilityMapPins(Relation relation, Buffer buffer1, Buffer buffer2,
 	bool		need_to_pin_buffer2;
 
 	Assert(BufferIsValid(buffer1));
-	Assert(buffer2 == InvalidBuffer || buffer1 <= buffer2);
+	Assert(buffer2 == InvalidBuffer || block1 <= block2);
 
 	while (1)
 	{
@@ -465,7 +465,7 @@ loop:
 		 * done a bit of extra work for no gain, but there's no real harm
 		 * done.
 		 */
-		if (otherBuffer == InvalidBuffer || buffer <= otherBuffer)
+		if (otherBuffer == InvalidBuffer || targetBlock <= otherBlock)
 			GetVisibilityMapPins(relation, buffer, otherBuffer,
 								 targetBlock, otherBlock, vmbuffer,
 								 vmbuffer_other);
-- 
2.15.3.AMZN