From 3a9738e9729445c29e44bb319af3ab7bca2983a0 Mon Sep 17 00:00:00 2001 From: Andres Freund Date: Wed, 27 Jun 2018 12:14:58 -0700 Subject: [PATCH] Check for interrupts inside nbtree page deletion code. Author: Reviewed-By: Discussion: https://postgr.es/m/ Backpatch: --- src/backend/access/nbtree/nbtpage.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/backend/access/nbtree/nbtpage.c b/src/backend/access/nbtree/nbtpage.c index a24e64156ab..6e395199d55 100644 --- a/src/backend/access/nbtree/nbtpage.c +++ b/src/backend/access/nbtree/nbtpage.c @@ -1443,6 +1443,7 @@ _bt_pagedel(Relation rel, Buffer buf) rightsib_empty = false; while (P_ISHALFDEAD(opaque)) { + /* will check for interrupts, once lock is released */ if (!_bt_unlink_halfdead_page(rel, buf, &rightsib_empty)) { /* _bt_unlink_halfdead_page already released buffer */ @@ -1455,6 +1456,12 @@ _bt_pagedel(Relation rel, Buffer buf) _bt_relbuf(rel, buf); + /* + * Check here, as calling loops will have locks held, preventing + * interrupts from being processed. + */ + CHECK_FOR_INTERRUPTS(); + /* * The page has now been deleted. If its right sibling is completely * empty, it's possible that the reason we haven't deleted it earlier @@ -1707,6 +1714,12 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, bool *rightsib_empty) LockBuffer(leafbuf, BUFFER_LOCK_UNLOCK); + /* + * Check here, as calling loops will have locks held, preventing + * interrupts from being processed. + */ + CHECK_FOR_INTERRUPTS(); + /* * If the leaf page still has a parent pointing to it (or a chain of * parents), we don't unlink the leaf page yet, but the topmost remaining @@ -1766,6 +1779,13 @@ _bt_unlink_halfdead_page(Relation rel, Buffer leafbuf, bool *rightsib_empty) /* step right one page */ leftsib = opaque->btpo_next; _bt_relbuf(rel, lbuf); + + /* + * It'd be good to check for interrupts here, but it's not + * entirely trivial to do so because a lock is always held. As the + * code is presently unreachable... + */ + if (leftsib == P_NONE) { elog(LOG, "no left sibling (concurrent deletion?) of block %u in \"%s\"", -- 2.18.0.rc2.dirty