@@ -4053,6 +4053,7 @@ Pipe StorageReplicatedMergeTree::alterPartition(
40534053
40544054
40554055// / If new version returns ordinary name, else returns part name containing the first and last month of the month
4056+ // / NOTE: use it in pair with getFakePartCoveringAllPartsInPartition(...)
40564057static String getPartNamePossiblyFake (MergeTreeDataFormatVersion format_version, const MergeTreePartInfo & part_info)
40574058{
40584059 if (format_version < MERGE_TREE_DATA_MIN_FORMAT_VERSION_WITH_CUSTOM_PARTITIONING)
@@ -4068,7 +4069,7 @@ static String getPartNamePossiblyFake(MergeTreeDataFormatVersion format_version,
40684069 return part_info.getPartName ();
40694070}
40704071
4071- bool StorageReplicatedMergeTree::getFakePartCoveringAllPartsInPartition (const String & partition_id, MergeTreePartInfo & part_info)
4072+ bool StorageReplicatedMergeTree::getFakePartCoveringAllPartsInPartition (const String & partition_id, MergeTreePartInfo & part_info, bool for_replace_partition )
40724073{
40734074 // / Even if there is no data in the partition, you still need to mark the range for deletion.
40744075 // / - Because before executing DETACH, tasks for downloading parts to this partition can be executed.
@@ -4091,14 +4092,21 @@ bool StorageReplicatedMergeTree::getFakePartCoveringAllPartsInPartition(const St
40914092 mutation_version = queue.getCurrentMutationVersion (partition_id, right);
40924093 }
40934094
4094- // / Empty partition.
4095- if (right == 0 )
4096- return false ;
4095+ // / REPLACE PARTITION uses different max level and does not decrement max_block of DROP_RANGE for unknown (probably historical) reason.
4096+ auto max_level = std::numeric_limits<decltype (part_info.level )>::max ();
4097+ if (!for_replace_partition)
4098+ {
4099+ max_level = MergeTreePartInfo::MAX_LEVEL;
4100+
4101+ // / Empty partition.
4102+ if (right == 0 )
4103+ return false ;
40974104
4098- --right;
4105+ --right;
4106+ }
40994107
41004108 // / Artificial high level is chosen, to make this part "covering" all parts inside.
4101- part_info = MergeTreePartInfo (partition_id, left, right, MergeTreePartInfo::MAX_LEVEL , mutation_version);
4109+ part_info = MergeTreePartInfo (partition_id, left, right, max_level , mutation_version);
41024110 return true ;
41034111}
41044112
@@ -5305,11 +5313,11 @@ void StorageReplicatedMergeTree::replacePartitionFrom(
53055313 // / Firstly, generate last block number and compute drop_range
53065314 // / NOTE: Even if we make ATTACH PARTITION instead of REPLACE PARTITION drop_range will not be empty, it will contain a block.
53075315 // / So, such case has special meaning, if drop_range contains only one block it means that nothing to drop.
5316+ // / TODO why not to add normal DROP_RANGE entry to replication queue if `replace` is true?
53085317 MergeTreePartInfo drop_range;
5309- drop_range.partition_id = partition_id;
5310- drop_range.max_block = allocateBlockNumber (partition_id, zookeeper)->getNumber ();
5311- drop_range.min_block = replace ? 0 : drop_range.max_block ;
5312- drop_range.level = std::numeric_limits<decltype (drop_range.level )>::max ();
5318+ getFakePartCoveringAllPartsInPartition (partition_id, drop_range, true );
5319+ if (!replace)
5320+ drop_range.min_block = drop_range.max_block ;
53135321
53145322 String drop_range_fake_part_name = getPartNamePossiblyFake (format_version, drop_range);
53155323
@@ -5388,6 +5396,7 @@ void StorageReplicatedMergeTree::replacePartitionFrom(
53885396 }
53895397
53905398 // / We are almost ready to commit changes, remove fetches and merges from drop range
5399+ // / FIXME it's unsafe to remove queue entries before we actually commit REPLACE_RANGE to replication log
53915400 queue.removePartProducingOpsInRange (zookeeper, drop_range, entry);
53925401
53935402 // / Remove deduplication block_ids of replacing parts
@@ -5502,11 +5511,7 @@ void StorageReplicatedMergeTree::movePartitionToTable(const StoragePtr & dest_ta
55025511 // / A range for log entry to remove parts from the source table (myself).
55035512
55045513 MergeTreePartInfo drop_range;
5505- drop_range.partition_id = partition_id;
5506- drop_range.max_block = allocateBlockNumber (partition_id, zookeeper)->getNumber ();
5507- drop_range.min_block = 0 ;
5508- drop_range.level = std::numeric_limits<decltype (drop_range.level )>::max ();
5509-
5514+ getFakePartCoveringAllPartsInPartition (partition_id, drop_range, true );
55105515 String drop_range_fake_part_name = getPartNamePossiblyFake (format_version, drop_range);
55115516
55125517 if (drop_range.getBlocksCount () > 1 )
@@ -5561,6 +5566,7 @@ void StorageReplicatedMergeTree::movePartitionToTable(const StoragePtr & dest_ta
55615566 drop_range_dest.max_block = drop_range.max_block ;
55625567 drop_range_dest.min_block = drop_range.max_block ;
55635568 drop_range_dest.level = drop_range.level ;
5569+ drop_range_dest.mutation = drop_range.mutation ;
55645570
55655571 entry.type = ReplicatedMergeTreeLogEntryData::REPLACE_RANGE;
55665572 entry.source_replica = dest_table_storage->replica_name ;
0 commit comments