323 throw std::runtime_error(
"DUMP/RESTORE is not supported yet on distributed setup.");
325 if (!boost::filesystem::exists(archive_path)) {
326 throw std::runtime_error(
"Archive " + archive_path +
" does not exist.");
329 throw std::runtime_error(
"Restoring view or temporary table is not supported.");
333 const auto table_read_lock =
336 const auto insert_data_lock =
342 constexpr
static const auto temp_data_basename =
"_data";
343 constexpr
static const auto temp_back_basename =
"_back";
344 const auto temp_data_dir =
abs_path(global_file_mgr) +
"/" + temp_data_basename;
345 const auto temp_back_dir =
abs_path(global_file_mgr) +
"/" + temp_back_basename;
347 auto tmp_files_cleaner = [&](
void*) {
348 run(
"rm -rf " + temp_data_dir +
" " + temp_back_dir);
353 std::unique_ptr<decltype(tmp_files_cleaner), decltype(tmp_files_cleaner)> tfc(
354 &tmp_files_cleaner, tmp_files_cleaner);
357 const auto create_table_stmt =
358 Parser::parseDDL<Parser::CreateTableStmt>(
"table schema", schema_str);
361 std::list<ColumnDescriptor> src_columns;
362 std::vector<Parser::SharedDictionaryDef> shared_dict_defs;
363 create_table_stmt->executeDryRun(session, src_td, src_columns, shared_dict_defs);
368 throw std::runtime_error(
"Incompatible table VACCUM option");
370 if (src_td.nShards != td->
nShards) {
373 throw std::runtime_error(
"Unmatched number of table shards");
376 const auto dst_columns =
378 if (dst_columns.size() != src_columns.size()) {
379 throw std::runtime_error(
"Unmatched number of table columns");
381 for (
const auto& [src_cd, dst_cd] : boost::combine(src_columns, dst_columns)) {
382 if (src_cd.columnType.get_type_name() != dst_cd->columnType.get_type_name() ||
383 src_cd.columnType.get_compression_name() !=
384 dst_cd->columnType.get_compression_name()) {
385 throw std::runtime_error(
"Incompatible types on column " + src_cd.columnName);
389 const auto all_src_oldinfo_str =
391 std::vector<std::string> src_oldinfo_strs;
394 boost::is_any_of(
" "),
395 boost::token_compress_on);
396 auto all_dst_columns =
398 if (src_oldinfo_strs.size() != all_dst_columns.size()) {
399 throw std::runtime_error(
"Source table has a unmatched number of columns: " +
409 std::unordered_map<int, int> column_ids_map;
410 std::unordered_map<std::string, std::string> dict_paths_map;
412 std::list<std::vector<std::string>> src_oldinfo_tokens;
414 src_oldinfo_strs.begin(),
415 src_oldinfo_strs.end(),
416 std::back_inserter(src_oldinfo_tokens),
417 [](
const auto& src_oldinfo_str) ->
auto {
418 std::vector<std::string> tokens;
420 tokens, src_oldinfo_str, boost::is_any_of(
":"), boost::token_compress_on);
423 src_oldinfo_tokens.sort(
424 [](
const auto& lhs,
const auto& rhs) {
return lhs[0].compare(rhs[0]) < 0; });
425 all_dst_columns.sort(
426 [](
auto a,
auto b) {
return a->columnName.compare(b->columnName) < 0; });
428 std::transform(src_oldinfo_tokens.begin(),
429 src_oldinfo_tokens.end(),
430 all_dst_columns.begin(),
431 std::inserter(column_ids_map, column_ids_map.end()),
432 [&](
const auto& tokens,
const auto& cd) -> std::pair<int, int> {
434 << cd->columnName <<
":" << cd->columnId;
436 return {boost::lexical_cast<
int>(tokens[1]), cd->columnId};
438 bool was_table_altered =
false;
439 std::for_each(column_ids_map.begin(), column_ids_map.end(), [&](
auto& it) {
440 was_table_altered = was_table_altered || it.first != it.second;
442 VLOG(3) <<
"was_table_altered = " << was_table_altered;
445 run(
"rm -rf " + temp_data_dir);
446 run(
"mkdir -p " + temp_data_dir);
449 if (was_table_altered) {
452 VLOG(3) <<
"adjust_altered_table_files: " << time_ms <<
" ms";
458 std::vector<std::string> both_file_dirs;
459 std::merge(data_file_dirs.begin(),
460 data_file_dirs.end(),
461 dict_file_dirs.begin(),
462 dict_file_dirs.end(),
463 std::back_inserter(both_file_dirs));
464 bool backup_completed =
false;
466 run(
"rm -rf " + temp_back_dir);
467 run(
"mkdir -p " + temp_back_dir);
468 for (
const auto& dir : both_file_dirs) {
469 const auto dir_full_path =
abs_path(global_file_mgr) +
"/" + dir;
470 if (boost::filesystem::is_directory(dir_full_path)) {
471 run(
"mv " + dir_full_path +
" " + temp_back_dir);
474 backup_completed =
true;
479 for (
const auto& dit : dict_paths_map) {
480 if (!dit.first.empty() && !dit.second.empty()) {
481 const auto src_dict_path = temp_data_dir +
"/" + dit.first;
482 const auto dst_dict_path =
abs_path(global_file_mgr) +
"/" + dit.second;
483 run(
"mv " + src_dict_path +
" " + dst_dict_path);
488 throw std::runtime_error(
"lol!");
493 if (backup_completed) {
498 boost::filesystem::path base_path(temp_back_dir);
499 boost::filesystem::directory_iterator end_it;
500 for (boost::filesystem::directory_iterator fit(base_path); fit != end_it; ++fit) {
501 run(
"mv " + fit->path().string() +
" .",
abs_path(global_file_mgr));
std::string get_table_schema(const std::string &archive_path, const std::string &table, const std::string &compression)
static ReadLock getReadLockForTable(const Catalog_Namespace::Catalog &cat, const std::string &table_name)
static constexpr char const * table_schema_filename
std::string abs_path(const File_Namespace::GlobalFileMgr *global_file_mgr)
Data_Namespace::DataMgr & getDataMgr() const
static WriteLock getWriteLockForTable(const Catalog_Namespace::Catalog &cat, const std::string &table_name)
void adjust_altered_table_files(const std::string &temp_data_dir, const std::unordered_map< int, int > &column_ids_map)
static constexpr char const * table_oldinfo_filename
File_Namespace::GlobalFileMgr * getGlobalFileMgr() const
std::vector< std::string > getTableDictDirectories(const TableDescriptor *td) const
std::string getColumnDictDirectory(const ColumnDescriptor *cd) const
void rename_table_directories(const File_Namespace::GlobalFileMgr *global_file_mgr, const std::string &temp_data_dir, const std::vector< std::string > &target_paths, const std::string &name_prefix)
const DBMetadata & getCurrentDB() const
void validate_allowed_file_path(const std::string &file_path, const DataTransferType data_transfer_type, const bool allow_wildcards)
void setTableEpoch(const int db_id, const int table_id, const int new_epoch)
Data_Namespace::MemoryLevel persistenceLevel
static constexpr char const * table_epoch_filename
std::vector< std::string > getTableDataDirectories(const TableDescriptor *td) const
std::list< const ColumnDescriptor * > getAllColumnMetadataForTable(const int tableId, const bool fetchSystemColumns, const bool fetchVirtualColumns, const bool fetchPhysicalColumns) const
Returns a list of pointers to constant ColumnDescriptor structs for all the columns from a particular...
static TimeT::rep execution(F func, Args &&... args)
std::string simple_file_cat(const std::string &archive_path, const std::string &file_name, const std::string &compression)
bool g_test_rollback_dump_restore
Catalog_Namespace::Catalog * cat_