]> granicus.if.org Git - postgresql/commitdiff
Fix parallel index scan hang with deleted or half-dead pages.
authorRobert Haas <rhaas@postgresql.org>
Wed, 13 Dec 2017 21:09:00 +0000 (16:09 -0500)
committerRobert Haas <rhaas@postgresql.org>
Wed, 13 Dec 2017 21:09:00 +0000 (16:09 -0500)
The previous coding forgot to release the scan before seizing
it again, leading to a lockup.

Report by Patrick Hemmer.  Diagnosis by Thomas Munro.  Patch by
Amit Kapila.

Discussion: http://postgr.es/m/CAEepm=2xZUcOGP9V0O_G0=2P2wwXwPrkF=upWTCJSisUxMnuSg@mail.gmail.com

src/backend/access/nbtree/nbtsearch.c

index 642c8943e71cb9579dcb5ac642c606348c35ac78..e48d4482d1f1deccda5d8ede1f77236818e2a7d8 100644 (file)
@@ -1486,6 +1486,11 @@ _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno, ScanDirection dir)
                                if (_bt_readpage(scan, dir, P_FIRSTDATAKEY(opaque)))
                                        break;
                        }
+                       else if (scan->parallel_scan != NULL)
+                       {
+                               /* allow next page be processed by parallel worker */
+                               _bt_parallel_release(scan, opaque->btpo_next);
+                       }
 
                        /* nope, keep going */
                        if (scan->parallel_scan != NULL)
@@ -1581,6 +1586,11 @@ _bt_readnextpage(IndexScanDesc scan, BlockNumber blkno, ScanDirection dir)
                                if (_bt_readpage(scan, dir, PageGetMaxOffsetNumber(page)))
                                        break;
                        }
+                       else if (scan->parallel_scan != NULL)
+                       {
+                               /* allow next page be processed by parallel worker */
+                               _bt_parallel_release(scan, BufferGetBlockNumber(so->currPos.buf));
+                       }
 
                        /*
                         * For parallel scans, get the last page scanned as it is quite