diff --git a/src/Storages/MergeTree/IMergeTreeDataPart.h b/src/Storages/MergeTree/IMergeTreeDataPart.h index a8e053a9c7b..0b7a2b44da7 100644 --- a/src/Storages/MergeTree/IMergeTreeDataPart.h +++ b/src/Storages/MergeTree/IMergeTreeDataPart.h @@ -264,6 +264,8 @@ public: /// Some old parts don't have metadata version, so we set it to the current table's version when loading the part bool old_part_with_no_metadata_version_on_disk = false; + bool new_part_was_committed_to_zookeeper_after_rename_on_disk = false; + using TTLInfo = MergeTreeDataPartTTLInfo; using TTLInfos = MergeTreeDataPartTTLInfos; diff --git a/src/Storages/MergeTree/ReplicatedMergeTreeSink.cpp b/src/Storages/MergeTree/ReplicatedMergeTreeSink.cpp index d5b23b14524..72c495191c2 100644 --- a/src/Storages/MergeTree/ReplicatedMergeTreeSink.cpp +++ b/src/Storages/MergeTree/ReplicatedMergeTreeSink.cpp @@ -641,6 +641,27 @@ bool ReplicatedMergeTreeSinkImpl::writeExistingPart(MergeTreeData::Mutabl Stopwatch watch; ProfileEventsScope profile_events_scope; + String original_part_dir = part->getDataPartStorage().getPartDirectory(); + auto try_rollback_part_rename = [this, &part, &original_part_dir]() + { + if (original_part_dir == part->getDataPartStorage().getPartDirectory()) + return; + + if (part->new_part_was_committed_to_zookeeper_after_rename_on_disk) + return; + + /// Probably we have renamed the part on disk, but then failed to commit it to ZK. + /// We should rename it back, otherwise it will be lost (e.g. if it was a part from detached/ and we failed to attach it). + try + { + part->renameTo(original_part_dir, /*remove_new_dir_if_exists*/ false); + } + catch (...) + { + tryLogCurrentException(log); + } + }; + try { part->version.setCreationTID(Tx::PrehistoricTID, nullptr); @@ -654,6 +675,7 @@ bool ReplicatedMergeTreeSinkImpl::writeExistingPart(MergeTreeData::Mutabl } catch (...) { + try_rollback_part_rename(); PartLog::addNewPart(storage.getContext(), PartLog::PartLogEntry(part, watch.elapsed(), profile_events_scope.getSnapshot()), ExecutionStatus::fromCurrentException("", true)); throw; } @@ -1001,6 +1023,7 @@ std::pair, bool> ReplicatedMergeTreeSinkImpl:: Coordination::Error multi_code = zookeeper->tryMultiNoThrow(ops, responses); /// 1 RTT if (multi_code == Coordination::Error::ZOK) { + part->new_part_was_committed_to_zookeeper_after_rename_on_disk = true; transaction.commit(); storage.merge_selecting_task->schedule();