2022-04-19 18:15:27 +00:00
|
|
|
#include <Backups/BackupCoordinationLocal.h>
|
2022-05-08 21:41:49 +00:00
|
|
|
#include <Common/Exception.h>
|
|
|
|
#include <Common/logger_useful.h>
|
2022-04-17 12:11:43 +00:00
|
|
|
#include <fmt/format.h>
|
|
|
|
|
|
|
|
|
|
|
|
namespace DB
|
|
|
|
{
|
2022-05-08 21:41:49 +00:00
|
|
|
|
2022-04-19 09:02:34 +00:00
|
|
|
using SizeAndChecksum = IBackupCoordination::SizeAndChecksum;
|
2022-04-17 12:11:43 +00:00
|
|
|
using FileInfo = IBackupCoordination::FileInfo;
|
|
|
|
|
2022-05-31 09:33:23 +00:00
|
|
|
BackupCoordinationLocal::BackupCoordinationLocal() = default;
|
|
|
|
BackupCoordinationLocal::~BackupCoordinationLocal() = default;
|
|
|
|
|
2022-07-20 19:44:51 +00:00
|
|
|
void BackupCoordinationLocal::setStage(const String &, const String &, const String &)
|
2022-05-08 21:41:49 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-07-20 19:44:51 +00:00
|
|
|
void BackupCoordinationLocal::setError(const String &, const Exception &)
|
2022-07-08 20:13:27 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2022-07-20 19:44:51 +00:00
|
|
|
Strings BackupCoordinationLocal::waitForStage(const Strings &, const String &)
|
2022-06-23 17:45:36 +00:00
|
|
|
{
|
2022-06-23 18:49:44 +00:00
|
|
|
return {};
|
2022-06-23 17:45:36 +00:00
|
|
|
}
|
|
|
|
|
2022-07-20 19:44:51 +00:00
|
|
|
Strings BackupCoordinationLocal::waitForStage(const Strings &, const String &, std::chrono::milliseconds)
|
2022-05-31 09:33:23 +00:00
|
|
|
{
|
2022-06-23 18:49:44 +00:00
|
|
|
return {};
|
2022-05-31 09:33:23 +00:00
|
|
|
}
|
2022-04-17 12:11:43 +00:00
|
|
|
|
2022-06-24 19:29:38 +00:00
|
|
|
void BackupCoordinationLocal::addReplicatedPartNames(const String & table_shared_id, const String & table_name_for_logs, const String & replica_name, const std::vector<PartNameAndChecksum> & part_names_and_checksums)
|
2022-05-08 21:41:49 +00:00
|
|
|
{
|
|
|
|
std::lock_guard lock{mutex};
|
2022-07-06 09:09:31 +00:00
|
|
|
replicated_tables.addPartNames(table_shared_id, table_name_for_logs, replica_name, part_names_and_checksums);
|
2022-05-08 21:41:49 +00:00
|
|
|
}
|
|
|
|
|
2022-06-24 19:29:38 +00:00
|
|
|
Strings BackupCoordinationLocal::getReplicatedPartNames(const String & table_shared_id, const String & replica_name) const
|
2022-05-08 21:41:49 +00:00
|
|
|
{
|
|
|
|
std::lock_guard lock{mutex};
|
2022-07-06 09:09:31 +00:00
|
|
|
return replicated_tables.getPartNames(table_shared_id, replica_name);
|
2022-07-05 07:39:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void BackupCoordinationLocal::addReplicatedMutations(const String & table_shared_id, const String & table_name_for_logs, const String & replica_name, const std::vector<MutationInfo> & mutations)
|
|
|
|
{
|
|
|
|
std::lock_guard lock{mutex};
|
2022-07-06 09:09:31 +00:00
|
|
|
replicated_tables.addMutations(table_shared_id, table_name_for_logs, replica_name, mutations);
|
2022-07-05 07:39:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<IBackupCoordination::MutationInfo> BackupCoordinationLocal::getReplicatedMutations(const String & table_shared_id, const String & replica_name) const
|
|
|
|
{
|
|
|
|
std::lock_guard lock{mutex};
|
2022-07-06 09:09:31 +00:00
|
|
|
return replicated_tables.getMutations(table_shared_id, replica_name);
|
2022-05-23 12:05:35 +00:00
|
|
|
}
|
|
|
|
|
2022-05-29 19:53:56 +00:00
|
|
|
|
2022-06-24 19:29:38 +00:00
|
|
|
void BackupCoordinationLocal::addReplicatedDataPath(const String & table_shared_id, const String & data_path)
|
2022-05-23 12:05:35 +00:00
|
|
|
{
|
|
|
|
std::lock_guard lock{mutex};
|
2022-07-06 09:09:31 +00:00
|
|
|
replicated_tables.addDataPath(table_shared_id, data_path);
|
2022-05-08 21:41:49 +00:00
|
|
|
}
|
|
|
|
|
2022-06-24 19:29:38 +00:00
|
|
|
Strings BackupCoordinationLocal::getReplicatedDataPaths(const String & table_shared_id) const
|
2022-05-08 21:41:49 +00:00
|
|
|
{
|
2022-05-29 19:53:56 +00:00
|
|
|
std::lock_guard lock{mutex};
|
2022-07-06 09:09:31 +00:00
|
|
|
return replicated_tables.getDataPaths(table_shared_id);
|
2022-05-08 21:41:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-07-05 18:57:01 +00:00
|
|
|
void BackupCoordinationLocal::addReplicatedAccessFilePath(const String & access_zk_path, AccessEntityType access_entity_type, const String & host_id, const String & file_path)
|
2022-06-29 20:44:05 +00:00
|
|
|
{
|
|
|
|
std::lock_guard lock{mutex};
|
2022-07-05 18:57:01 +00:00
|
|
|
replicated_access.addFilePath(access_zk_path, access_entity_type, host_id, file_path);
|
2022-06-29 20:44:05 +00:00
|
|
|
}
|
|
|
|
|
2022-07-05 18:57:01 +00:00
|
|
|
Strings BackupCoordinationLocal::getReplicatedAccessFilePaths(const String & access_zk_path, AccessEntityType access_entity_type, const String & host_id) const
|
2022-06-29 20:44:05 +00:00
|
|
|
{
|
|
|
|
std::lock_guard lock{mutex};
|
2022-07-05 18:57:01 +00:00
|
|
|
return replicated_access.getFilePaths(access_zk_path, access_entity_type, host_id);
|
2022-06-29 20:44:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-04-19 18:15:27 +00:00
|
|
|
void BackupCoordinationLocal::addFileInfo(const FileInfo & file_info, bool & is_data_file_required)
|
2022-04-17 12:11:43 +00:00
|
|
|
{
|
|
|
|
std::lock_guard lock{mutex};
|
2022-04-19 09:02:34 +00:00
|
|
|
file_names.emplace(file_info.file_name, std::pair{file_info.size, file_info.checksum});
|
|
|
|
if (!file_info.size)
|
|
|
|
{
|
|
|
|
is_data_file_required = false;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
bool inserted_file_info = file_infos.try_emplace(std::pair{file_info.size, file_info.checksum}, file_info).second;
|
|
|
|
is_data_file_required = inserted_file_info && (file_info.size > file_info.base_size);
|
2022-04-17 12:11:43 +00:00
|
|
|
}
|
|
|
|
|
2022-04-19 18:15:27 +00:00
|
|
|
void BackupCoordinationLocal::updateFileInfo(const FileInfo & file_info)
|
2022-04-17 12:11:43 +00:00
|
|
|
{
|
2022-04-19 09:02:34 +00:00
|
|
|
if (!file_info.size)
|
|
|
|
return; /// we don't keep FileInfos for empty files, nothing to update
|
|
|
|
|
2022-04-17 12:11:43 +00:00
|
|
|
std::lock_guard lock{mutex};
|
2022-04-19 09:02:34 +00:00
|
|
|
auto & dest = file_infos.at(std::pair{file_info.size, file_info.checksum});
|
2022-04-17 12:11:43 +00:00
|
|
|
dest.archive_suffix = file_info.archive_suffix;
|
|
|
|
}
|
|
|
|
|
2022-04-19 18:15:27 +00:00
|
|
|
std::vector<FileInfo> BackupCoordinationLocal::getAllFileInfos() const
|
2022-04-17 12:11:43 +00:00
|
|
|
{
|
|
|
|
std::lock_guard lock{mutex};
|
|
|
|
std::vector<FileInfo> res;
|
2022-04-19 09:02:34 +00:00
|
|
|
for (const auto & [file_name, size_and_checksum] : file_names)
|
2022-04-17 12:11:43 +00:00
|
|
|
{
|
2022-04-19 09:02:34 +00:00
|
|
|
FileInfo info;
|
|
|
|
UInt64 size = size_and_checksum.first;
|
|
|
|
if (size) /// we don't keep FileInfos for empty files
|
|
|
|
info = file_infos.at(size_and_checksum);
|
2022-04-17 12:11:43 +00:00
|
|
|
info.file_name = file_name;
|
|
|
|
res.push_back(std::move(info));
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2022-06-06 09:50:20 +00:00
|
|
|
Strings BackupCoordinationLocal::listFiles(const String & directory, bool recursive) const
|
2022-04-17 12:11:43 +00:00
|
|
|
{
|
|
|
|
std::lock_guard lock{mutex};
|
2022-06-06 09:50:20 +00:00
|
|
|
String prefix = directory;
|
|
|
|
if (!prefix.empty() && !prefix.ends_with('/'))
|
|
|
|
prefix += '/';
|
|
|
|
String terminator = recursive ? "" : "/";
|
2022-06-19 13:48:52 +00:00
|
|
|
|
2022-04-17 12:11:43 +00:00
|
|
|
Strings elements;
|
|
|
|
for (auto it = file_names.lower_bound(prefix); it != file_names.end(); ++it)
|
|
|
|
{
|
|
|
|
const String & name = it->first;
|
|
|
|
if (!name.starts_with(prefix))
|
|
|
|
break;
|
|
|
|
size_t start_pos = prefix.length();
|
|
|
|
size_t end_pos = String::npos;
|
|
|
|
if (!terminator.empty())
|
|
|
|
end_pos = name.find(terminator, start_pos);
|
|
|
|
std::string_view new_element = std::string_view{name}.substr(start_pos, end_pos - start_pos);
|
|
|
|
if (!elements.empty() && (elements.back() == new_element))
|
|
|
|
continue;
|
|
|
|
elements.push_back(String{new_element});
|
|
|
|
}
|
2022-06-19 13:48:52 +00:00
|
|
|
|
2022-04-17 12:11:43 +00:00
|
|
|
return elements;
|
|
|
|
}
|
|
|
|
|
2022-06-06 09:50:20 +00:00
|
|
|
bool BackupCoordinationLocal::hasFiles(const String & directory) const
|
|
|
|
{
|
|
|
|
std::lock_guard lock{mutex};
|
|
|
|
String prefix = directory;
|
|
|
|
if (!prefix.empty() && !prefix.ends_with('/'))
|
|
|
|
prefix += '/';
|
|
|
|
|
|
|
|
auto it = file_names.lower_bound(prefix);
|
|
|
|
if (it == file_names.end())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
const String & name = it->first;
|
|
|
|
return name.starts_with(prefix);
|
|
|
|
}
|
|
|
|
|
2022-04-19 18:15:27 +00:00
|
|
|
std::optional<FileInfo> BackupCoordinationLocal::getFileInfo(const String & file_name) const
|
2022-04-17 12:11:43 +00:00
|
|
|
{
|
|
|
|
std::lock_guard lock{mutex};
|
|
|
|
auto it = file_names.find(file_name);
|
|
|
|
if (it == file_names.end())
|
|
|
|
return std::nullopt;
|
2022-04-19 09:02:34 +00:00
|
|
|
const auto & size_and_checksum = it->second;
|
|
|
|
UInt64 size = size_and_checksum.first;
|
|
|
|
FileInfo info;
|
|
|
|
if (size) /// we don't keep FileInfos for empty files
|
|
|
|
info = file_infos.at(size_and_checksum);
|
|
|
|
info.file_name = file_name;
|
|
|
|
return info;
|
2022-04-17 12:11:43 +00:00
|
|
|
}
|
|
|
|
|
2022-04-19 18:15:27 +00:00
|
|
|
std::optional<FileInfo> BackupCoordinationLocal::getFileInfo(const SizeAndChecksum & size_and_checksum) const
|
2022-04-17 12:11:43 +00:00
|
|
|
{
|
|
|
|
std::lock_guard lock{mutex};
|
2022-04-19 09:02:34 +00:00
|
|
|
auto it = file_infos.find(size_and_checksum);
|
2022-04-17 12:11:43 +00:00
|
|
|
if (it == file_infos.end())
|
|
|
|
return std::nullopt;
|
|
|
|
return it->second;
|
|
|
|
}
|
|
|
|
|
2022-04-19 18:15:27 +00:00
|
|
|
String BackupCoordinationLocal::getNextArchiveSuffix()
|
2022-04-17 12:11:43 +00:00
|
|
|
{
|
2022-04-19 09:02:34 +00:00
|
|
|
std::lock_guard lock{mutex};
|
2022-04-17 12:11:43 +00:00
|
|
|
String new_archive_suffix = fmt::format("{:03}", ++current_archive_suffix); /// Outputs 001, 002, 003, ...
|
|
|
|
archive_suffixes.push_back(new_archive_suffix);
|
|
|
|
return new_archive_suffix;
|
|
|
|
}
|
|
|
|
|
2022-04-19 18:15:27 +00:00
|
|
|
Strings BackupCoordinationLocal::getAllArchiveSuffixes() const
|
2022-04-17 12:11:43 +00:00
|
|
|
{
|
|
|
|
std::lock_guard lock{mutex};
|
|
|
|
return archive_suffixes;
|
|
|
|
}
|
|
|
|
|
2023-02-16 08:30:27 +00:00
|
|
|
bool BackupCoordinationLocal::hasConcurrentBackups(const std::atomic<size_t> & num_active_backups) const
|
2023-02-10 11:04:05 +00:00
|
|
|
{
|
|
|
|
return (num_active_backups > 1);
|
|
|
|
}
|
|
|
|
|
2022-04-17 12:11:43 +00:00
|
|
|
}
|