]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Properly acquire buffer lock for page-at-a-time hash vacuum.
authorRobert Haas <rhaas@postgresql.org>
Tue, 4 Apr 2017 02:24:17 +0000 (22:24 -0400)
committerRobert Haas <rhaas@postgresql.org>
Tue, 4 Apr 2017 02:26:06 +0000 (22:26 -0400)
In a couple of places, _hash_kill_items was mistakenly called with
the buffer lock not held.  Repair.

Ashutosh Sharma, per a report from Andreas Seltenreich

Discussion: http://postgr.es/m/87o9wo8o0j.fsf@credativ.de

src/backend/access/hash/hash.c

index 34cc08f12d2fcb39b3bb555bce359864e3e1c25f..b835f772d46aaec5c43729b924ae64a88bff132a 100644 (file)
@@ -476,9 +476,17 @@ hashrescan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
        HashScanOpaque so = (HashScanOpaque) scan->opaque;
        Relation        rel = scan->indexRelation;
 
-       /* Before leaving current page, deal with any killed items */
+       /*
+        * Before leaving current page, deal with any killed items.
+        * Also, ensure that we acquire lock on current page before
+        * calling _hash_kill_items.
+        */
        if (so->numKilled > 0)
+       {
+               LockBuffer(so->hashso_curbuf, BUFFER_LOCK_SHARE);
                _hash_kill_items(scan);
+               LockBuffer(so->hashso_curbuf, BUFFER_LOCK_UNLOCK);
+       }
 
        _hash_dropscanbuf(rel, so);
 
@@ -507,9 +515,17 @@ hashendscan(IndexScanDesc scan)
        HashScanOpaque so = (HashScanOpaque) scan->opaque;
        Relation        rel = scan->indexRelation;
 
-       /* Before leaving current page, deal with any killed items */
+       /*
+        * Before leaving current page, deal with any killed items.
+        * Also, ensure that we acquire lock on current page before
+        * calling _hash_kill_items.
+        */
        if (so->numKilled > 0)
+       {
+               LockBuffer(so->hashso_curbuf, BUFFER_LOCK_SHARE);
                _hash_kill_items(scan);
+               LockBuffer(so->hashso_curbuf, BUFFER_LOCK_UNLOCK);
+       }
 
        _hash_dropscanbuf(rel, so);