diff --git a/src/backend/storage/ipc/dht.c b/src/backend/storage/ipc/dht.c index 1fc6aa1..c0f68fc 100644 --- a/src/backend/storage/ipc/dht.c +++ b/src/backend/storage/ipc/dht.c @@ -73,6 +73,12 @@ struct dht_hash_table_item /* A magic value used to identify DHT hash tables. */ #define DHT_MAGIC 0x75ff6a20 +/* Resize cleanup operations per insert in dht_release(exclusive). */ +#define DHT_INSERT_CLEANS 3 + +/* Resize cleanup operations per find in dht_release(shared). */ +#define DHT_SEARCH_CLEANS 2 + /* * Tracking information for each lock partition. Initially, each partition * corresponds to one bucket, but each time the hash table grows, the buckets @@ -613,21 +619,40 @@ dht_release(dht_hash_table *hash_table, void *entry) * already hold a lock, but if not, we'll make a note to search other lock * partitions after releasing the lock we currently hold. */ - if (RESIZE_IN_PROGRESS(hash_table) && hash_table->exclusively_locked) + if (RESIZE_IN_PROGRESS(hash_table)) { - dht_partition *partition; + if (hash_table->exclusively_locked) + { + dht_partition *partition; - partition = &hash_table->control->partitions[partition_index]; + partition = &hash_table->control->partitions[partition_index]; - if (partition->old_count > 0) - { - /* Do some resizing work in this partition. */ - do_incremental_resize(hash_table, partition_index); + if (partition->old_count > 0) + { + /* Do some resizing work in this partition. */ + int ii = 0; + + while (true) + { + /* We always do at least one. */ + do_incremental_resize(hash_table, partition_index); + if (partition->old_count <= 0) + break; + ii++; + if (ii >= DHT_INSERT_CLEANS) + break; + } + } + else + { + /* Nothing left to do in this partition. Look elsewhere. */ + deferred_resize_work = true; + } } else { - /* Nothing left to do in this partition. Look elsewhere. */ - deferred_resize_work = true; + /* Do cleanups after dht_find() ... dht_release() */ + deferred_resize_work = (DHT_SEARCH_CLEANS > 0); } } @@ -636,8 +661,9 @@ dht_release(dht_hash_table *hash_table, void *entry) /* * If we need to contribute some work to the ongoing resize effort, and we - * didn't find something to migrate in our own partition, go search for - * such work in other partitions. We'll start with the one after ours. + * didn't find something to migrate in our own partition under exclusive + * lock, go search for such work in other partitions. We'll start with + * the one after ours. */ if (deferred_resize_work) search_for_resize_work(hash_table, @@ -1240,7 +1266,18 @@ search_for_resize_work(dht_hash_table *hash_table, int start_partition) else if (partition->old_count > 0) { /* There is in fact work to be done in this partition. */ - do_incremental_resize(hash_table, i); + int ii = 0; + + while (true) + { + /* We always do at least one. */ + do_incremental_resize(hash_table, i); + if (partition->old_count <= 0) + break; + ii++; + if (ii >= DHT_SEARCH_CLEANS) + break; + } done = true; } LWLockRelease(PARTITION_LOCK(hash_table, i));