mirror of
https://github.com/postgres/postgres.git
synced 2026-10-23 13:29:09 +03:00
Initialize read stream before fetching metapage in hash bulk-deletion
hashbulkdelete() fetched the relcache's cached hash metapage before
calling read_stream_begin_relation(). During the read stream
initialization, relation lookups may process pending relcache
invalidation messages, which could cause the cached metapage to be
invalidated before the read stream uses it, leading to the failure of a
VACUUM bulk-deletion for a hash index.
This commit reworks the order of hashbulkdelete() so as its read stream
is initialized before fetching the cached metapage, so as pending
invalidation messages do not interfere with the relation scan.
Issue introduced by bfa3c4f106.
Author: Mikhail Nikalayeu <mihailnikalayeu@gmail.com>
Reviewed-by: Bertrand Drouvot <bertranddrouvot.pg@gmail.com>
Reviewed-by: Nazir Bilal Yavuz <byavuz81@gmail.com>
Reviewed-by: Xuneng Zhou <xunengzhou@gmail.com>
Discussion: https://postgr.es/m/CADzfLwVEJ2_7ioX3ZSB1P7qXW40ghUy_ZCzeFvhDLoa_3Muztg@mail.gmail.com
Backpatch-through: 19
This commit is contained in:
@@ -515,6 +515,21 @@ hashbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
|
||||
tuples_removed = 0;
|
||||
num_index_tuples = 0;
|
||||
|
||||
/*
|
||||
* Set up the streaming read before fetching the cached metapage as read
|
||||
* stream initialization may process relcache invalidation messages,
|
||||
* invalidating the cached metapage. It is safe to use batchmode as
|
||||
* hash_bulkdelete_read_stream_cb takes no locks.
|
||||
*/
|
||||
stream = read_stream_begin_relation(READ_STREAM_MAINTENANCE |
|
||||
READ_STREAM_USE_BATCHING,
|
||||
info->strategy,
|
||||
rel,
|
||||
MAIN_FORKNUM,
|
||||
hash_bulkdelete_read_stream_cb,
|
||||
&stream_private,
|
||||
0);
|
||||
|
||||
/*
|
||||
* We need a copy of the metapage so that we can use its hashm_spares[]
|
||||
* values to compute bucket page addresses, but a cached copy should be
|
||||
@@ -536,19 +551,6 @@ hashbulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
|
||||
stream_private.next_bucket = cur_bucket;
|
||||
stream_private.max_bucket = cur_maxbucket;
|
||||
|
||||
/*
|
||||
* It is safe to use batchmode as hash_bulkdelete_read_stream_cb takes no
|
||||
* locks.
|
||||
*/
|
||||
stream = read_stream_begin_relation(READ_STREAM_MAINTENANCE |
|
||||
READ_STREAM_USE_BATCHING,
|
||||
info->strategy,
|
||||
rel,
|
||||
MAIN_FORKNUM,
|
||||
hash_bulkdelete_read_stream_cb,
|
||||
&stream_private,
|
||||
0);
|
||||
|
||||
bucket_loop:
|
||||
while (cur_bucket <= cur_maxbucket)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user