mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 15:42:02 +00:00
Change paths of temporary part directories during RESTORE
use "/var/lib/clickhouse/data/test/table/tmp_restore_all_0_1_1_0-XXXXXXXX" instead of "/tmp/XXXXXXXX/data/test/table/0_1_1_0" (because directories can only be renamed in s3_plain_rewritable, and not moved to another parent directory).
This commit is contained in:
parent
a3a4548d96
commit
eb519c5016
@ -58,7 +58,8 @@ TemporaryFileOnDisk::~TemporaryFileOnDisk()
|
||||
|
||||
if (!disk->exists(relative_path))
|
||||
{
|
||||
LOG_WARNING(getLogger("TemporaryFileOnDisk"), "Temporary path '{}' does not exist in '{}'", relative_path, disk->getPath());
|
||||
if (show_warning_if_removed)
|
||||
LOG_WARNING(getLogger("TemporaryFileOnDisk"), "Temporary path '{}' does not exist in '{}'", relative_path, disk->getPath());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -27,12 +27,19 @@ public:
|
||||
/// Return relative path (without disk)
|
||||
const String & getRelativePath() const { return relative_path; }
|
||||
|
||||
/// Sets whether the destructor should show a warning if the temporary file has been already removed.
|
||||
/// By default a warning is shown.
|
||||
void setShowWarningIfRemoved(bool show_warning_if_removed_) { show_warning_if_removed = show_warning_if_removed_; }
|
||||
|
||||
private:
|
||||
DiskPtr disk;
|
||||
|
||||
/// Relative path in disk to the temporary file or directory
|
||||
String relative_path;
|
||||
|
||||
/// Whether the destructor should show a warning if the temporary file has been already removed.
|
||||
bool show_warning_if_removed = true;
|
||||
|
||||
CurrentMetrics::Increment metric_increment;
|
||||
|
||||
/// Specified if we know what for file is used (sort/aggregate/join).
|
||||
|
@ -5549,12 +5549,17 @@ public:
|
||||
attachIfAllPartsRestored();
|
||||
}
|
||||
|
||||
String getTemporaryDirectory(const DiskPtr & disk)
|
||||
String getTemporaryDirectory(const DiskPtr & disk, const String & part_name)
|
||||
{
|
||||
std::lock_guard lock{mutex};
|
||||
auto it = temp_dirs.find(disk);
|
||||
if (it == temp_dirs.end())
|
||||
it = temp_dirs.emplace(disk, std::make_shared<TemporaryFileOnDisk>(disk, "tmp/")).first;
|
||||
auto it = temp_part_dirs.find(part_name);
|
||||
if (it == temp_part_dirs.end())
|
||||
{
|
||||
auto temp_part_dir = std::make_shared<TemporaryFileOnDisk>(disk, fs::path{storage->getRelativeDataPath()} / ("tmp_restore_" + part_name + "-"));
|
||||
/// Attaching parts will rename them so it's expected for a temporary part directory not to exist anymore in the end.
|
||||
temp_part_dir->setShowWarningIfRemoved(false);
|
||||
it = temp_part_dirs.emplace(part_name, temp_part_dir).first;
|
||||
}
|
||||
return it->second->getRelativePath();
|
||||
}
|
||||
|
||||
@ -5572,7 +5577,7 @@ private:
|
||||
|
||||
storage->attachRestoredParts(std::move(parts));
|
||||
parts.clear();
|
||||
temp_dirs.clear();
|
||||
temp_part_dirs.clear();
|
||||
num_parts = 0;
|
||||
}
|
||||
|
||||
@ -5581,7 +5586,7 @@ private:
|
||||
size_t num_parts = 0;
|
||||
size_t num_broken_parts = 0;
|
||||
MutableDataPartsVector parts;
|
||||
std::map<DiskPtr, std::shared_ptr<TemporaryFileOnDisk>> temp_dirs;
|
||||
std::map<String /* part_name*/, std::shared_ptr<TemporaryFileOnDisk>> temp_part_dirs;
|
||||
mutable std::mutex mutex;
|
||||
};
|
||||
|
||||
@ -5648,11 +5653,9 @@ void MergeTreeData::restorePartFromBackup(std::shared_ptr<RestoredPartsHolder> r
|
||||
/// Calculate paths, for example:
|
||||
/// part_name = 0_1_1_0
|
||||
/// part_path_in_backup = /data/test/table/0_1_1_0
|
||||
/// tmp_dir = tmp/1aaaaaa
|
||||
/// tmp_part_dir = tmp/1aaaaaa/data/test/table/0_1_1_0
|
||||
/// temp_part_dir = /var/lib/clickhouse/data/test/table/tmp_restore_all_0_1_1_0-XXXXXXXX
|
||||
auto disk = reservation->getDisk();
|
||||
fs::path temp_dir = restored_parts_holder->getTemporaryDirectory(disk);
|
||||
fs::path temp_part_dir = temp_dir / part_path_in_backup_fs.relative_path();
|
||||
fs::path temp_part_dir = restored_parts_holder->getTemporaryDirectory(disk, part_name);
|
||||
|
||||
/// Subdirectories in the part's directory. It's used to restore projections.
|
||||
std::unordered_set<String> subdirs;
|
||||
@ -5679,22 +5682,25 @@ void MergeTreeData::restorePartFromBackup(std::shared_ptr<RestoredPartsHolder> r
|
||||
reservation->update(reservation->getSize() - file_size);
|
||||
}
|
||||
|
||||
if (auto part = loadPartRestoredFromBackup(disk, temp_part_dir.parent_path(), part_name, detach_if_broken))
|
||||
if (auto part = loadPartRestoredFromBackup(part_name, disk, temp_part_dir, detach_if_broken))
|
||||
restored_parts_holder->addPart(part);
|
||||
else
|
||||
restored_parts_holder->increaseNumBrokenParts();
|
||||
}
|
||||
|
||||
MergeTreeData::MutableDataPartPtr MergeTreeData::loadPartRestoredFromBackup(const DiskPtr & disk, const String & temp_dir, const String & part_name, bool detach_if_broken) const
|
||||
MergeTreeData::MutableDataPartPtr MergeTreeData::loadPartRestoredFromBackup(const String & part_name, const DiskPtr & disk, const String & temp_part_dir, bool detach_if_broken) const
|
||||
{
|
||||
MutableDataPartPtr part;
|
||||
|
||||
auto single_disk_volume = std::make_shared<SingleDiskVolume>(disk->getName(), disk, 0);
|
||||
fs::path full_part_dir{temp_part_dir};
|
||||
String parent_part_dir = full_part_dir.parent_path();
|
||||
String part_dir_name = full_part_dir.filename();
|
||||
|
||||
/// Load this part from the directory `tmp_part_dir`.
|
||||
/// Load this part from the directory `temp_part_dir`.
|
||||
auto load_part = [&]
|
||||
{
|
||||
MergeTreeDataPartBuilder builder(*this, part_name, single_disk_volume, temp_dir, part_name);
|
||||
MergeTreeDataPartBuilder builder(*this, part_name, single_disk_volume, parent_part_dir, part_dir_name);
|
||||
builder.withPartFormatFromDisk();
|
||||
part = std::move(builder).build();
|
||||
part->version.setCreationTID(Tx::PrehistoricTID, nullptr);
|
||||
@ -5709,7 +5715,7 @@ MergeTreeData::MutableDataPartPtr MergeTreeData::loadPartRestoredFromBackup(cons
|
||||
if (!part)
|
||||
{
|
||||
/// Make a fake data part only to copy its files to /detached/.
|
||||
part = MergeTreeDataPartBuilder{*this, part_name, single_disk_volume, temp_dir, part_name}
|
||||
part = MergeTreeDataPartBuilder{*this, part_name, single_disk_volume, parent_part_dir, part_dir_name}
|
||||
.withPartStorageType(MergeTreeDataPartStorageType::Full)
|
||||
.withPartType(MergeTreeDataPartType::Wide)
|
||||
.build();
|
||||
|
@ -1473,7 +1473,7 @@ protected:
|
||||
/// Restores the parts of this table from backup.
|
||||
void restorePartsFromBackup(RestorerFromBackup & restorer, const String & data_path_in_backup, const std::optional<ASTs> & partitions);
|
||||
void restorePartFromBackup(std::shared_ptr<RestoredPartsHolder> restored_parts_holder, const MergeTreePartInfo & part_info, const String & part_path_in_backup, bool detach_if_broken) const;
|
||||
MutableDataPartPtr loadPartRestoredFromBackup(const DiskPtr & disk, const String & temp_dir, const String & part_name, bool detach_if_broken) const;
|
||||
MutableDataPartPtr loadPartRestoredFromBackup(const String & part_name, const DiskPtr & disk, const String & temp_part_dir, bool detach_if_broken) const;
|
||||
|
||||
/// Attaches restored parts to the storage.
|
||||
virtual void attachRestoredParts(MutableDataPartsVector && parts) = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user