Commit 4c226c18 authored by Vlad Lesin's avatar Vlad Lesin

MDEV-29050 mariabackup issues error messages during InnoDB tablespaces export...

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.
parent d575b07c
......@@ -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++;
......
......@@ -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
......@@ -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;
......@@ -3235,10 +3235,15 @@ fil_ibd_open(
}
}
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 @@ fil_ibd_open(
/* 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;
......
......@@ -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;
}
......
......@@ -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());
}
......
......@@ -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!
......
......@@ -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 */
......
......@@ -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
......
......@@ -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:
......
......@@ -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 @@ dberr_t srv_start(bool create_new_db)
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 @@ dberr_t srv_start(bool create_new_db)
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 @@ dberr_t srv_start(bool create_new_db)
}
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();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment