diff options
author | Vlad Lesin <vlad_lesin@mail.ru> | 2023-03-23 16:26:17 +0300 |
---|---|---|
committer | Vlad Lesin <vlad_lesin@mail.ru> | 2023-03-27 20:15:10 +0300 |
commit | 4c226c185015faa40fbd9b5e70bca5d819f2c3d5 (patch) | |
tree | f858f83db33d00b4dc789ec3da685d6599abdcfc | |
parent | d575b07c862daf68ddb124486ca8e829cd23cdd9 (diff) | |
download | mariadb-git-4c226c185015faa40fbd9b5e70bca5d819f2c3d5.tar.gz |
MDEV-29050 mariabackup issues error messages during InnoDB tablespaces export on partial backup preparing
The solution is to suppress error messages for missing tablespaces if
mariabackup is launched with "--prepare --export" options.
"mariabackup --prepare --export" invokes itself with --mysqld parameter.
If the parameter is set, then it starts server to feed "FLUSH TABLES ...
FOR EXPORT;" queries for exported tablespaces. This is "normal" server
start, that's why new srv_operation value is introduced.
Reviewed by Marko Makela.
-rw-r--r-- | extra/mariabackup/xtrabackup.cc | 1 | ||||
-rw-r--r-- | mysql-test/suite/mariabackup/partial_exclude.result | 7 | ||||
-rw-r--r-- | mysql-test/suite/mariabackup/partial_exclude.test | 20 | ||||
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 16 | ||||
-rw-r--r-- | storage/innobase/fsp/fsp0file.cc | 2 | ||||
-rw-r--r-- | storage/innobase/fsp/fsp0sysspace.cc | 2 | ||||
-rw-r--r-- | storage/innobase/include/os0file.h | 15 | ||||
-rw-r--r-- | storage/innobase/include/srv0srv.h | 3 | ||||
-rw-r--r-- | storage/innobase/log/log0recv.cc | 11 | ||||
-rw-r--r-- | storage/innobase/os/os0file.cc | 38 | ||||
-rw-r--r-- | storage/innobase/srv/srv0start.cc | 13 |
11 files changed, 76 insertions, 52 deletions
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index d2ce3395da8..5e01e64f490 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -6830,6 +6830,7 @@ int main(int argc, char **argv) */ if (strcmp(argv[1], "--mysqld") == 0) { + srv_operation= SRV_OPERATION_EXPORT_RESTORED; extern int mysqld_main(int argc, char **argv); argc--; argv++; diff --git a/mysql-test/suite/mariabackup/partial_exclude.result b/mysql-test/suite/mariabackup/partial_exclude.result index 628613040e0..9f4c1042d93 100644 --- a/mysql-test/suite/mariabackup/partial_exclude.result +++ b/mysql-test/suite/mariabackup/partial_exclude.result @@ -8,8 +8,15 @@ CREATE DATABASE db2; USE db2; CREATE TABLE t1(i INT) ENGINE INNODB; USE test; +BEGIN; +INSERT INTO db2.t1 VALUES(20); +INSERT INTO test.t1 VALUES(20); +INSERT INTO test.t2 VALUES(20); # xtrabackup backup +COMMIT; t1.ibd DROP TABLE t1; DROP TABLE t2; DROP DATABASE db2; +NOT FOUND /Operating system error number/ in backup.log +NOT FOUND /Could not find a valid tablespace file for/ in backup.log diff --git a/mysql-test/suite/mariabackup/partial_exclude.test b/mysql-test/suite/mariabackup/partial_exclude.test index 99d14e58231..beff778e7bc 100644 --- a/mysql-test/suite/mariabackup/partial_exclude.test +++ b/mysql-test/suite/mariabackup/partial_exclude.test @@ -19,6 +19,11 @@ CREATE TABLE t1(i INT) ENGINE INNODB; USE test; +BEGIN; +INSERT INTO db2.t1 VALUES(20); +INSERT INTO test.t1 VALUES(20); +INSERT INTO test.t2 VALUES(20); + echo # xtrabackup backup; let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; @@ -26,6 +31,8 @@ let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup "--tables-exclude=test.*2" "--databases-exclude=db2" --target-dir=$targetdir; --enable_result_log +COMMIT; + # check that only t1 table is in backup (t2 is excluded) list_files $targetdir/test *.ibd; # check that db2 database is not in the backup (excluded) @@ -46,4 +53,17 @@ DROP DATABASE db2; rmdir $MYSQLD_DATADIR/db3; rmdir $MYSQLD_DATADIR/db4; rmdir $MYSQLD_DATADIR/db5; + +--let $backup_log=$MYSQLTEST_VARDIR/tmp/backup.log +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --export --prepare --target-dir="$targetdir" > $backup_log; +--enable_result_log + +--let SEARCH_FILE=$backup_log +--let SEARCH_PATTERN=Operating system error number +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=Could not find a valid tablespace file for +--source include/search_pattern_in_file.inc +--remove_file $backup_log + rmdir $targetdir; diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 53387657ebc..ebeb1f66101 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -3235,10 +3235,15 @@ corrupted: } } + const bool operation_not_for_export = + srv_operation != SRV_OPERATION_RESTORE_EXPORT + && srv_operation != SRV_OPERATION_EXPORT_RESTORED; + /* Always look for a file at the default location. But don't log an error if the tablespace is already open in remote or dict. */ ut_a(df_default.filepath()); - const bool strict = (tablespaces_found == 0); + const bool strict = operation_not_for_export + && (tablespaces_found == 0); if (df_default.open_read_only(strict) == DB_SUCCESS) { ut_ad(df_default.is_open()); ++tablespaces_found; @@ -3284,9 +3289,11 @@ corrupted: /* Make sense of these three possible locations. First, bail out if no tablespace files were found. */ if (valid_tablespaces_found == 0) { - os_file_get_last_error(true); - ib::error() << "Could not find a valid tablespace file for `" - << tablename << "`. " << TROUBLESHOOT_DATADICT_MSG; + os_file_get_last_error( + operation_not_for_export, !operation_not_for_export); + if (operation_not_for_export) + ib::error() << "Could not find a valid tablespace file for `" + << tablename << "`. " << TROUBLESHOOT_DATADICT_MSG; goto corrupted; } if (!validate) { @@ -3617,6 +3624,7 @@ fil_ibd_discover( case SRV_OPERATION_RESTORE: break; case SRV_OPERATION_NORMAL: + case SRV_OPERATION_EXPORT_RESTORED: df_rem_per.set_name(db); if (df_rem_per.open_link_file() != DB_SUCCESS) { break; diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc index 5f6d70bb3b5..8d89c98e383 100644 --- a/storage/innobase/fsp/fsp0file.cc +++ b/storage/innobase/fsp/fsp0file.cc @@ -787,7 +787,7 @@ the double write buffer. bool Datafile::restore_from_doublewrite() { - if (srv_operation != SRV_OPERATION_NORMAL) { + if (srv_operation > SRV_OPERATION_EXPORT_RESTORED) { return true; } diff --git a/storage/innobase/fsp/fsp0sysspace.cc b/storage/innobase/fsp/fsp0sysspace.cc index 5fcf8ea4e51..dcab09e5eec 100644 --- a/storage/innobase/fsp/fsp0sysspace.cc +++ b/storage/innobase/fsp/fsp0sysspace.cc @@ -580,7 +580,7 @@ SysTablespace::read_lsn_and_check_flags(lsn_t* flushed_lsn) ut_a(it->order() == 0); - if (srv_operation == SRV_OPERATION_NORMAL) { + if (srv_operation <= SRV_OPERATION_EXPORT_RESTORED) { buf_dblwr_init_or_load_pages(it->handle(), it->filepath()); } diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index be363b8eea5..20fcc0b64b8 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -1210,13 +1210,14 @@ os_file_flush_func( /** Retrieves the last error number if an error occurs in a file io function. The number should be retrieved before any other OS calls (because they may overwrite the error number). If the number is not known to this program, -the OS error number + 100 is returned. -@param[in] report true if we want an error message printed - for all errors -@return error number, or OS error number + 100 */ -ulint -os_file_get_last_error( - bool report); +the OS error number + OS_FILE_ERROR_MAX is returned. +@param[in] report_all_errors true if we want an error message + printed of all errors +@param[in] on_error_silent true then don't print any diagnostic + to the log +@return error number, or OS error number + OS_FILE_ERROR_MAX */ +ulint os_file_get_last_error(bool report_all_errors, + bool on_error_silent= false); /** NOTE! Use the corresponding macro os_file_read(), not directly this function! diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 6d9d162e78e..1624619e897 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -469,6 +469,9 @@ extern my_bool innodb_encrypt_temporary_tables; enum srv_operation_mode { /** Normal mode (MariaDB Server) */ SRV_OPERATION_NORMAL, + /** Mariabackup is executing server to export already restored + tablespaces */ + SRV_OPERATION_EXPORT_RESTORED, /** Mariabackup taking a backup */ SRV_OPERATION_BACKUP, /** Mariabackup restoring a backup for subsequent --copy-back */ diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 3ecbcb180c9..eb4cb910679 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -406,7 +406,7 @@ fil_name_process( return; } - ut_ad(srv_operation == SRV_OPERATION_NORMAL + ut_ad(srv_operation <= SRV_OPERATION_EXPORT_RESTORED || is_mariabackup_restore_or_export()); /* We will also insert space=NULL into the map, so that @@ -2286,7 +2286,7 @@ buf_block_t* recv_recovery_create_page_low(const page_id_t page_id) performed as part of the operation */ void recv_apply_hashed_log_recs(bool last_batch) { - ut_ad(srv_operation == SRV_OPERATION_NORMAL + ut_ad(srv_operation <= SRV_OPERATION_EXPORT_RESTORED || is_mariabackup_restore_or_export()); mutex_enter(&recv_sys.mutex); @@ -3603,7 +3603,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn) byte* buf; dberr_t err = DB_SUCCESS; - ut_ad(srv_operation == SRV_OPERATION_NORMAL + ut_ad(srv_operation <= SRV_OPERATION_EXPORT_RESTORED || is_mariabackup_restore_or_export()); /* Initialize red-black tree for fast insertions into the @@ -3797,7 +3797,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn) recv_sys.parse_start_lsn = checkpoint_lsn; - if (srv_operation == SRV_OPERATION_NORMAL) { + if (srv_operation <= SRV_OPERATION_EXPORT_RESTORED) { buf_dblwr_process(); } @@ -3862,7 +3862,8 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn) log_sys.last_checkpoint_lsn = checkpoint_lsn; - if (!srv_read_only_mode && srv_operation == SRV_OPERATION_NORMAL) { + if (!srv_read_only_mode + && srv_operation <= SRV_OPERATION_EXPORT_RESTORED) { /* Write a MLOG_CHECKPOINT marker as the first thing, before generating any other redo log. This ensures that subsequent crash recovery will be possible even diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index b40e41cbab9..832f5e05658 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -2287,15 +2287,11 @@ The number should be retrieved before any other OS calls (because they may overwrite the error number). If the number is not known to this program, the OS error number + OS_FILE_ERROR_MAX is returned. @param[in] report_all_errors true if we want an error message - printed of all errors + printed of all errors @param[in] on_error_silent true then don't print any diagnostic - to the log + to the log @return error number, or OS error number + OS_FILE_ERROR_MAX */ -static -ulint -os_file_get_last_error_low( - bool report_all_errors, - bool on_error_silent) +ulint os_file_get_last_error(bool report_all_errors, bool on_error_silent) { int err = errno; @@ -3407,16 +3403,12 @@ os_file_flush_func( The number should be retrieved before any other OS calls (because they may overwrite the error number). If the number is not known to this program, the OS error number + 100 is returned. -@param[in] report_all_errors true if we want an error message printed - of all errors +@param[in] report_all_errors true if we want an error message +printed of all errors @param[in] on_error_silent true then don't print any diagnostic - to the log + to the log @return error number, or OS error number + 100 */ -static -ulint -os_file_get_last_error_low( - bool report_all_errors, - bool on_error_silent) +ulint os_file_get_last_error(bool report_all_errors, bool on_error_silent) { ulint err = (ulint) GetLastError(); @@ -4700,20 +4692,6 @@ os_file_read_page( return err; } -/** Retrieves the last error number if an error occurs in a file io function. -The number should be retrieved before any other OS calls (because they may -overwrite the error number). If the number is not known to this program, -the OS error number + 100 is returned. -@param[in] report_all_errors true if we want an error printed - for all errors -@return error number, or OS error number + 100 */ -ulint -os_file_get_last_error( - bool report_all_errors) -{ - return(os_file_get_last_error_low(report_all_errors, false)); -} - /** Handle errors for file operations. @param[in] name name of a file or NULL @param[in] operation operation @@ -4730,7 +4708,7 @@ os_file_handle_error_cond_exit( { ulint err; - err = os_file_get_last_error_low(false, on_error_silent); + err = os_file_get_last_error(false, on_error_silent); switch (err) { case OS_FILE_DISK_FULL: diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 30e2d7c6fbb..b8b74263eba 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -810,7 +810,7 @@ srv_undo_tablespaces_init(bool create_new_db) srv_undo_tablespaces_open = 0; ut_a(srv_undo_tablespaces <= TRX_SYS_N_RSEGS); - ut_a(!create_new_db || srv_operation == SRV_OPERATION_NORMAL); + ut_a(!create_new_db || srv_operation <= SRV_OPERATION_EXPORT_RESTORED); if (srv_undo_tablespaces == 1) { /* 1 is not allowed, make it 0 */ srv_undo_tablespaces = 0; @@ -876,6 +876,7 @@ srv_undo_tablespaces_init(bool create_new_db) prev_space_id = srv_undo_space_id_start - 1; break; case SRV_OPERATION_NORMAL: + case SRV_OPERATION_EXPORT_RESTORED: case SRV_OPERATION_RESTORE_ROLLBACK_XA: case SRV_OPERATION_RESTORE: case SRV_OPERATION_RESTORE_EXPORT: @@ -1132,6 +1133,7 @@ srv_shutdown_all_bg_threads() case SRV_OPERATION_RESTORE_DELTA: break; case SRV_OPERATION_NORMAL: + case SRV_OPERATION_EXPORT_RESTORED: case SRV_OPERATION_RESTORE_ROLLBACK_XA: case SRV_OPERATION_RESTORE: case SRV_OPERATION_RESTORE_EXPORT: @@ -1310,7 +1312,7 @@ dberr_t srv_start(bool create_new_db) size_t dirnamelen; unsigned i = 0; - ut_ad(srv_operation == SRV_OPERATION_NORMAL + ut_ad(srv_operation <= SRV_OPERATION_EXPORT_RESTORED || is_mariabackup_restore_or_export()); @@ -1894,6 +1896,7 @@ files_checked: switch (srv_operation) { case SRV_OPERATION_NORMAL: + case SRV_OPERATION_EXPORT_RESTORED: case SRV_OPERATION_RESTORE_ROLLBACK_XA: case SRV_OPERATION_RESTORE_EXPORT: /* Initialize the change buffer. */ @@ -2304,7 +2307,8 @@ skip_monitors: return(srv_init_abort(err)); } - if (!srv_read_only_mode && srv_operation == SRV_OPERATION_NORMAL) { + if (!srv_read_only_mode + && srv_operation <= SRV_OPERATION_EXPORT_RESTORED) { /* Initialize the innodb_temporary tablespace and keep it open until shutdown. */ err = srv_open_tmp_tablespace(create_new_db); @@ -2326,7 +2330,7 @@ skip_monitors: } if (!srv_read_only_mode - && (srv_operation == SRV_OPERATION_NORMAL + && (srv_operation <= SRV_OPERATION_EXPORT_RESTORED || srv_operation == SRV_OPERATION_RESTORE_ROLLBACK_XA) && srv_force_recovery < SRV_FORCE_NO_BACKGROUND) { @@ -2465,6 +2469,7 @@ void innodb_shutdown() fil_close_all_files(); break; case SRV_OPERATION_NORMAL: + case SRV_OPERATION_EXPORT_RESTORED: /* Shut down the persistent files. */ logs_empty_and_mark_files_at_shutdown(); |