@@ -523,7 +523,8 @@ hashbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
523523orig_maxbucket = metap -> hashm_maxbucket ;
524524orig_ntuples = metap -> hashm_ntuples ;
525525memcpy (& local_metapage ,metap ,sizeof (local_metapage ));
526- _hash_relbuf (rel ,metabuf );
526+ /* release the lock, but keep pin */
527+ _hash_chgbufaccess (rel ,metabuf ,HASH_READ ,HASH_NOLOCK );
527528
528529/* Scan the buckets that we know exist */
529530cur_bucket = 0 ;
@@ -563,8 +564,23 @@ hashbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
563564 */
564565if (!H_BUCKET_BEING_SPLIT (bucket_opaque )&&
565566H_NEEDS_SPLIT_CLEANUP (bucket_opaque ))
567+ {
566568split_cleanup = true;
567569
570+ /*
571+ * This bucket might have been split since we last held a lock on
572+ * the metapage. If so, hashm_maxbucket, hashm_highmask and
573+ * hashm_lowmask might be old enough to cause us to fail to remove
574+ * tuples left behind by the most recent split. To prevent that,
575+ * now that the primary page of the target bucket has been locked
576+ * (and thus can't be further split), update our cached metapage
577+ * data.
578+ */
579+ _hash_chgbufaccess (rel ,metabuf ,HASH_NOLOCK ,HASH_READ );
580+ memcpy (& local_metapage ,metap ,sizeof (local_metapage ));
581+ _hash_chgbufaccess (rel ,metabuf ,HASH_READ ,HASH_NOLOCK );
582+ }
583+
568584bucket_buf = buf ;
569585
570586hashbucketcleanup (rel ,cur_bucket ,bucket_buf ,blkno ,info -> strategy ,
@@ -581,15 +597,15 @@ hashbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
581597}
582598
583599/* Write-lock metapage and check for split since we started */
584- metabuf = _hash_getbuf (rel ,HASH_METAPAGE , HASH_WRITE , LH_META_PAGE );
600+ _hash_chgbufaccess (rel ,metabuf , HASH_NOLOCK , HASH_WRITE );
585601metap = HashPageGetMeta (BufferGetPage (metabuf ));
586602
587603if (cur_maxbucket != metap -> hashm_maxbucket )
588604{
589605/* There's been a split, so process the additional bucket(s) */
590606cur_maxbucket = metap -> hashm_maxbucket ;
591607memcpy (& local_metapage ,metap ,sizeof (local_metapage ));
592- _hash_relbuf (rel ,metabuf );
608+ _hash_chgbufaccess (rel ,metabuf , HASH_READ , HASH_NOLOCK );
593609gotoloop_top ;
594610}
595611