I wrote a test for  `PART MOVE TO SHARD` runs multiple times and received some unexpected behavior.

**Test description:**
1) Create a table
2) Make 2 rows insert on one shard and 1 row insert on some other
3) Stop Merges
4) Create Distributed table
5) Receive part UUID
6) Move this part multiple times
7) Make concurrent check on the number of rows

**How to reproduce**
1) CREATE TABLE IF NOT EXISTS {table_name} on CLUSTER {cluster_name}
                                                (v UInt64) "
                                                ENGINE = {table_engine}('/clickhouse/tables/replicated/{shard}/{table_name}', '{replica}') 
                                                ORDER BY tuple() 
                                                SETTINGS assign_part_uuids=1,
                                                part_moves_between_shards_enable=1,
                                                part_moves_between_shards_delay_seconds=2;

2) INSERT INTO {table_name} VALUES ({value}) - 2 rows  on one shard and 1 row on some other

3) SYSTEM STOP MERGES {table_name} - on all nodes

4) CREATE TABLE IF NOT EXISTS {table_name_d} as {table_name} 
                                                    ENGINE = Distributed({cluster_name}, currentDatabase(), {table_name})
5) SELECT uuid FROM system.parts where name = 'all_0_0_0'

6) SELECT name FROM system.parts where uuid = '{part_uuid}'
    ALTER TABLE {table_name} MOVE PART name TO SHARD '/clickhouse/tables/replicated/{shard1}/{table_name}' - multiple times

7) select count() from {table_name_d}

* ClickHouse server version to use
22.1.2
* Queries to run that lead to an unexpected result
select count() from {table_name_d}

Result: 4

**Expected behavior**
Result: 3

**Additional information**
If make retries some time result becomes correct. The test gives the correct result if put part_moves_between_shards_delay_seconds=0.

* 1. In different threads read from the remote servers blocks.
      * Save all the blocks in the RAM. Merge blocks.
      * If the aggregation is two-level - parallelize to the number of buckets.
      *
      * 2. In one thread, read blocks from different servers in order.
      * RAM stores only one block from each server.
      * If the aggregation is a two-level aggregation, we consistently merge the blocks of each next level.
      *
      * The second option consumes less memory (up to 256 times less)
      *  in the case of two-level aggregation, which is used for large results after GROUP BY,
      *  but it can work more slowly.
      */
    Aggregator::Params params(header_before_merge, keys, aggregates, overflow_row, settings.max_threads);
    auto transform_params = std::make_shared<AggregatingTransformParams>(params, final);
    auto merging_aggregated = std::make_unique<MergingAggregatedStep>(
        query_plan.getCurrentDataStream(),
        std::move(transform_params),
        settings.distributed_aggregation_memory_efficient && is_remote_storage,
        settings.max_threads,
        settings.aggregation_memory_efficient_merge_threads);
    query_plan.addStep(std::move(merging_aggregated));
}
void InterpreterSelectQuery::addEmptySourceToQueryPlan(
    QueryPlan & query_plan, const Block & source_header, const SelectQueryInfo & query_info, ContextPtr context_)
{
    Pipe pipe(std::make_shared<NullSource>(source_header));
    PrewhereInfoPtr prewhere_info_ptr = query_info.projection ? query_info.projection->prewhere_info : query_info.prewhere_info;
    if (prewhere_info_ptr)
    {
        auto & prewhere_info = *prewhere_info_ptr;