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.
This commit is contained in:
Vlad Lesin 2023-03-23 16:26:17 +03:00
parent d575b07c86
commit 4c226c1850
11 changed files with 76 additions and 52 deletions

View file

@ -6830,6 +6830,7 @@ int main(int argc, char **argv)
*/ */
if (strcmp(argv[1], "--mysqld") == 0) if (strcmp(argv[1], "--mysqld") == 0)
{ {
srv_operation= SRV_OPERATION_EXPORT_RESTORED;
extern int mysqld_main(int argc, char **argv); extern int mysqld_main(int argc, char **argv);
argc--; argc--;
argv++; argv++;

View file

@ -8,8 +8,15 @@ CREATE DATABASE db2;
USE db2; USE db2;
CREATE TABLE t1(i INT) ENGINE INNODB; CREATE TABLE t1(i INT) ENGINE INNODB;
USE test; USE test;
BEGIN;
INSERT INTO db2.t1 VALUES(20);
INSERT INTO test.t1 VALUES(20);
INSERT INTO test.t2 VALUES(20);
# xtrabackup backup # xtrabackup backup
COMMIT;
t1.ibd t1.ibd
DROP TABLE t1; DROP TABLE t1;
DROP TABLE t2; DROP TABLE t2;
DROP DATABASE db2; 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

View file

@ -19,6 +19,11 @@ CREATE TABLE t1(i INT) ENGINE INNODB;
USE test; USE test;
BEGIN;
INSERT INTO db2.t1 VALUES(20);
INSERT INTO test.t1 VALUES(20);
INSERT INTO test.t2 VALUES(20);
echo # xtrabackup backup; echo # xtrabackup backup;
let $targetdir=$MYSQLTEST_VARDIR/tmp/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; exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup "--tables-exclude=test.*2" "--databases-exclude=db2" --target-dir=$targetdir;
--enable_result_log --enable_result_log
COMMIT;
# check that only t1 table is in backup (t2 is excluded) # check that only t1 table is in backup (t2 is excluded)
list_files $targetdir/test *.ibd; list_files $targetdir/test *.ibd;
# check that db2 database is not in the backup (excluded) # check that db2 database is not in the backup (excluded)
@ -46,4 +53,17 @@ DROP DATABASE db2;
rmdir $MYSQLD_DATADIR/db3; rmdir $MYSQLD_DATADIR/db3;
rmdir $MYSQLD_DATADIR/db4; rmdir $MYSQLD_DATADIR/db4;
rmdir $MYSQLD_DATADIR/db5; 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; rmdir $targetdir;

View file

@ -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 /* 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. */ an error if the tablespace is already open in remote or dict. */
ut_a(df_default.filepath()); 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) { if (df_default.open_read_only(strict) == DB_SUCCESS) {
ut_ad(df_default.is_open()); ut_ad(df_default.is_open());
++tablespaces_found; ++tablespaces_found;
@ -3284,7 +3289,9 @@ corrupted:
/* Make sense of these three possible locations. /* Make sense of these three possible locations.
First, bail out if no tablespace files were found. */ First, bail out if no tablespace files were found. */
if (valid_tablespaces_found == 0) { if (valid_tablespaces_found == 0) {
os_file_get_last_error(true); 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 `" ib::error() << "Could not find a valid tablespace file for `"
<< tablename << "`. " << TROUBLESHOOT_DATADICT_MSG; << tablename << "`. " << TROUBLESHOOT_DATADICT_MSG;
goto corrupted; goto corrupted;
@ -3617,6 +3624,7 @@ fil_ibd_discover(
case SRV_OPERATION_RESTORE: case SRV_OPERATION_RESTORE:
break; break;
case SRV_OPERATION_NORMAL: case SRV_OPERATION_NORMAL:
case SRV_OPERATION_EXPORT_RESTORED:
df_rem_per.set_name(db); df_rem_per.set_name(db);
if (df_rem_per.open_link_file() != DB_SUCCESS) { if (df_rem_per.open_link_file() != DB_SUCCESS) {
break; break;

View file

@ -787,7 +787,7 @@ the double write buffer.
bool bool
Datafile::restore_from_doublewrite() Datafile::restore_from_doublewrite()
{ {
if (srv_operation != SRV_OPERATION_NORMAL) { if (srv_operation > SRV_OPERATION_EXPORT_RESTORED) {
return true; return true;
} }

View file

@ -580,7 +580,7 @@ SysTablespace::read_lsn_and_check_flags(lsn_t* flushed_lsn)
ut_a(it->order() == 0); 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()); buf_dblwr_init_or_load_pages(it->handle(), it->filepath());
} }

View file

@ -1210,13 +1210,14 @@ os_file_flush_func(
/** Retrieves the last error number if an error occurs in a file io function. /** 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 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, overwrite the error number). If the number is not known to this program,
the OS error number + 100 is returned. the OS error number + OS_FILE_ERROR_MAX is returned.
@param[in] report true if we want an error message printed @param[in] report_all_errors true if we want an error message
for all errors printed of all errors
@return error number, or OS error number + 100 */ @param[in] on_error_silent true then don't print any diagnostic
ulint to the log
os_file_get_last_error( @return error number, or OS error number + OS_FILE_ERROR_MAX */
bool report); 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 /** NOTE! Use the corresponding macro os_file_read(), not directly this
function! function!

View file

@ -469,6 +469,9 @@ extern my_bool innodb_encrypt_temporary_tables;
enum srv_operation_mode { enum srv_operation_mode {
/** Normal mode (MariaDB Server) */ /** Normal mode (MariaDB Server) */
SRV_OPERATION_NORMAL, SRV_OPERATION_NORMAL,
/** Mariabackup is executing server to export already restored
tablespaces */
SRV_OPERATION_EXPORT_RESTORED,
/** Mariabackup taking a backup */ /** Mariabackup taking a backup */
SRV_OPERATION_BACKUP, SRV_OPERATION_BACKUP,
/** Mariabackup restoring a backup for subsequent --copy-back */ /** Mariabackup restoring a backup for subsequent --copy-back */

View file

@ -406,7 +406,7 @@ fil_name_process(
return; return;
} }
ut_ad(srv_operation == SRV_OPERATION_NORMAL ut_ad(srv_operation <= SRV_OPERATION_EXPORT_RESTORED
|| is_mariabackup_restore_or_export()); || is_mariabackup_restore_or_export());
/* We will also insert space=NULL into the map, so that /* 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 */ performed as part of the operation */
void recv_apply_hashed_log_recs(bool last_batch) 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()); || is_mariabackup_restore_or_export());
mutex_enter(&recv_sys.mutex); mutex_enter(&recv_sys.mutex);
@ -3603,7 +3603,7 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
byte* buf; byte* buf;
dberr_t err = DB_SUCCESS; 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()); || is_mariabackup_restore_or_export());
/* Initialize red-black tree for fast insertions into the /* 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; recv_sys.parse_start_lsn = checkpoint_lsn;
if (srv_operation == SRV_OPERATION_NORMAL) { if (srv_operation <= SRV_OPERATION_EXPORT_RESTORED) {
buf_dblwr_process(); buf_dblwr_process();
} }
@ -3862,7 +3862,8 @@ recv_recovery_from_checkpoint_start(lsn_t flush_lsn)
log_sys.last_checkpoint_lsn = checkpoint_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, /* Write a MLOG_CHECKPOINT marker as the first thing,
before generating any other redo log. This ensures before generating any other redo log. This ensures
that subsequent crash recovery will be possible even that subsequent crash recovery will be possible even

View file

@ -2291,11 +2291,7 @@ the OS error number + OS_FILE_ERROR_MAX is returned.
@param[in] on_error_silent true then don't print any diagnostic @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 */ @return error number, or OS error number + OS_FILE_ERROR_MAX */
static ulint os_file_get_last_error(bool report_all_errors, bool on_error_silent)
ulint
os_file_get_last_error_low(
bool report_all_errors,
bool on_error_silent)
{ {
int err = errno; int err = errno;
@ -3407,16 +3403,12 @@ os_file_flush_func(
The number should be retrieved before any other OS calls (because they may 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, overwrite the error number). If the number is not known to this program,
the OS error number + 100 is returned. the OS error number + 100 is returned.
@param[in] report_all_errors true if we want an error message printed @param[in] report_all_errors true if we want an error message
of all errors printed of all errors
@param[in] on_error_silent true then don't print any diagnostic @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 */ @return error number, or OS error number + 100 */
static ulint os_file_get_last_error(bool report_all_errors, bool on_error_silent)
ulint
os_file_get_last_error_low(
bool report_all_errors,
bool on_error_silent)
{ {
ulint err = (ulint) GetLastError(); ulint err = (ulint) GetLastError();
@ -4700,20 +4692,6 @@ os_file_read_page(
return err; 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. /** Handle errors for file operations.
@param[in] name name of a file or NULL @param[in] name name of a file or NULL
@param[in] operation operation @param[in] operation operation
@ -4730,7 +4708,7 @@ os_file_handle_error_cond_exit(
{ {
ulint err; 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) { switch (err) {
case OS_FILE_DISK_FULL: case OS_FILE_DISK_FULL:

View file

@ -810,7 +810,7 @@ srv_undo_tablespaces_init(bool create_new_db)
srv_undo_tablespaces_open = 0; srv_undo_tablespaces_open = 0;
ut_a(srv_undo_tablespaces <= TRX_SYS_N_RSEGS); 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 */ if (srv_undo_tablespaces == 1) { /* 1 is not allowed, make it 0 */
srv_undo_tablespaces = 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; prev_space_id = srv_undo_space_id_start - 1;
break; break;
case SRV_OPERATION_NORMAL: case SRV_OPERATION_NORMAL:
case SRV_OPERATION_EXPORT_RESTORED:
case SRV_OPERATION_RESTORE_ROLLBACK_XA: case SRV_OPERATION_RESTORE_ROLLBACK_XA:
case SRV_OPERATION_RESTORE: case SRV_OPERATION_RESTORE:
case SRV_OPERATION_RESTORE_EXPORT: case SRV_OPERATION_RESTORE_EXPORT:
@ -1132,6 +1133,7 @@ srv_shutdown_all_bg_threads()
case SRV_OPERATION_RESTORE_DELTA: case SRV_OPERATION_RESTORE_DELTA:
break; break;
case SRV_OPERATION_NORMAL: case SRV_OPERATION_NORMAL:
case SRV_OPERATION_EXPORT_RESTORED:
case SRV_OPERATION_RESTORE_ROLLBACK_XA: case SRV_OPERATION_RESTORE_ROLLBACK_XA:
case SRV_OPERATION_RESTORE: case SRV_OPERATION_RESTORE:
case SRV_OPERATION_RESTORE_EXPORT: case SRV_OPERATION_RESTORE_EXPORT:
@ -1310,7 +1312,7 @@ dberr_t srv_start(bool create_new_db)
size_t dirnamelen; size_t dirnamelen;
unsigned i = 0; unsigned i = 0;
ut_ad(srv_operation == SRV_OPERATION_NORMAL ut_ad(srv_operation <= SRV_OPERATION_EXPORT_RESTORED
|| is_mariabackup_restore_or_export()); || is_mariabackup_restore_or_export());
@ -1894,6 +1896,7 @@ files_checked:
switch (srv_operation) { switch (srv_operation) {
case SRV_OPERATION_NORMAL: case SRV_OPERATION_NORMAL:
case SRV_OPERATION_EXPORT_RESTORED:
case SRV_OPERATION_RESTORE_ROLLBACK_XA: case SRV_OPERATION_RESTORE_ROLLBACK_XA:
case SRV_OPERATION_RESTORE_EXPORT: case SRV_OPERATION_RESTORE_EXPORT:
/* Initialize the change buffer. */ /* Initialize the change buffer. */
@ -2304,7 +2307,8 @@ skip_monitors:
return(srv_init_abort(err)); 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 /* Initialize the innodb_temporary tablespace and keep
it open until shutdown. */ it open until shutdown. */
err = srv_open_tmp_tablespace(create_new_db); err = srv_open_tmp_tablespace(create_new_db);
@ -2326,7 +2330,7 @@ skip_monitors:
} }
if (!srv_read_only_mode if (!srv_read_only_mode
&& (srv_operation == SRV_OPERATION_NORMAL && (srv_operation <= SRV_OPERATION_EXPORT_RESTORED
|| srv_operation == SRV_OPERATION_RESTORE_ROLLBACK_XA) || srv_operation == SRV_OPERATION_RESTORE_ROLLBACK_XA)
&& srv_force_recovery < SRV_FORCE_NO_BACKGROUND) { && srv_force_recovery < SRV_FORCE_NO_BACKGROUND) {
@ -2465,6 +2469,7 @@ void innodb_shutdown()
fil_close_all_files(); fil_close_all_files();
break; break;
case SRV_OPERATION_NORMAL: case SRV_OPERATION_NORMAL:
case SRV_OPERATION_EXPORT_RESTORED:
/* Shut down the persistent files. */ /* Shut down the persistent files. */
logs_empty_and_mark_files_at_shutdown(); logs_empty_and_mark_files_at_shutdown();