diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 9efde5d00bc..3936d23a904 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -518,8 +518,15 @@ class Tablespace_dirs { void set_scan_dirs(const std::string &directories); /** Discover tablespaces by reading the header from .ibd files. + @param[in] populate_fil_cache if true, tabelspace are loaded to cache + @param[in] is_prep_handled_ddls if true, xtrabackup uses + ibd_open_for_recovery instead of + fil_open_for_xtrabackup() + @param[in] only_undo if true, only the undo tablespaces are + discovered @return DB_SUCCESS if all goes well */ - [[nodiscard]] dberr_t scan(bool populate_fil_cache, bool is_prep_handle_ddls); + [[nodiscard]] dberr_t scan(bool populate_fil_cache, bool is_prep_handle_ddls, + bool only_undo); /** Clear all the tablespace file data but leave the list of scanned directories in place. */ @@ -1700,9 +1707,17 @@ class Fil_system { } /** Scan the directories to build the tablespace ID to file name - mapping table. */ - dberr_t scan(bool populate_fil_cache, bool is_prep_handle_ddls) { - return (m_dirs.scan(populate_fil_cache, is_prep_handle_ddls)); + mapping table + @param[in] populate_fil_cache if true, tabelspace are loaded to cache + @param[in] is_prep_handled_ddls if true, xtrabackup uses + ibd_open_for_recovery instead of + fil_open_for_xtrabackup() + @param[in] only_undo if true, only the undo tablespaces are + discovered + @return DB_SUCCESS on success, other codes on errors */ + dberr_t scan(bool populate_fil_cache, bool is_prep_handle_ddls, + bool only_undo) { + return (m_dirs.scan(populate_fil_cache, is_prep_handle_ddls, only_undo)); } /** Open all known tablespaces. */ @@ -11964,10 +11979,14 @@ void Tablespace_dirs::set_scan_dirs(const std::string &in_directories) { } /** Discover tablespaces by reading the header from .ibd files. -@param[in] in_directories Directories to scan +@param[in] populate_fil_cache if true, tabelspace are loaded to cache +@param[in] is_prep_handled_ddls if true, xtrabackup uses ibd_open_for_recovery + instead of fil_open_for_xtrabackup() +@param[in] only_undo if true, only the undo tablespaces are +discovered @return DB_SUCCESS if all goes well */ -dberr_t Tablespace_dirs::scan(bool populate_fil_cache, - bool is_prep_handle_ddls) { +dberr_t Tablespace_dirs::scan(bool populate_fil_cache, bool is_prep_handle_ddls, + bool only_undo) { Scanned_files ibd_files; Scanned_files undo_files; uint16_t count = 0; @@ -11982,9 +12001,10 @@ dberr_t Tablespace_dirs::scan(bool populate_fil_cache, ib::info(ER_IB_MSG_379) << "Scanning '" << dir.path() << "'"; - /* Walk the sub-tree of dir. */ - - Dir_Walker::walk(real_path_dir, true, [&](const std::string &path) { + /* Walk the sub-tree of dir. If it is undo tablespaces only discovery, + used by xtrabackup, we dont do look into sub directories */ + bool walk_subtree = only_undo ? false : true; + Dir_Walker::walk(real_path_dir, walk_subtree, [&](const std::string &path) { /* If it is a file and the suffix matches ".ibd" or the undo file name format then store it for determining the space ID. */ @@ -12001,11 +12021,12 @@ dberr_t Tablespace_dirs::scan(bool populate_fil_cache, using Value = Scanned_files::value_type; - if (Fil_path::has_suffix(IBD, file.c_str())) { - ibd_files.push_back(Value{count, file}); - - } else if (Fil_path::is_undo_tablespace_name(file)) { + if (Fil_path::is_undo_tablespace_name(file)) { undo_files.push_back(Value{count, file}); + } else if (only_undo) { + return; + } else if (Fil_path::has_suffix(IBD, file.c_str())) { + ibd_files.push_back(Value{count, file}); } if (std::chrono::steady_clock::now() - start_time >= PRINT_INTERVAL) { @@ -12055,7 +12076,7 @@ dberr_t Tablespace_dirs::scan(bool populate_fil_cache, check = std::bind(&Tablespace_dirs::duplicate_check, this, _1, _2, _3, _4, _5, _6); - if (!populate_fil_cache) { + if (!populate_fil_cache && ibd_files.size() > 0) { par_for(PFS_NOT_INSTRUMENTED, ibd_files, n_threads, check, &m, &unique, &duplicates); } @@ -12081,7 +12102,7 @@ dberr_t Tablespace_dirs::scan(bool populate_fil_cache, debug_sync_point("xtrabackup_suspend_between_file_discovery_and_open"); - if (err == DB_SUCCESS && populate_fil_cache) { + if (err == DB_SUCCESS && populate_fil_cache && !only_undo) { bool result = true; std::function @@ -12105,11 +12126,15 @@ void fil_set_scan_dirs(const std::string &directories) { } /** Discover tablespaces by reading the header from .ibd files. -@param[in] populate_fil_cache Whether to load tablespaces into fil cache +@param[in] populate_fil_cache Whether to load tablespaces into fil cache +@param[in] is_prep_handled_ddls if true, xtrabackup uses ibd_open_for_recovery + instead of fil_open_for_xtrabackup() +@param[in] only_undo if true, only the undo tablespaces are + discovered @return DB_SUCCESS if all goes well */ dberr_t fil_scan_for_tablespaces(bool populate_fil_cache, - bool is_prep_handle_ddls) { - return (fil_system->scan(populate_fil_cache, is_prep_handle_ddls)); + bool is_prep_handle_ddls, bool only_undo) { + return (fil_system->scan(populate_fil_cache, is_prep_handle_ddls, only_undo)); } /** Open all known tablespaces. */ diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index ed5aa3529df..7434f11e491 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -2240,12 +2240,13 @@ void fil_set_scan_dir(const std::string &directory, bool is_undo_dir = false); void fil_set_scan_dirs(const std::string &directories); /** Discover tablespaces by reading the header from .ibd files. -@param[in] populate_fil_cache Whether to load tablespaces into fil cache -@param[in] is_prep_handle_ddls Whether loading tablespaces on prepare phase - to handle the ddls +@param[in] populate_fil_cache Whether to load tablespaces into fil cache +@param[in] is_prep_handle_ddls Whether loading tablespaces on prepare phase + to handle the ddls +@param[in] only_undo if true, only the undo tablespaces are discovered @return DB_SUCCESS if all goes well */ dberr_t fil_scan_for_tablespaces(bool populate_fil_cache, - bool is_prep_handle_ddls); + bool is_prep_handle_ddls, bool only_undo); /** Open the tablespace and also get the tablespace filenames, space_id must already be known. diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index a537c44f5f7..6567ad7a6a2 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -3708,8 +3708,8 @@ void Dir_Walker::walk_posix(const Path &basedir, bool recursive, Function &&f) { continue; } - if (file_type == OS_FILE_TYPE_DIR && recursive) { - directories.push(Entry(path, current.m_depth + 1)); + if (file_type == OS_FILE_TYPE_DIR) { + if (recursive) directories.push(Entry(path, current.m_depth + 1)); } else { f(path, current.m_depth + 1); } diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 3577bc515af..2525dfe8128 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -657,10 +657,12 @@ dberr_t srv_undo_tablespace_open(undo::Tablespace &undo_space) { } DBUG_EXECUTE_IF( - "undo_space_open", - if (strncmp(file_name, "./undo_1.ibu", strlen("./undo_1.ibu")) == 0) { - *const_cast(&xtrabackup_debug_sync) = "undo_space_open"; - debug_sync_point("undo_space_open"); + "undo_space_open", if (!is_server_locked()) { + if (strncmp(file_name, "./undo_1.ibu", strlen("./undo_1.ibu")) == 0) { + *const_cast(&xtrabackup_debug_sync) = + "undo_space_open"; + debug_sync_point("undo_space_open"); + } }); /* Now that space and node exist, make sure this undo tablespace @@ -675,6 +677,13 @@ dberr_t srv_undo_tablespace_open(undo::Tablespace &undo_space) { } } + // Track undo tablespaces that are found after server is locked + // if lock_ddl is REDUCED, we will do one more undo scan via + // srv_undo_tablespaces_init()/open() + if (ddl_tracker && is_server_locked()) { + ddl_tracker->add_undo_tablespace(space_id, file_name); + } + if (undo::is_reserved(space_id)) { undo::spaces->add(undo_space); } @@ -1782,7 +1791,7 @@ dberr_t srv_start(bool create_new_db IF_XB(, lsn_t to_lsn)) { return (srv_init_abort(err)); } - err = fil_scan_for_tablespaces(false, false); + err = fil_scan_for_tablespaces(false, false, false); if (err != DB_SUCCESS) { return (srv_init_abort(err)); diff --git a/storage/innobase/xtrabackup/src/ddl_tracker.cc b/storage/innobase/xtrabackup/src/ddl_tracker.cc index ad598d49fc2..06b030d8bd9 100644 --- a/storage/innobase/xtrabackup/src/ddl_tracker.cc +++ b/storage/innobase/xtrabackup/src/ddl_tracker.cc @@ -23,9 +23,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA #include #include "backup_copy.h" #include "file_utils.h" +#include "fsp0fsp.h" // fsp_is_undo_tablespace #include "sql_thd_internal_api.h" // create_thd, destroy_thd -#include "xb0xb.h" // check_if_skip_table -#include "xtrabackup.h" // datafiles_iter_t +#include "srv0start.h" +#include "xb0xb.h" // check_if_skip_table +#include "xtrabackup.h" // datafiles_iter_t void ddl_tracker_t::backup_file_op(uint32_t space_id, mlog_id_t type, const byte *buf, ulint len, @@ -78,6 +80,17 @@ void ddl_tracker_t::add_table_from_ibd_scan(const space_id_t space_id, tables_in_backup[space_id] = name; } +void ddl_tracker_t::add_undo_tablespace(const space_id_t space_id, + std::string name) { + Fil_path::normalize(name); + std::lock_guard lock(m_ddl_tracker_mutex); + if (is_server_locked()) { + after_lock_undo[name] = space_id; + } else { + before_lock_undo[name] = space_id; + } +} + void ddl_tracker_t::add_corrupted_tablespace(const space_id_t space_id, const std::string &path) { std::lock_guard lock(m_ddl_tracker_mutex); @@ -87,6 +100,13 @@ void ddl_tracker_t::add_corrupted_tablespace(const space_id_t space_id, void ddl_tracker_t::add_to_recopy_tables(space_id_t space_id, lsn_t start_lsn, const std::string operation) { + // There should never be MLOG_INDEX_LOAD. However MLOG_WRITE_STRING on + // new undo tabelsapce creation is possible. But we ignore this as the UNDOs + // are tracked separately + if (fsp_is_undo_tablespace(space_id)) { + return; + } + std::lock_guard lock(m_ddl_tracker_mutex); recopy_tables.insert(space_id); xb::info() << "DDL tracking : LSN: " << start_lsn << " " << operation @@ -105,6 +125,11 @@ void ddl_tracker_t::add_missing_table(std::string path) { void ddl_tracker_t::add_create_table_from_redo(const space_id_t space_id, lsn_t start_lsn, const char *name) { + // undo tablespaces are tracked separately. + if (fsp_is_undo_tablespace(space_id)) { + return; + } + std::string new_space_name = name; Fil_path::normalize(new_space_name); if (Fil_path::has_prefix(new_space_name, Fil_path::DOT_SLASH)) { @@ -147,6 +172,11 @@ void ddl_tracker_t::add_rename_table_from_redo(const space_id_t space_id, void ddl_tracker_t::add_drop_table_from_redo(const space_id_t space_id, lsn_t start_lsn, const char *name) { + // undo tablespaces are tracked separately. + if (fsp_is_undo_tablespace(space_id)) { + return; + } + std::string new_space_name{name}; Fil_path::normalize(new_space_name); if (Fil_path::has_prefix(new_space_name, Fil_path::DOT_SLASH)) { @@ -169,6 +199,13 @@ bool ddl_tracker_t::is_missing_table(const std::string &name) { void ddl_tracker_t::add_renamed_table(const space_id_t &space_id, std::string new_name) { + // undo tablespaces are tracked separately. + if (fsp_is_undo_tablespace(space_id)) { + // MLOG_FILE_RENAME is never done for undo tablespace + ut_ad(0); + return; + } + Fil_path::normalize(new_name); if (Fil_path::has_prefix(new_name, Fil_path::DOT_SLASH)) { new_name.erase(0, 2); @@ -233,15 +270,89 @@ std::string ddl_tracker_t::convert_file_name(space_id_t space_id, return file_name.substr(0, sep_pos + 1) + std::to_string(space_id) + ext; } +// Helper function to print the contents of a vector of pairs +void printVector(const std::string &operation, const filevec &vec) { + for (const auto &element : vec) { + xb::info() << operation << element.first << " : " << element.second << " "; + } +} + +// Function to find new, deleted, and changed files between two unordered_maps +std::tuple findChanges(const name_to_space_id_t &before, + const name_to_space_id_t &after) { + filevec newFiles; + filevec deletedOrChangedFiles; + + // Iterate through the after map to find new, changed, and unchanged files + for (const auto &pair : after) { + auto itBefore = before.find(pair.first); + if (itBefore == before.end()) { + // Element is new + newFiles.emplace_back(pair.first, pair.second); + } else { + // Element exists in before map + if (itBefore->second != pair.second) { + // Element value has changed + deletedOrChangedFiles.emplace_back( + pair.first, itBefore->second); // Use old value from before map + newFiles.emplace_back(pair.first, pair.second); + } + } + } + + // Look for deleted + for (const auto &pair : before) { + auto itAfter = after.find(pair.first); + + if (itAfter == after.end()) { + // Element is not present in the after map. This is deleted + deletedOrChangedFiles.emplace_back(pair.first, pair.second); + } + } + + return {newFiles, deletedOrChangedFiles}; +} + +std::tuple ddl_tracker_t::handle_undo_ddls() { + xb::info() << "DDL tracking: handling undo DDLs"; + + undo_spaces_deinit(); + undo_spaces_init(); + xb_scan_for_tablespaces(false, true); + + // Generates the after_lock_undo list + srv_undo_tablespaces_init(false, true); + + auto [newfiles, deletedOrChangedFiles] = + findChanges(before_lock_undo, after_lock_undo); + + // Print the results + xb::info() << "New UNDO files: "; + printVector("New undo file: ", newfiles); + + xb::info() << "Deleted or truncated UNDO files: "; + printVector("Deleted undo file: ", deletedOrChangedFiles); + + return {newfiles, deletedOrChangedFiles}; +} + void ddl_tracker_t::handle_ddl_operations() { + fil_close_all_files(); + fil_close(); + fil_init(LONG_MAX); + + auto [new_undo_files, deleted_undo_files] = handle_undo_ddls(); + xb::info() << "DDL tracking : handling DDL operations"; if (new_tables.empty() && renames.empty() && drops.empty() && - recopy_tables.empty() && corrupted_tablespaces.empty()) { + recopy_tables.empty() && corrupted_tablespaces.empty() && + new_undo_files.empty() && deleted_undo_files.empty()) { xb::info() << "DDL tracking : Finished handling DDL operations - No changes"; return; } + dberr_t err; for (auto &tablespace : corrupted_tablespaces) { @@ -333,7 +444,6 @@ void ddl_tracker_t::handle_ddl_operations() { "%s", table.second.second.c_str()); } - fil_close_all_files(); for (auto table = new_tables.begin(); table != new_tables.end();) { if (check_if_skip_table(table->second.c_str())) { table = new_tables.erase(table); @@ -344,6 +454,18 @@ void ddl_tracker_t::handle_ddl_operations() { table++; } + // Create .del files for deleted undo tablespaces + for (auto &elem : deleted_undo_files) { + backup_file_printf( + convert_file_name(elem.second, elem.first, ".ibu.del").c_str(), "%s", + ""); + } + + // Add new undo files to be recopied + for (auto &elem : new_undo_files) { + new_tables[elem.second] = elem.first; + } + if (new_tables.empty()) return; /* Create data copying threads */ diff --git a/storage/innobase/xtrabackup/src/ddl_tracker.h b/storage/innobase/xtrabackup/src/ddl_tracker.h index 092557420b7..27fa9dd61a5 100644 --- a/storage/innobase/xtrabackup/src/ddl_tracker.h +++ b/storage/innobase/xtrabackup/src/ddl_tracker.h @@ -23,7 +23,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA #include "log0types.h" #include "mtr0types.h" typedef std::unordered_map space_id_to_name_t; +typedef std::unordered_map name_to_space_id_t; typedef std::unordered_map meta_map_t; +using filevec = std::vector>; extern meta_map_t meta_map; @@ -32,6 +34,8 @@ class ddl_tracker_t { space_id_to_name_t tables_in_backup; /** Tablspaces with their ID and name, as they were copied to backup.*/ space_id_to_name_t new_tables; + name_to_space_id_t before_lock_undo; + name_to_space_id_t after_lock_undo; /** Tablespaces involved in encryption or bulk index load.*/ std::unordered_set recopy_tables; /** Drop operations found in redo log. */ @@ -53,7 +57,11 @@ class ddl_tracker_t { recopy_tables concurrently */ std::mutex m_ddl_tracker_mutex; + std::tuple handle_undo_ddls(); + public: + void add_undo_tablespace(const space_id_t space_id, std::string name); + /** Add a new table in the DDL tracker table list. @param[in] space_id tablespace identifier @param[in] name tablespace name */ diff --git a/storage/innobase/xtrabackup/src/xtrabackup.cc b/storage/innobase/xtrabackup/src/xtrabackup.cc index 79aeaebb7ed..91924e87aa7 100644 --- a/storage/innobase/xtrabackup/src/xtrabackup.cc +++ b/storage/innobase/xtrabackup/src/xtrabackup.cc @@ -2469,7 +2469,7 @@ static bool innodb_init_param(void) { return (true); } -static void xb_scan_for_tablespaces(bool is_prep_handle_ddls) { +void xb_scan_for_tablespaces(bool is_prep_handle_ddls, bool only_undo) { /* This is the default directory for IBD and IBU files. Put it first in the list of known directories. */ fil_set_scan_dir(MySQL_datadir_path.path()); @@ -2488,7 +2488,8 @@ static void xb_scan_for_tablespaces(bool is_prep_handle_ddls) { --innodb-undo-directory also. */ fil_set_scan_dir(Fil_path::remove_quotes(MySQL_undo_path), true); - if (fil_scan_for_tablespaces(true, is_prep_handle_ddls) != DB_SUCCESS) { + if (fil_scan_for_tablespaces(true, is_prep_handle_ddls, only_undo) != + DB_SUCCESS) { exit(EXIT_FAILURE); } } @@ -3362,6 +3363,11 @@ static void data_copy_thread_func(data_thread_ctxt_t *ctxt) { if (xtrabackup_copy_datafile(node, num)) { xb::error() << "failed to copy datafile " << node->name; *(ctxt->error) = true; + } else { + if (ddl_tracker && fsp_is_undo_tablespace(node->space->id)) { + ddl_tracker->add_undo_tablespace(node->space->id, + node->space->files.front().name); + } } } @@ -3615,7 +3621,7 @@ static dberr_t xb_load_tablespaces(bool is_prep_handle_ddls) } xb::info() << "Generating a list of tablespaces"; - xb_scan_for_tablespaces(is_prep_handle_ddls); + xb_scan_for_tablespaces(is_prep_handle_ddls, false); /* Add separate undo tablespaces to fil_system */ @@ -7045,6 +7051,7 @@ static void xtrabackup_prepare_func(int argc, char **argv) { xb_data_files_close(); fil_close(); innodb_free_param(); + undo_spaces_deinit(); /* Handle `CREATE` DDL files produced by DDL tracking during backup */ if (xtrabackup_incremental_dir) { diff --git a/storage/innobase/xtrabackup/src/xtrabackup.h b/storage/innobase/xtrabackup/src/xtrabackup.h index 6613badcb42..6d427775fdd 100644 --- a/storage/innobase/xtrabackup/src/xtrabackup.h +++ b/storage/innobase/xtrabackup/src/xtrabackup.h @@ -342,4 +342,6 @@ bool xb_process_datadir(const char *path, /*! >( tee $XB_ERROR_LOG)& + +job_pid=$! +pid_file=$topdir/backup/xtrabackup_debug_sync +wait_for_xb_to_suspend $pid_file +xb_pid=`cat $pid_file` +echo "backup pid is $job_pid" + +UNDO_2_BI_SPACE_ID=$($MYSQL $MYSQL_ARGS -BN -e "select space from information_schema.innodb_tablespaces where name = 'UNDO_3'") +mysql -e "ALTER UNDO TABLESPACE UNDO_2 SET INACTIVE" +mysql -e "SET GLOBAL innodb_purge_rseg_truncate_frequency=1" +sleep 1 +UNDO_2_BI_SPACE_ID=$($MYSQL $MYSQL_ARGS -BN -e "select space from information_schema.innodb_tablespaces where name = 'UNDO_3'") +mysql -e "DROP UNDO TABLESPACE UNDO_2" + +# before inactive +UNDO_3_BI_SPACE_ID=$($MYSQL $MYSQL_ARGS -BN -e "select space from information_schema.innodb_tablespaces where name = 'UNDO_3'") + +mysql -e "ALTER UNDO TABLESPACE UNDO_3 SET INACTIVE" +mysql -e "SET GLOBAL innodb_purge_rseg_truncate_frequency=1" +sleep 2 + +# after inactive +UNDO_3_AI_SPACE_ID=$($MYSQL $MYSQL_ARGS -BN -e "select space from information_schema.innodb_tablespaces where name = 'UNDO_3'") +mysql -e "CREATE UNDO TABLESPACE UNDO_4 ADD DATAFILE 'undo_4.ibu'" + +# Resume the xtrabackup process +vlog "Resuming xtrabackup" +kill -SIGCONT $xb_pid +run_cmd wait $job_pid + +UNDO_1_SPACE_ID=$($MYSQL $MYSQL_ARGS -BN -e "select space from information_schema.innodb_tablespaces where name = 'UNDO_1'") +UNDO_4_SPACE_ID=$($MYSQL $MYSQL_ARGS -BN -e "select space from information_schema.innodb_tablespaces where name = 'UNDO_4'") + +xtrabackup --prepare --target-dir=$BACKUP_DIR +stop_server + +rm -rf $mysql_datadir/* +xtrabackup --copy-back --target-dir=$BACKUP_DIR +start_server + +UNDO_BACKUP_1_SPACE_ID=$($MYSQL $MYSQL_ARGS -BN -e "select space from information_schema.innodb_tablespaces where name = 'UNDO_1'") +UNDO_BACKUP_2_SPACE_ID=$($MYSQL $MYSQL_ARGS -BN -e "select space from information_schema.innodb_tablespaces where name = 'UNDO_2'") +UNDO_BACKUP_3_SPACE_ID=$($MYSQL $MYSQL_ARGS -BN -e "select space from information_schema.innodb_tablespaces where name = 'UNDO_3'") +UNDO_BACKUP_4_SPACE_ID=$($MYSQL $MYSQL_ARGS -BN -e "select space from information_schema.innodb_tablespaces where name = 'UNDO_4'") + +echo "UNDO_1 space_id is $UNDO_BACKUP_1_SPACE_ID" +echo "UNDO_2 space_id is $UNDO_BACKUP_2_SPACE_ID" +echo "UNDO_3 space_id is $UNDO_BACKUP_3_SPACE_ID" +echo "UNDO_4 space_id is $UNDO_BACKUP_4_SPACE_ID" + +# UNDO_1 no space_id change +if [ $UNDO_1_SPACE_ID != $UNDO_BACKUP_1_SPACE_ID ]; then + echo "space_id of undo_01 shouldn't have changed. Before backup: undo_1 space_id $UNDO_1_SPACE_ID. After backup and restore undo_1 space_id is $UNDO_BACKUP_1_SPACE_ID" + exit 1 +fi + +## UNDO_4 no space_id change. If we get this it means undo_04 is copied. +#FILE=$BACKUP_DIR/undo_4.ibu +#[ -f $FILE ] || die "$FILE did NOT exist. It should have been backuped. It is created before end of backup. Server did CREATE UNDO TABLESPACE undo_04, right before DDL lock is taken" +# +#if [ -z ${UNDO_BACKUP_4_SPACE_ID+x} ]; then +# echo "UNDO TABLESPACE 4 should have been present in backup. But it is not found." +# exit 1 +#if +# +#if [ $UNDO_4_SPACE_ID != $UNDO_BACKUP_4_SPACE_ID ]; then +# echo "space_id of undo_04 shouldn't have changed. Before backup: undo_4 space_id $UNDO_4_SPACE_ID. After backup and restore undo_4 space_id is $UNDO_BACKUP_4_SPACE_ID" +# exit 1 +#fi + +# UND0_3 should have AI space_id and not BI space_id +if [ $UNDO_3_AI_SPACE_ID != $UNDO_BACKUP_3_SPACE_ID ]; then + echo "space_id of undo_03 should have space_id after truncation. space_id at time of the backup: undo_3 space_id $UNDO_3_AF_SPACE_ID. After backup and restore undo_1 space_id is $UNDO_BACKUP_3_SPACE_ID" + exit 1 +fi + +# UNDO_3 shouldn't have space_id before truncation +if [ $UNDO_3_BI_SPACE_ID == $UNDO_BACKUP_3_SPACE_ID ]; then + echo "space_id of undo_03 should NOT have space_id before truncation. space_id before_truncation undo_3 space_id $UNDO_3_BI_SPACE_ID. After backup and restore undo_1 space_id is $UNDO_BACKUP_3_SPACE_ID" + exit 1 +fi + +FILE=$BACKUP_DIR/undo_2.ibu +[ ! -f $FILE ] || die "$FILE exists. It should have been deleted by prepare. Server did DROP UNDO TABLESPACE undo_02" + +# UNDO_2 should be empty because it was dropped. We should also check physical presence of undo_02.ibu file +if [ ! -z "${UNDO_BACKUP_2_SPACE_ID}" ]; then + echo "UNDO TABLESPACE 2 should have been dropped in backup. Found UNDO_2 with space_id: $UNDO_BACKUP_2_SPACE_ID" + exit 1 +fi + + +stop_server + +rm -rf $mysql_datadir $BACKUP_DIR +rm $XB_ERROR_LOG