summaryrefslogtreecommitdiff
path: root/extra/mariabackup/xtrabackup.cc
diff options
context:
space:
mode:
Diffstat (limited to 'extra/mariabackup/xtrabackup.cc')
-rw-r--r--extra/mariabackup/xtrabackup.cc887
1 files changed, 543 insertions, 344 deletions
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index aa0ed07c205..009a4891d93 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -36,8 +36,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
-this program; if not, write to the Free Software Foundation, Inc., 59 Temple
-Place, Suite 330, Boston, MA 02111-1307 USA
+this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*******************************************************/
@@ -185,7 +185,7 @@ xb_stream_fmt_t xtrabackup_stream_fmt = XB_STREAM_FMT_NONE;
ibool xtrabackup_stream = FALSE;
const char *xtrabackup_compress_alg = NULL;
-ibool xtrabackup_compress = FALSE;
+uint xtrabackup_compress = FALSE;
uint xtrabackup_compress_threads;
ulonglong xtrabackup_compress_chunk_size = 0;
@@ -200,6 +200,8 @@ static char* log_ignored_opt;
extern my_bool opt_use_ssl;
my_bool opt_ssl_verify_server_cert;
+my_bool opt_extended_validation;
+my_bool opt_encrypted_backup;
/* === metadata of backup === */
#define XTRABACKUP_METADATA_FILENAME "xtrabackup_checkpoints"
@@ -301,6 +303,7 @@ my_bool opt_decompress = FALSE;
my_bool opt_remove_original;
my_bool opt_lock_ddl_per_table = FALSE;
+static my_bool opt_check_privileges;
extern const char *innodb_checksum_algorithm_names[];
extern TYPELIB innodb_checksum_algorithm_typelib;
@@ -474,9 +477,18 @@ DECLARE_THREAD(dbug_execute_in_new_connection)(void *arg)
dbug_thread_param_t *par= (dbug_thread_param_t *)arg;
int err = mysql_query(par->con, par->query);
int err_no = mysql_errno(par->con);
- DBUG_ASSERT(par->expect_err == err);
- if (err && par->expect_errno)
- DBUG_ASSERT(err_no == par->expect_errno);
+ if(par->expect_err != err)
+ {
+ msg("FATAL: dbug_execute_in_new_connection : mysql_query '%s' returns %d, instead of expected %d",
+ par->query, err, par->expect_err);
+ _exit(1);
+ }
+ if (err && par->expect_errno && par->expect_errno != err_no)
+ {
+ msg("FATAL: dbug_execute_in_new_connection: mysql_query '%s' returns mysql_errno %d, instead of expected %d",
+ par->query, err_no, par->expect_errno);
+ _exit(1);
+ }
mysql_close(par->con);
mysql_thread_end();
os_event_t done = par->done_event;
@@ -522,16 +534,18 @@ static os_event_t dbug_start_query_thread(
mysql_thread_id(par->con), wait_state);
for (;;) {
MYSQL_RES *result = xb_mysql_query(mysql_connection,q, true, true);
- if (mysql_fetch_row(result)) {
+ bool exists = mysql_fetch_row(result) != NULL;
+ mysql_free_result(result);
+ if (exists) {
goto end;
}
- msg_ts("Waiting for query '%s' on connection %lu to "
+ msg("Waiting for query '%s' on connection %lu to "
" reach state '%s'", query, mysql_thread_id(par->con),
wait_state);
my_sleep(1000);
}
end:
- msg_ts("query '%s' on connection %lu reached state '%s'", query,
+ msg("query '%s' on connection %lu reached state '%s'", query,
mysql_thread_id(par->con), wait_state);
return par->done_event;
}
@@ -577,7 +591,9 @@ std::string filename_to_spacename(const byte *filename, size_t len)
char *db = strrchr(f, '/');
ut_a(db);
*table = '/';
- return std::string(db+1);
+ std::string s(db+1);
+ free(f);
+ return s;
}
/** Report an operation to create, delete, or rename a file during backup.
@@ -587,7 +603,7 @@ std::string filename_to_spacename(const byte *filename, size_t len)
@param[in] len length of name, in bytes
@param[in] new_name new file name (NULL if not rename)
@param[in] new_len length of new_name, in bytes (0 if NULL) */
-void backup_file_op(ulint space_id, const byte* flags,
+static void backup_file_op(ulint space_id, const byte* flags,
const byte* name, ulint len,
const byte* new_name, ulint new_len)
{
@@ -600,41 +616,123 @@ void backup_file_op(ulint space_id, const byte* flags,
if (flags) {
ddl_tracker.id_to_name[space_id] = filename_to_spacename(name, len);
- msg("DDL tracking : create %zu \"%.*s\": %x\n",
+ msg("DDL tracking : create %zu \"%.*s\": %x",
space_id, int(len), name, mach_read_from_4(flags));
}
else if (new_name) {
ddl_tracker.id_to_name[space_id] = filename_to_spacename(new_name, new_len);
- msg("DDL tracking : rename %zu \"%.*s\",\"%.*s\"\n",
+ msg("DDL tracking : rename %zu \"%.*s\",\"%.*s\"",
space_id, int(len), name, int(new_len), new_name);
} else {
ddl_tracker.drops.insert(space_id);
- msg("DDL tracking : delete %zu \"%.*s\"\n", space_id, int(len), name);
+ msg("DDL tracking : delete %zu \"%.*s\"", space_id, int(len), name);
}
pthread_mutex_unlock(&backup_mutex);
}
+/*
+ This callback is called if DDL operation is detected,
+ at the end of backup
+
+ Normally, DDL operations are blocked due to FTWRL,
+ but in rare cases of --no-lock, they are not.
+
+ We will abort backup in this case.
+*/
+static void backup_file_op_fail(ulint space_id, const byte* flags,
+ const byte* name, ulint len,
+ const byte* new_name, ulint new_len)
+{
+ ut_a(opt_no_lock);
+ bool fail;
+ if (flags) {
+ msg("DDL tracking : create %zu \"%.*s\": %x",
+ space_id, int(len), name, mach_read_from_4(flags));
+ std::string spacename = filename_to_spacename(name, len);
+ fail = !check_if_skip_table(spacename.c_str());
+ }
+ else if (new_name) {
+ msg("DDL tracking : rename %zu \"%.*s\",\"%.*s\"",
+ space_id, int(len), name, int(new_len), new_name);
+ std::string spacename = filename_to_spacename(name, len);
+ std::string new_spacename = filename_to_spacename(new_name, new_len);
+ fail = !check_if_skip_table(spacename.c_str()) || !check_if_skip_table(new_spacename.c_str());
+ }
+ else {
+ std::string spacename = filename_to_spacename(name, len);
+ fail = !check_if_skip_table(spacename.c_str());
+ msg("DDL tracking : delete %zu \"%.*s\"", space_id, int(len), name);
+ }
+ if (fail) {
+ die("DDL operation detected in the late phase of backup."
+ "Backup is inconsistent. Remove --no-lock option to fix.");
+ }
+}
+
+
/** Callback whenever MLOG_INDEX_LOAD happens.
@param[in] space_id space id to check */
static void backup_optimized_ddl_op(ulint space_id)
{
- // TODO : handle incremental
- if (xtrabackup_incremental)
- return;
-
pthread_mutex_lock(&backup_mutex);
ddl_tracker.optimized_ddl.insert(space_id);
pthread_mutex_unlock(&backup_mutex);
}
+/*
+ Optimized DDL callback at the end of backup that
+ run with --no-lock. Usually aborts the backup.
+*/
+static void backup_optimized_ddl_op_fail(ulint space_id) {
+ ut_a(opt_no_lock);
+ msg("DDL tracking : optimized DDL on space %zu", space_id);
+ if (ddl_tracker.tables_in_backup.find(space_id) != ddl_tracker.tables_in_backup.end()) {
+ msg("ERROR : Optimized DDL operation detected in the late phase of backup."
+ "Backup is inconsistent. Remove --no-lock option to fix.");
+ exit(EXIT_FAILURE);
+ }
+}
+
+
+/*
+ Retrieve default data directory, to be used with --copy-back.
+
+ On Windows, default datadir is ..\data, relative to the
+ directory where mariabackup.exe is located(usually "bin")
+
+ Elsewhere, the compiled-in constant MYSQL_DATADIR is used.
+*/
+static char *get_default_datadir() {
+ static char ddir[] = MYSQL_DATADIR;
+#ifdef _WIN32
+ static char buf[MAX_PATH];
+ DWORD size = (DWORD)sizeof(buf) - 1;
+ if (GetModuleFileName(NULL, buf, size) <= size)
+ {
+ char *p;
+ if ((p = strrchr(buf, '\\')))
+ {
+ *p = 0;
+ if ((p = strrchr(buf, '\\')))
+ {
+ strncpy(p + 1, "data", buf + MAX_PATH - p);
+ return buf;
+ }
+ }
+ }
+#endif
+ return ddir;
+}
+
+
/* ======== Date copying thread context ======== */
typedef struct {
datafiles_iter_t *it;
uint num;
uint *count;
- pthread_mutex_t count_mutex;
+ pthread_mutex_t* count_mutex;
os_thread_id_t id;
} data_thread_ctxt_t;
@@ -661,6 +759,8 @@ enum options_xtrabackup
OPT_XTRA_DATABASES,
OPT_XTRA_DATABASES_FILE,
OPT_XTRA_PARALLEL,
+ OPT_XTRA_EXTENDED_VALIDATION,
+ OPT_XTRA_ENCRYPTED_BACKUP,
OPT_XTRA_STREAM,
OPT_XTRA_COMPRESS,
OPT_XTRA_COMPRESS_THREADS,
@@ -734,7 +834,8 @@ enum options_xtrabackup
OPT_PROTOCOL,
OPT_LOCK_DDL_PER_TABLE,
OPT_ROCKSDB_DATADIR,
- OPT_BACKUP_ROCKSDB
+ OPT_BACKUP_ROCKSDB,
+ OPT_XTRA_CHECK_PRIVILEGES
};
struct my_option xb_client_options[] =
@@ -1117,6 +1218,22 @@ struct my_option xb_server_options[] =
(G_PTR*) &xtrabackup_parallel, (G_PTR*) &xtrabackup_parallel, 0, GET_INT,
REQUIRED_ARG, 1, 1, INT_MAX, 0, 0, 0},
+ {"extended_validation", OPT_XTRA_EXTENDED_VALIDATION,
+ "Enable extended validation for Innodb data pages during backup phase. "
+ "Will slow down backup considerably, in case encryption is used. "
+ "May fail if tables are created during the backup.",
+ (G_PTR*)&opt_extended_validation,
+ (G_PTR*)&opt_extended_validation,
+ 0, GET_BOOL, NO_ARG, FALSE, 0, 0, 0, 0, 0},
+
+ {"encrypted_backup", OPT_XTRA_ENCRYPTED_BACKUP,
+ "In --backup, assume that nonzero key_version implies that the page"
+ " is encrypted. Use --backup --skip-encrypted-backup to allow"
+ " copying unencrypted that were originally created before MySQL 5.1.48.",
+ (G_PTR*)&opt_encrypted_backup,
+ (G_PTR*)&opt_encrypted_backup,
+ 0, GET_BOOL, NO_ARG, TRUE, 0, 0, 0, 0, 0},
+
{"log", OPT_LOG, "Ignored option for MySQL option compatibility",
(G_PTR*) &log_ignored_opt, (G_PTR*) &log_ignored_opt, 0,
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
@@ -1287,6 +1404,10 @@ struct my_option xb_server_options[] =
&xb_backup_rocksdb, &xb_backup_rocksdb,
0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 },
+ {"check-privileges", OPT_XTRA_CHECK_PRIVILEGES, "Check database user "
+ "privileges fro the backup user",
+ &opt_check_privileges, &opt_check_privileges,
+ 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
};
@@ -1327,14 +1448,13 @@ debug_sync_point(const char *name)
xtrabackup_target_dir);
fp = fopen(pid_path, "w");
if (fp == NULL) {
- msg("mariabackup: Error: cannot open %s\n", pid_path);
- exit(EXIT_FAILURE);
+ die("Can't open open %s", pid_path);
}
fprintf(fp, "%u\n", (uint) pid);
fclose(fp);
msg("mariabackup: DEBUG: Suspending at debug sync point '%s'. "
- "Resume with 'kill -SIGCONT %u'.\n", name, (uint) pid);
+ "Resume with 'kill -SIGCONT %u'.", name, (uint) pid);
debug_sync_resumed= 0;
kill(pid, SIGSTOP);
@@ -1343,13 +1463,13 @@ debug_sync_point(const char *name)
}
/* On resume */
- msg("mariabackup: DEBUG: removing the pid file.\n");
+ msg("mariabackup: DEBUG: removing the pid file.");
my_delete(pid_path, MYF(MY_WME));
#endif
}
-static std::vector<std::string> tables_for_export;
+static std::set<std::string> tables_for_export;
static void append_export_table(const char *dbname, const char *tablename, bool is_remote)
{
@@ -1361,7 +1481,15 @@ static void append_export_table(const char *dbname, const char *tablename, bool
char *p=strrchr(buf, '.');
if (p) *p=0;
- tables_for_export.push_back(ut_get_name(0,buf));
+ std::string name=ut_get_name(0, buf);
+ /* Strip partition name comment from table name, if any */
+ if (ends_with(name.c_str(), "*/"))
+ {
+ size_t pos= name.rfind("/*");
+ if (pos != std::string::npos)
+ name.resize(pos);
+ }
+ tables_for_export.insert(name);
}
}
@@ -1376,9 +1504,10 @@ static int create_bootstrap_file()
fputs("SET NAMES UTF8;\n",f);
enumerate_ibd_files(append_export_table);
- for (size_t i= 0; i < tables_for_export.size(); i++)
+ for (std::set<std::string>::iterator it = tables_for_export.begin();
+ it != tables_for_export.end(); it++)
{
- const char *tab = tables_for_export[i].c_str();
+ const char *tab = it->c_str();
fprintf(f,
"BEGIN NOT ATOMIC "
"DECLARE CONTINUE HANDLER FOR NOT FOUND,SQLEXCEPTION BEGIN END;"
@@ -1408,7 +1537,7 @@ static int prepare_export()
snprintf(cmdline, sizeof cmdline,
IF_WIN("\"","") "\"%s\" --mysqld \"%s\" "
" --defaults-extra-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=."
- " --innodb --innodb-fast-shutdown=0"
+ " --innodb --innodb-fast-shutdown=0 --loose-partition"
" --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu"
" --console --skip-log-error --bootstrap < " BOOTSTRAP_FILENAME IF_WIN("\"",""),
mariabackup_exe,
@@ -1420,7 +1549,7 @@ static int prepare_export()
sprintf(cmdline,
IF_WIN("\"","") "\"%s\" --mysqld"
" --defaults-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=."
- " --innodb --innodb-fast-shutdown=0"
+ " --innodb --innodb-fast-shutdown=0 --loose-partition"
" --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu"
" --console --log-error= --bootstrap < " BOOTSTRAP_FILENAME IF_WIN("\"",""),
mariabackup_exe,
@@ -1454,7 +1583,7 @@ static const char *xb_server_default_groups[]=
static void print_version(void)
{
- msg("%s based on MariaDB server %s %s (%s) \n",
+ msg("%s based on MariaDB server %s %s (%s)",
my_progname, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE);
}
@@ -1579,7 +1708,7 @@ xb_get_one_option(int optid,
xtrabackup_stream_fmt = XB_STREAM_FMT_XBSTREAM;
else
{
- msg("Invalid --stream argument: %s\n", argument);
+ msg("Invalid --stream argument: %s", argument);
return 1;
}
xtrabackup_stream = TRUE;
@@ -1589,7 +1718,7 @@ xb_get_one_option(int optid,
xtrabackup_compress_alg = "quicklz";
else if (strcasecmp(argument, "quicklz"))
{
- msg("Invalid --compress argument: %s\n", argument);
+ msg("Invalid --compress argument: %s", argument);
return 1;
}
xtrabackup_compress = TRUE;
@@ -1654,8 +1783,10 @@ static bool innodb_init_param()
/* === some variables from mysqld === */
memset((G_PTR) &mysql_tmpdir_list, 0, sizeof(mysql_tmpdir_list));
- if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir))
+ if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir)) {
+ msg("init_tmpdir() failed");
return true;
+ }
xtrabackup_tmpdir = my_tmpdir(&mysql_tmpdir_list);
/* dummy for initialize all_charsets[] */
get_charset_name(0);
@@ -1673,9 +1804,9 @@ static bool innodb_init_param()
srv_page_size_shift = ulong(n_shift);
srv_page_size = 1U << n_shift;
msg("InnoDB: The universal page size of the "
- "database is set to %lu.\n", srv_page_size);
+ "database is set to %lu.", srv_page_size);
} else {
- msg("InnoDB: Error: invalid value of "
+ msg("invalid value of "
"innobase_page_size: %lld", innobase_page_size);
goto error;
}
@@ -1688,12 +1819,12 @@ static bool innodb_init_param()
if (sizeof(ulint) == 4) {
if (xtrabackup_use_memory > UINT_MAX32) {
msg("mariabackup: use-memory can't be over 4GB"
- " on 32-bit systems\n");
+ " on 32-bit systems");
}
if (innobase_buffer_pool_size > UINT_MAX32) {
msg("mariabackup: innobase_buffer_pool_size can't be "
- "over 4GB on 32-bit systems\n");
+ "over 4GB on 32-bit systems");
goto error;
}
@@ -1706,10 +1837,10 @@ static bool innodb_init_param()
read from MySQL .cnf file */
if (xtrabackup_backup) {
- msg("mariabackup: using the following InnoDB configuration:\n");
+ msg("mariabackup: using the following InnoDB configuration:");
} else {
msg("mariabackup: using the following InnoDB configuration "
- "for recovery:\n");
+ "for recovery:");
}
/*--------------- Data files -------------------------*/
@@ -1718,7 +1849,7 @@ static bool innodb_init_param()
srv_data_home = (xtrabackup_backup && innobase_data_home_dir
? innobase_data_home_dir : default_path);
- msg("mariabackup: innodb_data_home_dir = %s\n", srv_data_home);
+ msg("innodb_data_home_dir = %s", srv_data_home);
/* Set default InnoDB data file size to 10 MB and let it be
auto-extending. Thus users can use InnoDB in >= 4.0 without having
@@ -1727,7 +1858,7 @@ static bool innodb_init_param()
if (!innobase_data_file_path) {
innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
}
- msg("mariabackup: innodb_data_file_path = %s\n",
+ msg("innodb_data_file_path = %s",
innobase_data_file_path);
/* This is the first time univ_page_size is used.
@@ -1757,13 +1888,12 @@ static bool innodb_init_param()
if (xtrabackup_prepare && xtrabackup_incremental_dir) {
srv_log_group_home_dir = xtrabackup_incremental_dir;
}
- msg("mariabackup: innodb_log_group_home_dir = %s\n",
+ msg("innodb_log_group_home_dir = %s",
srv_log_group_home_dir);
os_normalize_path(srv_log_group_home_dir);
if (strchr(srv_log_group_home_dir, ';')) {
-
msg("syntax error in innodb_log_group_home_dir, ");
goto error;
}
@@ -1811,8 +1941,7 @@ static bool innodb_init_param()
#elif defined(LINUX_NATIVE_AIO)
if (srv_use_native_aio) {
- ut_print_timestamp(stderr);
- msg(" InnoDB: Using Linux native AIO\n");
+ msg("InnoDB: Using Linux native AIO");
}
#else
/* Currently native AIO is supported only on windows and linux
@@ -1857,7 +1986,7 @@ static bool innodb_init()
}
if (err != DB_SUCCESS) {
- msg("mariabackup: innodb_init() returned %d (%s).\n",
+ msg("mariabackup: innodb_init() returned %d (%s).",
err, ut_strerr(err));
innodb_shutdown();
return(TRUE);
@@ -1881,7 +2010,7 @@ xtrabackup_read_metadata(char *filename)
fp = fopen(filename,"r");
if(!fp) {
- msg("mariabackup: Error: cannot open %s\n", filename);
+ msg("Error: cannot open %s", filename);
return(FALSE);
}
@@ -1960,8 +2089,7 @@ xtrabackup_stream_metadata(ds_ctxt_t *ds_ctxt)
stream = ds_open(ds_ctxt, XTRABACKUP_METADATA_FILENAME, &mystat);
if (stream == NULL) {
- msg("mariabackup: Error: cannot open output stream "
- "for %s\n", XTRABACKUP_METADATA_FILENAME);
+ msg("Error: cannot open output stream for %s", XTRABACKUP_METADATA_FILENAME);
return(FALSE);
}
@@ -1993,7 +2121,7 @@ xtrabackup_write_metadata(const char *filepath)
fp = fopen(filepath, "w");
if(!fp) {
- msg("mariabackup: Error: cannot open %s\n", filepath);
+ msg("Error: cannot open %s", filepath);
return(FALSE);
}
if (fwrite(buf, len, 1, fp) < 1) {
@@ -2042,7 +2170,7 @@ xb_read_delta_metadata(const char *filepath, xb_delta_info_t *info)
fclose(fp);
if (page_size == ULINT_UNDEFINED) {
- msg("mariabackup: page_size is required in %s\n", filepath);
+ msg("page_size is required in %s", filepath);
r = FALSE;
} else {
info->page_size = page_size_t(zip_size ? zip_size : page_size,
@@ -2052,7 +2180,7 @@ xb_read_delta_metadata(const char *filepath, xb_delta_info_t *info)
if (info->space_id == ULINT_UNDEFINED) {
msg("mariabackup: Warning: This backup was taken with XtraBackup 2.0.1 "
"or earlier, some DDL operations between full and incremental "
- "backups may be handled incorrectly\n");
+ "backups may be handled incorrectly");
}
return(r);
@@ -2085,8 +2213,7 @@ xb_write_delta_metadata(const char *filename, const xb_delta_info_t *info)
f = ds_open(ds_meta, filename, &mystat);
if (f == NULL) {
- msg("mariabackup: Error: cannot open output stream for %s\n",
- filename);
+ msg("Error: Can't open output stream for %s",filename);
return(FALSE);
}
@@ -2260,6 +2387,18 @@ check_if_skip_table(
const char *ptr;
char *eptr;
+
+ dbname = NULL;
+ tbname = name;
+ while ((ptr = strchr(tbname, '/')) != NULL) {
+ dbname = tbname;
+ tbname = ptr + 1;
+ }
+
+ if (strncmp(tbname, tmp_file_prefix, tmp_file_prefix_length) == 0) {
+ return TRUE;
+ }
+
if (regex_exclude_list.empty() &&
regex_include_list.empty() &&
tables_include_hash == NULL &&
@@ -2269,13 +2408,6 @@ check_if_skip_table(
return(FALSE);
}
- dbname = NULL;
- tbname = name;
- while ((ptr = strchr(tbname, '/')) != NULL) {
- dbname = tbname;
- tbname = ptr + 1;
- }
-
if (dbname == NULL) {
return(FALSE);
}
@@ -2394,7 +2526,7 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
if (fil_is_user_tablespace_id(node->space->id)
&& check_if_skip_table(node_name)) {
- msg("[%02u] Skipping %s.\n", thread_n, node_name);
+ msg(thread_n, "Skipping %s.", node_name);
return(FALSE);
}
@@ -2440,26 +2572,22 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
if (write_filter->init != NULL &&
!write_filter->init(&write_filt_ctxt, dst_name, &cursor)) {
- msg("[%02u] mariabackup: error: "
- "failed to initialize page write filter.\n", thread_n);
+ msg (thread_n, "mariabackup: error: failed to initialize page write filter.");
goto error;
}
dstfile = ds_open(ds_data, dst_name, &cursor.statinfo);
if (dstfile == NULL) {
- msg("[%02u] mariabackup: error: "
- "cannot open the destination stream for %s\n",
- thread_n, dst_name);
+ msg(thread_n,"mariabackup: error: can't open the destination stream for %s", dst_name);
goto error;
}
action = xb_get_copy_action();
if (xtrabackup_stream) {
- msg_ts("[%02u] %s %s\n", thread_n, action, node_path);
+ msg(thread_n, "%s %s", action, node_path);
} else {
- msg_ts("[%02u] %s %s to %s\n", thread_n, action,
- node_path, dstfile->path);
+ msg(thread_n, "%s %s to %s", action, node_path, dstfile->path);
}
/* The main copy loop */
@@ -2483,7 +2611,7 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n, const char *dest_name=
pthread_mutex_unlock(&backup_mutex);
/* close */
- msg_ts("[%02u] ...done\n", thread_n);
+ msg(thread_n," ...done");
xb_fil_cur_close(&cursor);
if (ds_close(dstfile)) {
rc = TRUE;
@@ -2501,8 +2629,7 @@ error:
if (write_filter && write_filter->deinit) {
write_filter->deinit(&write_filt_ctxt);;
}
- msg("[%02u] mariabackup: Error: "
- "xtrabackup_copy_datafile() failed.\n", thread_n);
+ msg(thread_n, "mariabackup: xtrabackup_copy_datafile() failed.");
return(TRUE); /*ERROR*/
skip:
@@ -2513,11 +2640,7 @@ skip:
if (write_filter && write_filter->deinit) {
write_filter->deinit(&write_filt_ctxt);
}
- msg("[%02u] mariabackup: Warning: We assume the "
- "table was dropped during xtrabackup execution "
- "and ignore the file.\n", thread_n);
- msg("[%02u] mariabackup: Warning: skipping tablespace %s.\n",
- thread_n, node_name);
+ msg(thread_n,"Warning: We assume the table was dropped during xtrabackup execution and ignore the tablespace %s", node_name);
return(FALSE);
}
@@ -2542,9 +2665,8 @@ static lsn_t xtrabackup_copy_log(lsn_t start_lsn, lsn_t end_lsn, bool last)
&& scanned_checkpoint - checkpoint >= 0x80000000UL) {
/* Garbage from a log buffer flush which was made
before the most recent database recovery */
- msg("mariabackup: checkpoint wrap: "
- LSN_PF ",%zx,%zx\n",
- scanned_lsn, scanned_checkpoint, checkpoint);
+ msg(0,"checkpoint wrap: " LSN_PF ",%zx,%zx",
+ scanned_lsn, scanned_checkpoint, checkpoint);
break;
}
@@ -2564,8 +2686,7 @@ static lsn_t xtrabackup_copy_log(lsn_t start_lsn, lsn_t end_lsn, bool last)
} else if (data_len >= log_sys.trailer_offset()
|| data_len <= LOG_BLOCK_HDR_SIZE) {
/* We got a garbage block (abrupt end of the log). */
- msg("mariabackup: garbage block: " LSN_PF ",%zu\n",
- scanned_lsn, data_len);
+ msg(0,"garbage block: " LSN_PF ",%zu",scanned_lsn, data_len);
break;
} else {
/* We got a partial block (abrupt end of the log). */
@@ -2576,7 +2697,7 @@ static lsn_t xtrabackup_copy_log(lsn_t start_lsn, lsn_t end_lsn, bool last)
if (more_data && recv_parse_log_recs(0, STORE_NO, false)) {
- msg("mariabackup: copying the log failed \n");
+ msg("Error: copying the log failed");
return(0);
}
@@ -2595,8 +2716,7 @@ static lsn_t xtrabackup_copy_log(lsn_t start_lsn, lsn_t end_lsn, bool last)
}
if (ds_write(dst_log_file, log_sys.buf, write_size)) {
- msg("mariabackup: Error: "
- "write to logfile failed\n");
+ msg("Error: write to logfile failed");
return(0);
}
}
@@ -2632,7 +2752,7 @@ static bool xtrabackup_copy_logfile(bool last = false)
|| lsn != start_lsn) {
break;
}
- msg("Retrying read of log at LSN=" LSN_PF "\n", lsn);
+ msg("Retrying read of log at LSN=" LSN_PF, lsn);
my_sleep(1000);
}
@@ -2642,15 +2762,13 @@ static bool xtrabackup_copy_logfile(bool last = false)
log_mutex_exit();
if (!start_lsn) {
- msg("mariabackup: Error: xtrabackup_copy_logfile()"
- " failed.\n");
- exit(EXIT_FAILURE);
+ die("xtrabackup_copy_logfile() failed.");
}
} while (start_lsn == end_lsn);
ut_ad(start_lsn == log_sys.log.scanned_lsn);
- msg_ts(">> log scanned up to (" LSN_PF ")\n", start_lsn);
+ msg(">> log scanned up to (" LSN_PF ")", start_lsn);
/* update global variable*/
pthread_mutex_lock(&backup_mutex);
@@ -2759,7 +2877,7 @@ static void dbug_mariabackup_event(const char *event,const char *key)
}
char *sql = getenv(envvar);
if (sql) {
- msg("dbug_mariabackup_event : executing '%s'\n", sql);
+ msg("dbug_mariabackup_event : executing '%s'", sql);
xb_mysql_query(mysql_connection, sql, false, true);
}
@@ -2790,24 +2908,19 @@ DECLARE_THREAD(data_copy_thread_func)(
debug_sync_point("data_copy_thread_func");
while ((node = datafiles_iter_next(ctxt->it)) != NULL) {
-
DBUG_MARIABACKUP_EVENT("before_copy", node->space->name);
-
-
/* copy the datafile */
if(xtrabackup_copy_datafile(node, num)) {
- msg("[%02u] mariabackup: Error: "
- "failed to copy datafile.\n", num);
- exit(EXIT_FAILURE);
+ die("failed to copy datafile.");
}
DBUG_MARIABACKUP_EVENT("after_copy", node->space->name);
}
- pthread_mutex_lock(&ctxt->count_mutex);
+ pthread_mutex_lock(ctxt->count_mutex);
(*ctxt->count)--;
- pthread_mutex_unlock(&ctxt->count_mutex);
+ pthread_mutex_unlock(ctxt->count_mutex);
my_thread_end();
os_thread_exit();
@@ -2974,12 +3087,19 @@ xb_load_single_table_tablespace(
Datafile *file = xb_new_datafile(name, is_remote);
if (file->open_read_only(true) != DB_SUCCESS) {
- msg("Can't open datafile %s\n", name);
- ut_free(name);
- exit(EXIT_FAILURE);
+ die("Can't open datafile %s", name);
}
- err = file->validate_first_page(&flush_lsn);
+ for (int i = 0; i < 10; i++) {
+ err = file->validate_first_page(&flush_lsn);
+ if (err != DB_CORRUPTION) {
+ break;
+ }
+
+ my_sleep(1000);
+ }
+
+ bool is_empty_file = file->exists() && file->is_empty_file();
if (err == DB_SUCCESS && file->space_id() != SRV_TMP_SPACE_ID) {
os_offset_t node_size = os_file_get_size(file->handle());
@@ -2995,11 +3115,8 @@ xb_load_single_table_tablespace(
ut_a(space != NULL);
- if (!fil_node_create(file->filepath(), ulint(n_pages), space,
- false, false)) {
- ut_error;
- }
-
+ space->add(file->filepath(), OS_FILE_CLOSED, ulint(n_pages),
+ false, false);
/* by opening the tablespace we forcing node and space objects
in the cache to be populated with fields from space header */
space->open();
@@ -3014,10 +3131,8 @@ xb_load_single_table_tablespace(
delete file;
- if (err != DB_SUCCESS && err != DB_CORRUPTION && xtrabackup_backup) {
- /* allow corrupted first page for xtrabackup, it could be just
- zero-filled page, which we restore from redo log later */
- exit(EXIT_FAILURE);
+ if (err != DB_SUCCESS && xtrabackup_backup && !is_empty_file) {
+ die("Failed to not validate first page of the file %s, error %d",name, (int)err);
}
}
@@ -3163,35 +3278,24 @@ the first slot rollback segments of TRX_SYS_PAGE_NO.
@retval DB_SUCCESS if srv_undo_space_id assigned successfully. */
static dberr_t xb_assign_undo_space_start()
{
- ulint dirnamelen;
- char name[1000];
+
pfs_os_file_t file;
byte* buf;
byte* page;
bool ret;
dberr_t error = DB_SUCCESS;
ulint space, page_no __attribute__((unused));
+ int n_retries = 5;
if (srv_undo_tablespaces == 0) {
return error;
}
- os_normalize_path(srv_data_home);
- dirnamelen = strlen(srv_data_home);
- memcpy(name, srv_data_home, dirnamelen);
-
- if (dirnamelen && name[dirnamelen - 1] != OS_PATH_SEPARATOR) {
- name[dirnamelen++] = OS_PATH_SEPARATOR;
- }
-
- snprintf(name + dirnamelen, (sizeof name) - dirnamelen,
- "%s", "ibdata1");
-
- file = os_file_create(0, name, OS_FILE_OPEN,
- OS_FILE_NORMAL, OS_DATA_FILE, true, &ret);
+ file = os_file_create(0, srv_sys_space.first_datafile()->filepath(),
+ OS_FILE_OPEN, OS_FILE_NORMAL, OS_DATA_FILE, true, &ret);
if (!ret) {
- msg("mariabackup: Error in opening %s\n", name);
+ msg("Error opening %s", srv_sys_space.first_datafile()->filepath());
return DB_ERROR;
}
@@ -3202,14 +3306,21 @@ retry:
if (!os_file_read(IORequestRead, file, page,
TRX_SYS_PAGE_NO << srv_page_size_shift,
srv_page_size)) {
- msg("mariabackup: Reading TRX_SYS page failed.\n");
+ msg("Reading TRX_SYS page failed.\n");
error = DB_ERROR;
goto func_exit;
}
/* TRX_SYS page can't be compressed or encrypted. */
if (buf_page_is_corrupted(false, page, univ_page_size)) {
- goto retry;
+ if (n_retries--) {
+ os_thread_sleep(1000);
+ goto retry;
+ } else {
+ msg("mariabackup: TRX_SYS page corrupted.\n");
+ error = DB_ERROR;
+ goto func_exit;
+ }
}
/* 0th slot always points to system tablespace.
@@ -3253,16 +3364,22 @@ xb_load_tablespaces()
/* create_new_db must not be true. */
if (err != DB_SUCCESS || create_new_db) {
- msg("mariabackup: could not find data files at the "
- "specified datadir\n");
+ msg("Could not find data files at the specified datadir");
return(DB_ERROR);
}
- err = srv_sys_space.open_or_create(false, false, &sum_of_new_sizes,
- &flush_lsn);
+ for (int i= 0; i < 10; i++) {
+ err = srv_sys_space.open_or_create(false, false, &sum_of_new_sizes,
+ &flush_lsn);
+ if (err == DB_PAGE_CORRUPTED || err == DB_CORRUPTION) {
+ my_sleep(1000);
+ }
+ else
+ break;
+ }
if (err != DB_SUCCESS) {
- msg("mariabackup: Could not open data files.\n");
+ msg("Could not open data files.\n");
return(err);
}
@@ -3284,7 +3401,7 @@ xb_load_tablespaces()
srv_undo_tablespaces_init(), because fil_is_user_tablespace_id() *
relies on srv_undo_tablespaces_open to be properly initialized */
- msg("mariabackup: Generating a list of tablespaces\n");
+ msg("mariabackup: Generating a list of tablespaces");
err = enumerate_ibd_files(xb_load_single_table_tablespace);
if (err != DB_SUCCESS) {
@@ -3387,13 +3504,11 @@ xb_validate_name(
/* perform only basic validation. validate length and
path symbols */
if (len > NAME_LEN) {
- msg("mariabackup: name `%s` is too long.\n", name);
- exit(EXIT_FAILURE);
+ die("name `%s` is too long.", name);
}
p = strpbrk(name, "/\\~");
if (p && (uint) (p - name) < NAME_LEN) {
- msg("mariabackup: name `%s` is not valid.\n", name);
- exit(EXIT_FAILURE);
+ die("name `%s` is not valid.", name);
}
}
@@ -3471,8 +3586,7 @@ xb_register_table(
const char* name) /*!< in: name of table */
{
if (strchr(name, '.') == NULL) {
- msg("mariabackup: `%s` is not fully qualified name.\n", name);
- exit(EXIT_FAILURE);
+ die("`%s` is not fully qualified name.", name);
}
xb_register_include_filter_entry(name);
@@ -3493,7 +3607,7 @@ xb_add_regex_to_list(
if (ret != 0) {
regerror(ret, &compiled_regex, errbuf, sizeof(errbuf));
- msg("mariabackup: error: %s regcomp(%s): %s\n",
+ msg("mariabackup: error: %s regcomp(%s): %s",
error_context, regex, errbuf);
exit(EXIT_FAILURE);
}
@@ -3562,17 +3676,15 @@ xb_load_list_file(
/* read and store the filenames */
fp = fopen(filename, "r");
if (!fp) {
- msg("mariabackup: cannot open %s\n",
+ die("Can't open %s",
filename);
- exit(EXIT_FAILURE);
}
while (fgets(name_buf, sizeof(name_buf), fp) != NULL) {
char* p = strchr(name_buf, '\n');
if (p) {
*p = '\0';
} else {
- msg("mariabackup: `%s...` name is too long", name_buf);
- exit(EXIT_FAILURE);
+ die("`%s...` name is too long", name_buf);
}
ins(name_buf);
@@ -3680,22 +3792,17 @@ xb_filters_free()
}
/*********************************************************************//**
-Creates or opens the log files and closes them.
-@return DB_SUCCESS or error code */
+Create log file metadata. */
static
-ulint
+void
open_or_create_log_file(
/*====================*/
fil_space_t* space,
- ibool* log_file_created, /*!< out: TRUE if new log file
- created */
ulint i) /*!< in: log file number in group */
{
char name[10000];
ulint dirnamelen;
- *log_file_created = FALSE;
-
os_normalize_path(srv_log_group_home_dir);
dirnamelen = strlen(srv_log_group_home_dir);
@@ -3707,14 +3814,13 @@ open_or_create_log_file(
name[dirnamelen++] = OS_PATH_SEPARATOR;
}
- sprintf(name + dirnamelen, "%s%lu", "ib_logfile", (ulong) i);
+ sprintf(name + dirnamelen, "%s%zu", "ib_logfile", i);
ut_a(fil_validate());
- ut_a(fil_node_create(name, ulint(srv_log_file_size >> srv_page_size_shift),
- space, false, false));
-
- return(DB_SUCCESS);
+ space->add(name, OS_FILE_CLOSED,
+ ulint(srv_log_file_size >> srv_page_size_shift),
+ false, false);
}
/***********************************************************************
@@ -3818,10 +3924,10 @@ static bool xtrabackup_backup_low()
metadata_to_lsn = mach_read_from_8(
log_sys.checkpoint_buf + LOG_CHECKPOINT_LSN);
msg("mariabackup: The latest check point"
- " (for incremental): '" LSN_PF "'\n",
+ " (for incremental): '" LSN_PF "'",
metadata_to_lsn);
} else {
- msg("mariabackup: Error: recv_find_max_checkpoint() failed.\n");
+ msg("Error: recv_find_max_checkpoint() failed.");
}
log_mutex_exit();
}
@@ -3851,7 +3957,7 @@ static bool xtrabackup_backup_low()
metadata_last_lsn = log_copy_scanned_lsn;
if (!xtrabackup_stream_metadata(ds_meta)) {
- msg("mariabackup: Error: failed to stream metadata.\n");
+ msg("Error: failed to stream metadata.");
return false;
}
if (xtrabackup_extra_lsndir) {
@@ -3860,15 +3966,15 @@ static bool xtrabackup_backup_low()
sprintf(filename, "%s/%s", xtrabackup_extra_lsndir,
XTRABACKUP_METADATA_FILENAME);
if (!xtrabackup_write_metadata(filename)) {
- msg("mariabackup: Error: failed to write metadata "
- "to '%s'.\n", filename);
+ msg("Error: failed to write metadata "
+ "to '%s'.", filename);
return false;
}
sprintf(filename, "%s/%s", xtrabackup_extra_lsndir,
XTRABACKUP_INFO);
if (!write_xtrabackup_info(mysql_connection, filename, false)) {
- msg("mariabackup: Error: failed to write info "
- "to '%s'.\n", filename);
+ msg("Error: failed to write info "
+ "to '%s'.", filename);
return false;
}
}
@@ -3891,19 +3997,19 @@ xtrabackup_backup_func()
pthread_cond_init(&scanned_lsn_cond, NULL);
#ifdef USE_POSIX_FADVISE
- msg("mariabackup: uses posix_fadvise().\n");
+ msg("uses posix_fadvise().");
#endif
/* cd to datadir */
if (my_setwd(mysql_real_data_home,MYF(MY_WME)))
{
- msg("mariabackup: cannot my_setwd %s\n", mysql_real_data_home);
+ msg("my_setwd() failed , %s", mysql_real_data_home);
return(false);
}
- msg("mariabackup: cd to %s\n", mysql_real_data_home);
+ msg("cd to %s", mysql_real_data_home);
encryption_plugin_backup_init(mysql_connection);
- msg("mariabackup: open files limit requested %u, set to %u\n",
+ msg("open files limit requested %u, set to %u",
(uint) xb_open_files_limit,
xb_set_max_open_files(xb_open_files_limit));
@@ -3918,12 +4024,6 @@ xtrabackup_backup_func()
log_file_op = backup_file_op;
metadata_to_lsn = 0;
- if (xb_close_files)
- msg("mariabackup: warning: close-files specified. Use it "
- "at your own risk. If there are DDL operations like table DROP TABLE "
- "or RENAME TABLE during the backup, inconsistent backup will be "
- "produced.\n");
-
/* initialize components */
if(innodb_init_param()) {
fail:
@@ -3974,13 +4074,6 @@ fail:
xb_filters_init();
- {
- ibool log_file_created;
- ibool log_created = FALSE;
- ibool log_opened = FALSE;
- ulint err;
- ulint i;
-
xb_fil_io_init();
srv_n_file_io_threads = srv_n_read_io_threads;
@@ -3993,43 +4086,15 @@ fail:
"innodb_redo_log", SRV_LOG_SPACE_FIRST_ID, 0,
FIL_TYPE_LOG, NULL);
- for (i = 0; i < srv_n_log_files; i++) {
- err = open_or_create_log_file(space, &log_file_created, i);
- if (err != DB_SUCCESS) {
- goto fail;
- }
-
- if (log_file_created) {
- log_created = TRUE;
- } else {
- log_opened = TRUE;
- }
- if ((log_opened && log_created)) {
- msg(
- "mariabackup: Error: all log files must be created at the same time.\n"
- "mariabackup: All log files must be created also in database creation.\n"
- "mariabackup: If you want bigger or smaller log files, shut down the\n"
- "mariabackup: database and make sure there were no errors in shutdown.\n"
- "mariabackup: Then delete the existing log files. Edit the .cnf file\n"
- "mariabackup: and start the database again.\n");
-
- goto fail;
- }
- }
-
- /* log_file_created must not be TRUE, if online */
- if (log_file_created) {
- msg("mariabackup: Something wrong with source files...\n");
- goto fail;
- }
-
+ for (ulint i = 0; i < srv_n_log_files; i++) {
+ open_or_create_log_file(space, i);
}
/* create extra LSN dir if it does not exist. */
if (xtrabackup_extra_lsndir
&&!my_stat(xtrabackup_extra_lsndir,&stat_info,MYF(0))
&& (my_mkdir(xtrabackup_extra_lsndir,0777,MYF(0)) < 0)) {
- msg("mariabackup: Error: cannot mkdir %d: %s\n",
+ msg("Error: cannot mkdir %d: %s\n",
my_errno, xtrabackup_extra_lsndir);
goto fail;
}
@@ -4037,7 +4102,7 @@ fail:
/* create target dir if not exist */
if (!xtrabackup_stream_str && !my_stat(xtrabackup_target_dir,&stat_info,MYF(0))
&& (my_mkdir(xtrabackup_target_dir,0777,MYF(0)) < 0)){
- msg("mariabackup: Error: cannot mkdir %d: %s\n",
+ msg("Error: cannot mkdir %d: %s\n",
my_errno, xtrabackup_target_dir);
goto fail;
}
@@ -4048,7 +4113,6 @@ fail:
/* start back ground thread to copy newer log */
os_thread_id_t log_copying_thread_id;
- datafiles_iter_t *it;
/* get current checkpoint_lsn */
/* Look for the latest checkpoint from any of the log groups */
@@ -4065,8 +4129,8 @@ log_fail:
if (log_sys.log.format == 0) {
old_format:
- msg("mariabackup: Error: cannot process redo log"
- " before MariaDB 10.2.2\n");
+ msg("Error: cannot process redo log"
+ " before MariaDB 10.2.2");
log_mutex_exit();
goto log_fail;
}
@@ -4105,8 +4169,8 @@ reread_log_header:
memset(&stat_info, 0, sizeof(MY_STAT));
dst_log_file = ds_open(ds_redo, "ib_logfile0", &stat_info);
if (dst_log_file == NULL) {
- msg("mariabackup: error: failed to open the target stream for "
- "'ib_logfile0'.\n");
+ msg("§rror: failed to open the target stream for "
+ "'ib_logfile0'.");
goto fail;
}
@@ -4124,7 +4188,7 @@ reread_log_header:
/* Write the log header. */
if (ds_write(dst_log_file, log_hdr, sizeof log_hdr)) {
log_write_fail:
- msg("mariabackup: error: write to logfile failed\n");
+ msg("error: write to logfile failed");
goto fail;
}
/* Adjust the checkpoint page. */
@@ -4159,8 +4223,8 @@ reread_log_header:
/* Populate fil_system with tablespaces to copy */
err = xb_load_tablespaces();
if (err != DB_SUCCESS) {
- msg("mariabackup: error: xb_load_tablespaces() failed with"
- " error %s.\n", ut_strerr(err));
+ msg("merror: xb_load_tablespaces() failed with"
+ " error %s.", ut_strerr(err));
fail_before_log_copying_thread_start:
log_copying_running = false;
goto fail;
@@ -4183,25 +4247,12 @@ fail_before_log_copying_thread_start:
}
debug_sync_point("xtrabackup_suspend_at_start");
- if (xtrabackup_incremental) {
- if (!xtrabackup_incremental_force_scan) {
- changed_page_bitmap = xb_page_bitmap_init();
- }
- if (!changed_page_bitmap) {
- msg("mariabackup: using the full scan for incremental "
- "backup\n");
- } else if (incremental_lsn != checkpoint_lsn_start) {
- /* Do not print that bitmaps are used when dummy bitmap
- is build for an empty LSN range. */
- msg("mariabackup: using the changed page bitmap\n");
- }
- }
ut_a(xtrabackup_parallel > 0);
if (xtrabackup_parallel > 1) {
msg("mariabackup: Starting %u threads for parallel data "
- "files transfer\n", xtrabackup_parallel);
+ "files transfer", xtrabackup_parallel);
}
if (opt_lock_ddl_per_table) {
@@ -4210,12 +4261,12 @@ fail_before_log_copying_thread_start:
DBUG_EXECUTE_IF("check_mdl_lock_works",
dbug_alter_thread_done =
dbug_start_query_thread("ALTER TABLE test.t ADD COLUMN mdl_lock_column int",
- "Waiting for table metadata lock", 1, ER_QUERY_INTERRUPTED););
+ "Waiting for table metadata lock", 0, 0););
}
- it = datafiles_iter_new();
+ datafiles_iter_t *it = datafiles_iter_new();
if (it == NULL) {
- msg("mariabackup: Error: datafiles_iter_new() failed.\n");
+ msg("mariabackup: Error: datafiles_iter_new() failed.");
goto fail;
}
@@ -4229,7 +4280,7 @@ fail_before_log_copying_thread_start:
data_threads[i].it = it;
data_threads[i].num = i+1;
data_threads[i].count = &count;
- data_threads[i].count_mutex = count_mutex;
+ data_threads[i].count_mutex = &count_mutex;
os_thread_create(data_copy_thread_func, data_threads + i,
&data_threads[i].id);
}
@@ -4276,16 +4327,16 @@ fail_before_log_copying_thread_start:
}
xtrabackup_destroy_datasinks();
- msg("mariabackup: Redo log (from LSN " LSN_PF " to " LSN_PF
- ") was copied.\n", checkpoint_lsn_start, log_copy_scanned_lsn);
+ msg("Redo log (from LSN " LSN_PF " to " LSN_PF
+ ") was copied.", checkpoint_lsn_start, log_copy_scanned_lsn);
xb_filters_free();
xb_data_files_close();
/* Make sure that the latest checkpoint was included */
if (metadata_to_lsn > log_copy_scanned_lsn) {
- msg("mariabackup: error: failed to copy enough redo log ("
- "LSN=" LSN_PF "; checkpoint LSN=" LSN_PF ").\n",
+ msg("Error: failed to copy enough redo log ("
+ "LSN=" LSN_PF "; checkpoint LSN=" LSN_PF ").",
log_copy_scanned_lsn, metadata_to_lsn);
goto fail;
}
@@ -4322,6 +4373,14 @@ void backup_fix_ddl(void)
std::set<std::string> dropped_tables;
std::map<std::string, std::string> renamed_tables;
+ /* Disable further DDL on backed up tables (only needed for --no-lock).*/
+ pthread_mutex_lock(&backup_mutex);
+ log_file_op = backup_file_op_fail;
+ log_optimized_ddl_op = backup_optimized_ddl_op_fail;
+ pthread_mutex_unlock(&backup_mutex);
+
+ DBUG_MARIABACKUP_EVENT("backup_fix_ddl",0);
+
for (space_id_to_name_t::iterator iter = ddl_tracker.tables_in_backup.begin();
iter != ddl_tracker.tables_in_backup.end();
iter++) {
@@ -4418,8 +4477,9 @@ void backup_fix_ddl(void)
}
fil_space_free(n->space->id, false);
}
+ datafiles_iter_free(it);
-
+ DBUG_EXECUTE_IF("check_mdl_lock_works", DBUG_ASSERT(new_tables.size() == 0););
for (std::set<std::string>::iterator iter = new_tables.begin();
iter != new_tables.end(); iter++) {
const char *space_name = iter->c_str();
@@ -4434,7 +4494,7 @@ void backup_fix_ddl(void)
const char *dbname = buf;
char *p = strchr(buf, '/');
if (p == 0) {
- msg("Unexpected tablespace %s filename %s\n", space_name, name.c_str());
+ msg("Unexpected tablespace %s filename %s", space_name, name.c_str());
ut_a(0);
}
ut_a(p);
@@ -4453,18 +4513,10 @@ void backup_fix_ddl(void)
continue;
std::string dest_name(node->space->name);
dest_name.append(".new");
-#if 0
- bool do_full_copy = ddl_tracker.optimized_ddl.find(n->space->id) != ddl_tracker.optimized_ddl.end();
- if (do_full_copy) {
- msg(
- "Performing a full copy of the tablespace %s, because optimized (without redo logging) DDL operation"
- "ran during backup. You can use set innodb_log_optimize_ddl=OFF to improve backup performance"
- "in the future.\n",
- n->space->name);
- }
-#endif
xtrabackup_copy_datafile(node, 0, dest_name.c_str()/*, do_full_copy ? ULONGLONG_MAX:UNIV_PAGE_SIZE */);
}
+
+ datafiles_iter_free(it);
}
/* ================= prepare ================= */
@@ -4515,7 +4567,7 @@ xb_space_create_file(
*file = os_file_create_simple_no_error_handling(
0, path, OS_FILE_CREATE, OS_FILE_READ_WRITE, false, &ret);
if (!ret) {
- msg("mariabackup: cannot create file %s\n", path);
+ msg("Can't create file %s", path);
return ret;
}
@@ -4523,7 +4575,7 @@ xb_space_create_file(
FIL_IBD_FILE_INITIAL_SIZE
<< srv_page_size_shift);
if (!ret) {
- msg("mariabackup: cannot set size for file %s\n", path);
+ msg("mariabackup: cannot set size for file %s", path);
os_file_close(*file);
os_file_delete(0, path);
return ret;
@@ -4567,7 +4619,7 @@ xb_space_create_file(
free(buf);
if (!ret) {
- msg("mariabackup: could not write the first page to %s\n",
+ msg("mariabackup: could not write the first page to %s",
path);
os_file_close(*file);
os_file_delete(0, path);
@@ -4638,7 +4690,7 @@ xb_delta_open_matching_space(
/* Create the database directory if it doesn't exist yet */
if (!os_file_create_directory(dest_dir, FALSE)) {
- msg("mariabackup: error: cannot create dir %s\n", dest_dir);
+ msg("mariabackup: error: cannot create dir %s", dest_dir);
return file;
}
@@ -4685,12 +4737,12 @@ exit:
snprintf(tmpname, FN_REFLEN, "%s/xtrabackup_tmp_#" ULINTPF,
dbname, fil_space->id);
- msg("mariabackup: Renaming %s to %s.ibd\n",
+ msg("mariabackup: Renaming %s to %s.ibd",
fil_space->name, tmpname);
if (fil_space->rename(tmpname, NULL, false)
!= DB_SUCCESS) {
- msg("mariabackup: Cannot rename %s to %s\n",
+ msg("mariabackup: Cannot rename %s to %s",
fil_space->name, tmpname);
goto exit;
}
@@ -4699,9 +4751,8 @@ exit:
if (info.space_id == ULINT_UNDEFINED)
{
- msg("mariabackup: Error: Cannot handle DDL operation on tablespace "
+ die("Can't handle DDL operation on tablespace "
"%s\n", dest_space_name);
- exit(EXIT_FAILURE);
}
mutex_enter(&fil_system.mutex);
fil_space = fil_space_get_by_id(info.space_id);
@@ -4711,12 +4762,12 @@ exit:
strncpy(tmpname, dest_space_name, FN_REFLEN);
- msg("mariabackup: Renaming %s to %s\n",
+ msg("mariabackup: Renaming %s to %s",
fil_space->name, dest_space_name);
if (fil_space->rename(tmpname, NULL, false) != DB_SUCCESS)
{
- msg("mariabackup: Cannot rename %s to %s\n",
+ msg("mariabackup: Cannot rename %s to %s",
fil_space->name, dest_space_name);
goto exit;
}
@@ -4744,8 +4795,7 @@ exit:
*success = xb_space_create_file(real_name, info.space_id,
flags, &file);
} else {
- msg("mariabackup: Cannot create tablespace %s\n",
- dest_space_name);
+ msg("Can't create tablespace %s\n", dest_space_name);
}
goto exit;
@@ -4815,12 +4865,12 @@ xtrabackup_apply_delta(
page_size = info.page_size.physical();
page_size_shift = get_bit_shift(page_size);
- msg("mariabackup: page size for %s is %zu bytes\n",
+ msg("page size for %s is %zu bytes",
src_path, page_size);
if (page_size_shift < 10 ||
page_size_shift > UNIV_PAGE_SIZE_SHIFT_MAX) {
- msg("mariabackup: error: invalid value of page_size "
- "(%zu bytes) read from %s\n", page_size, meta_path);
+ msg("error: invalid value of page_size "
+ "(%zu bytes) read from %s", page_size, meta_path);
goto error;
}
@@ -4829,7 +4879,7 @@ xtrabackup_apply_delta(
OS_FILE_OPEN, OS_FILE_READ_WRITE, false, &success);
if (!success) {
os_file_get_last_error(TRUE);
- msg("mariabackup: error: cannot open %s\n", src_path);
+ msg("error: can't open %s", src_path);
goto error;
}
@@ -4839,7 +4889,7 @@ xtrabackup_apply_delta(
dbname, space_name, info,
dst_path, sizeof(dst_path), &success);
if (!success) {
- msg("mariabackup: error: cannot open %s\n", dst_path);
+ msg("error: can't open %s", dst_path);
goto error;
}
@@ -4852,7 +4902,7 @@ xtrabackup_apply_delta(
(ut_align(incremental_buffer_base,
page_size));
- msg("Applying %s to %s...\n", src_path, dst_path);
+ msg("Applying %s to %s...", src_path, dst_path);
while (!last_buffer) {
ulint cluster_header;
@@ -4875,8 +4925,8 @@ xtrabackup_apply_delta(
last_buffer = TRUE;
break;
default:
- msg("mariabackup: error: %s seems not "
- ".delta file.\n", src_path);
+ msg("error: %s seems not "
+ ".delta file.", src_path);
goto error;
}
@@ -4974,7 +5024,7 @@ error:
os_file_close(src_file);
if (dst_file != OS_FILE_CLOSED)
os_file_close(dst_file);
- msg("mariabackup: Error: xtrabackup_apply_delta(): "
+ msg("Error: xtrabackup_apply_delta(): "
"failed to apply %s to %s.\n", src_path, dst_path);
return FALSE;
}
@@ -4992,8 +5042,7 @@ std::string change_extension(std::string filename, std::string new_ext) {
static void rename_file(const char *from,const char *to) {
msg("Renaming %s to %s\n", from, to);
if (my_rename(from, to, MY_WME)) {
- msg("Cannot rename %s to %s errno %d", from, to, errno);
- exit(EXIT_FAILURE);
+ die("Can't rename %s to %s errno %d", from, to, errno);
}
}
@@ -5014,7 +5063,7 @@ typedef ibool (*handle_datadir_entry_func_t)(
/** Rename, and replace destination file, if exists */
static void rename_force(const char *from, const char *to) {
if (access(to, R_OK) == 0) {
- msg("Removing %s\n", to);
+ msg("Removing %s", to);
if (my_delete(to, MYF(MY_WME))) {
msg("Can't remove %s, errno %d", to, errno);
exit(EXIT_FAILURE);
@@ -5122,6 +5171,7 @@ xb_process_datadir(
path, NULL,
fileinfo.name, NULL))
{
+ os_file_closedir(dbdir);
return(FALSE);
}
}
@@ -5133,16 +5183,14 @@ next_file_item_1:
os_file_closedir(dbdir);
} else {
- msg("mariabackup: Cannot open dir %s\n",
- path);
+ msg("Can't open dir %s", path);
}
/* single table tablespaces */
dir = os_file_opendir(path, FALSE);
if (dir == NULL) {
- msg("mariabackup: Cannot open dir %s\n",
- path);
+ msg("Can't open dir %s", path);
}
ret = fil_file_readdir_next_file(&err, path, dir,
@@ -5183,6 +5231,7 @@ next_file_item_1:
dbinfo.name,
fileinfo.name, NULL))
{
+ os_file_closedir(dbdir);
return(FALSE);
}
}
@@ -5237,7 +5286,7 @@ store_binlog_info(const char* filename, const char* name, ulonglong pos)
FILE *fp = fopen(filename, "w");
if (!fp) {
- msg("mariabackup: failed to open '%s'\n", filename);
+ msg("mariabackup: failed to open '%s'", filename);
return(false);
}
@@ -5258,7 +5307,7 @@ static std::string read_file_as_string(const std::string file) {
char content[FN_REFLEN];
FILE *f = fopen(file.c_str(), "r");
if (!f) {
- msg("Can not open %s\n", file.c_str());
+ msg("Can not open %s", file.c_str());
}
size_t len = fread(content, 1, FN_REFLEN, f);
fclose(f);
@@ -5270,8 +5319,7 @@ static void delete_file(const std::string& file, bool if_exists = false) {
if (if_exists && !file_exists(file))
return;
if (my_delete(file.c_str(), MYF(MY_WME))) {
- msg("Can't remove %s, errno %d", file.c_str(), errno);
- exit(EXIT_FAILURE);
+ die("Can't remove %s, errno %d", file.c_str(), errno);
}
}
@@ -5355,14 +5403,21 @@ xtrabackup_prepare_func(char** argv)
if (my_setwd(xtrabackup_real_target_dir,MYF(MY_WME)))
{
- msg("mariabackup: cannot my_setwd %s\n",
- xtrabackup_real_target_dir);
+ msg("can't my_setwd %s", xtrabackup_real_target_dir);
return(false);
}
- msg("mariabackup: cd to %s\n", xtrabackup_real_target_dir);
+ msg("cd to %s", xtrabackup_real_target_dir);
fil_path_to_mysql_datadir = ".";
+ /* Fix DDL for prepare. Process .del,.ren, and .new files.
+ The order in which files are processed, is important
+ (see MDEV-18185, MDEV-18201)
+ */
+ xb_process_datadir(xtrabackup_incremental_dir ? xtrabackup_incremental_dir : ".",
+ ".del", prepare_handle_del_files);
+ xb_process_datadir(xtrabackup_incremental_dir? xtrabackup_incremental_dir:".",
+ ".ren", prepare_handle_ren_files);
if (xtrabackup_incremental_dir) {
xb_process_datadir(xtrabackup_incremental_dir, ".new.meta", prepare_handle_new_files);
xb_process_datadir(xtrabackup_incremental_dir, ".new.delta", prepare_handle_new_files);
@@ -5370,11 +5425,6 @@ xtrabackup_prepare_func(char** argv)
else {
xb_process_datadir(".", ".new", prepare_handle_new_files);
}
- xb_process_datadir(xtrabackup_incremental_dir? xtrabackup_incremental_dir:".",
- ".ren", prepare_handle_ren_files);
- xb_process_datadir(xtrabackup_incremental_dir ? xtrabackup_incremental_dir : ".",
- ".del", prepare_handle_del_files);
-
int argc; for (argc = 0; argv[argc]; argc++) {}
encryption_plugin_prepare_init(argc, argv);
@@ -5392,32 +5442,31 @@ xtrabackup_prepare_func(char** argv)
XTRABACKUP_METADATA_FILENAME);
if (!xtrabackup_read_metadata(metadata_path)) {
- msg("mariabackup: Error: failed to read metadata from '%s'\n",
+ msg("Error: failed to read metadata from '%s'\n",
metadata_path);
return(false);
}
if (!strcmp(metadata_type, "full-backuped")) {
if (xtrabackup_incremental) {
- msg("mariabackup: error: applying incremental backup "
- "needs a prepared target.\n");
+ msg("error: applying incremental backup "
+ "needs a prepared target.");
return(false);
}
- msg("mariabackup: This target seems to be not prepared yet.\n");
+ msg("This target seems to be not prepared yet.");
} else if (!strcmp(metadata_type, "log-applied")) {
- msg("mariabackup: This target seems to be already prepared.\n");
+ msg("This target seems to be already prepared.");
} else {
- msg("mariabackup: This target does not have correct metadata.\n");
+ msg("This target does not have correct metadata.");
return(false);
}
bool ok = !xtrabackup_incremental
|| metadata_to_lsn == incremental_lsn;
if (!ok) {
- msg("mariabackup: error: This incremental backup seems "
- "not to be proper for the target.\n"
- "mariabackup: Check 'to_lsn' of the target and "
- "'from_lsn' of the incremental.\n");
+ msg("error: This incremental backup seems "
+ "not to be proper for the target. Check 'to_lsn' of the target and "
+ "'from_lsn' of the incremental.");
return(false);
}
@@ -5493,9 +5542,10 @@ xtrabackup_prepare_func(char** argv)
srv_n_write_io_threads = 4;
}
- msg("mariabackup: Starting InnoDB instance for recovery.\n"
- "mariabackup: Using %lld bytes for buffer pool "
- "(set by --use-memory parameter)\n", xtrabackup_use_memory);
+ msg("Starting InnoDB instance for recovery.");
+
+ msg("mariabackup: Using %lld bytes for buffer pool "
+ "(set by --use-memory parameter)", xtrabackup_use_memory);
srv_max_buf_pool_modified_pct = (double)max_buf_pool_modified_pct;
@@ -5508,7 +5558,7 @@ xtrabackup_prepare_func(char** argv)
}
if (ok) {
- msg("Last binlog file %s, position %lld\n",
+ msg("Last binlog file %s, position %lld",
trx_sys.recovered_binlog_filename,
longlong(trx_sys.recovered_binlog_offset));
@@ -5532,7 +5582,7 @@ xtrabackup_prepare_func(char** argv)
&& srv_start_lsn < target_lsn) {
msg("mariabackup: error: "
"The log was only applied up to LSN " LSN_PF
- ", instead of " LSN_PF "\n",
+ ", instead of " LSN_PF,
srv_start_lsn, target_lsn);
ok = false;
}
@@ -5560,13 +5610,13 @@ xtrabackup_prepare_func(char** argv)
if (!xtrabackup_write_metadata(filename)) {
msg("mariabackup: Error: failed to write metadata "
- "to '%s'\n", filename);
+ "to '%s'", filename);
ok = false;
} else if (xtrabackup_extra_lsndir) {
sprintf(filename, "%s/%s", xtrabackup_extra_lsndir, XTRABACKUP_METADATA_FILENAME);
if (!xtrabackup_write_metadata(filename)) {
msg("mariabackup: Error: failed to write "
- "metadata to '%s'\n", filename);
+ "metadata to '%s'", filename);
ok = false;
}
}
@@ -5601,6 +5651,153 @@ append_defaults_group(const char *group, const char *default_groups[],
ut_a(appended);
}
+static const char*
+normalize_privilege_target_name(const char* name)
+{
+ if (strcmp(name, "*") == 0) {
+ return "\\*";
+ }
+ else {
+ /* should have no regex special characters. */
+ ut_ad(strpbrk(name, ".()[]*+?") == 0);
+ }
+ return name;
+}
+
+/******************************************************************//**
+Check if specific privilege is granted.
+Uses regexp magic to check if requested privilege is granted for given
+database.table or database.* or *.*
+or if user has 'ALL PRIVILEGES' granted.
+@return true if requested privilege is granted, false otherwise. */
+static bool
+has_privilege(const std::list<std::string> &granted,
+ const char* required,
+ const char* db_name,
+ const char* table_name)
+{
+ char buffer[1000];
+ regex_t priv_re;
+ regmatch_t tables_regmatch[1];
+ bool result = false;
+
+ db_name = normalize_privilege_target_name(db_name);
+ table_name = normalize_privilege_target_name(table_name);
+
+ int written = snprintf(buffer, sizeof(buffer),
+ "GRANT .*(%s)|(ALL PRIVILEGES).* ON (\\*|`%s`)\\.(\\*|`%s`)",
+ required, db_name, table_name);
+ if (written < 0 || written == sizeof(buffer)
+ || regcomp(&priv_re, buffer, REG_EXTENDED)) {
+ die("regcomp() failed for '%s'", buffer);
+ }
+
+ typedef std::list<std::string>::const_iterator string_iter;
+ for (string_iter i = granted.begin(), e = granted.end(); i != e; ++i) {
+ int res = regexec(&priv_re, i->c_str(),
+ 1, tables_regmatch, 0);
+
+ if (res != REG_NOMATCH) {
+ result = true;
+ break;
+ }
+ }
+
+ xb_regfree(&priv_re);
+ return result;
+}
+
+enum {
+ PRIVILEGE_OK = 0,
+ PRIVILEGE_WARNING = 1,
+ PRIVILEGE_ERROR = 2,
+};
+
+/******************************************************************//**
+Check if specific privilege is granted.
+Prints error message if required privilege is missing.
+@return PRIVILEGE_OK if requested privilege is granted, error otherwise. */
+static
+int check_privilege(
+ const std::list<std::string> &granted_priv, /* in: list of
+ granted privileges*/
+ const char* required, /* in: required privilege name */
+ const char* target_database, /* in: required privilege target
+ database name */
+ const char* target_table, /* in: required privilege target
+ table name */
+ int error = PRIVILEGE_ERROR) /* in: return value if privilege
+ is not granted */
+{
+ if (!has_privilege(granted_priv,
+ required, target_database, target_table)) {
+ msg("%s: missing required privilege %s on %s.%s",
+ (error == PRIVILEGE_ERROR ? "Error" : "Warning"),
+ required, target_database, target_table);
+ return error;
+ }
+ return PRIVILEGE_OK;
+}
+
+
+/**
+Check DB user privileges according to the intended actions.
+
+Fetches DB user privileges, determines intended actions based on
+command-line arguments and prints missing privileges.
+@return whether all the necessary privileges are granted */
+static bool check_all_privileges()
+{
+ if (!mysql_connection) {
+ /* Not connected, no queries is going to be executed. */
+ return true;
+ }
+
+ /* Fetch effective privileges. */
+ std::list<std::string> granted_privileges;
+ MYSQL_RES* result = xb_mysql_query(mysql_connection, "SHOW GRANTS",
+ true);
+ while (MYSQL_ROW row = mysql_fetch_row(result)) {
+ granted_privileges.push_back(*row);
+ }
+ mysql_free_result(result);
+
+ int check_result = PRIVILEGE_OK;
+
+ /* FLUSH TABLES WITH READ LOCK */
+ if (!opt_no_lock)
+ {
+ check_result |= check_privilege(
+ granted_privileges,
+ "RELOAD", "*", "*");
+ check_result |= check_privilege(
+ granted_privileges,
+ "PROCESS", "*", "*");
+ }
+
+ /* KILL ... */
+ if ((!opt_no_lock && (opt_kill_long_queries_timeout || opt_lock_ddl_per_table))
+ /* START SLAVE SQL_THREAD */
+ /* STOP SLAVE SQL_THREAD */
+ || opt_safe_slave_backup) {
+ check_result |= check_privilege(
+ granted_privileges,
+ "SUPER", "*", "*",
+ PRIVILEGE_WARNING);
+ }
+
+ /* SHOW MASTER STATUS */
+ /* SHOW SLAVE STATUS */
+ if (opt_galera_info || opt_slave_info
+ || (opt_no_lock && opt_safe_slave_backup)) {
+ check_result |= check_privilege(granted_privileges,
+ "REPLICATION CLIENT", "*", "*",
+ PRIVILEGE_WARNING);
+ }
+
+ return !(check_result & PRIVILEGE_ERROR);
+}
+
bool
xb_init()
{
@@ -5614,7 +5811,7 @@ xb_init()
&& !opt_safe_slave_backup) {
msg("Error: --slave-info is used with --no-lock but "
"without --safe-slave-backup. The binlog position "
- "cannot be consistent with the backup data.\n");
+ "cannot be consistent with the backup data.");
return(false);
}
@@ -5665,7 +5862,9 @@ xb_init()
if (!get_mysql_vars(mysql_connection)) {
return(false);
}
-
+ if (opt_check_privileges && !check_all_privileges()) {
+ return(false);
+ }
history_start_time = time(NULL);
}
@@ -5834,21 +6033,13 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server)
char *optend = strcend((argv)[i], '=');
if (optend - argv[i] == 15 &&
- !strncmp(argv[i], "--defaults-file", optend - argv[i])) {
-
- msg("mariabackup: Error: --defaults-file "
- "must be specified first on the command "
- "line\n");
- exit(EXIT_FAILURE);
+ !strncmp(argv[i], "--defaults-file", optend - argv[i])) {
+ die("--defaults-file must be specified first on the command line");
}
- if (optend - argv[i] == 21 &&
- !strncmp(argv[i], "--defaults-extra-file",
- optend - argv[i])) {
-
- msg("mariabackup: Error: --defaults-extra-file "
- "must be specified first on the command "
- "line\n");
- exit(EXIT_FAILURE);
+ if (optend - argv[i] == 21 &&
+ !strncmp(argv[i], "--defaults-extra-file",
+ optend - argv[i])) {
+ die("--defaults-extra-file must be specified first on the command line");
}
}
@@ -5895,7 +6086,7 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server)
if (!server_option) {
msg("mariabackup: Error:"
- " unknown argument: '%s'\n", opt);
+ " unknown argument: '%s'", opt);
exit(EXIT_FAILURE);
}
}
@@ -5951,7 +6142,7 @@ int main(int argc, char **argv)
if (mysql_server_init(-1, NULL, NULL))
{
- exit(EXIT_FAILURE);
+ die("mysql_server_init() failed");
}
system_charset_info = &my_charset_utf8_general_ci;
@@ -5995,7 +6186,7 @@ int main(int argc, char **argv)
mysql_mutex_destroy(&LOCK_error_log);
if (status == EXIT_SUCCESS) {
- msg_ts("completed OK!\n");
+ msg("completed OK!");
}
return status;
@@ -6013,7 +6204,7 @@ static int main_low(char** argv)
&& !strcmp(mysql_data_home, "./")) {
if (!xtrabackup_print_param)
usage();
- msg("\nmariabackup: Error: Please set parameter 'datadir'\n");
+ msg("mariabackup: Error: Please set parameter 'datadir'");
return(EXIT_FAILURE);
}
@@ -6084,7 +6275,7 @@ static int main_low(char** argv)
if (error) {
msg("mariabackup: value '%s' may be wrong format for "
- "incremental option.\n", xtrabackup_incremental);
+ "incremental option.", xtrabackup_incremental);
return(EXIT_FAILURE);
}
} else if (xtrabackup_backup && xtrabackup_incremental_basedir) {
@@ -6094,7 +6285,7 @@ static int main_low(char** argv)
if (!xtrabackup_read_metadata(filename)) {
msg("mariabackup: error: failed to read metadata from "
- "%s\n", filename);
+ "%s", filename);
return(EXIT_FAILURE);
}
@@ -6107,7 +6298,7 @@ static int main_low(char** argv)
if (!xtrabackup_read_metadata(filename)) {
msg("mariabackup: error: failed to read metadata from "
- "%s\n", filename);
+ "%s", filename);
return(EXIT_FAILURE);
}
@@ -6125,7 +6316,7 @@ static int main_low(char** argv)
}
if (xtrabackup_stream && !xtrabackup_backup) {
- msg("Warning: --stream parameter is ignored, it only works together with --backup.\n");
+ msg("Warning: --stream parameter is ignored, it only works together with --backup.");
}
if (!xb_init()) {
@@ -6140,13 +6331,13 @@ static int main_low(char** argv)
print_version();
if (xtrabackup_incremental) {
- msg("incremental backup from " LSN_PF " is enabled.\n",
+ msg("incremental backup from " LSN_PF " is enabled.",
incremental_lsn);
}
if (xtrabackup_export && innobase_file_per_table == FALSE) {
msg("mariabackup: auto-enabling --innodb-file-per-table due to "
- "the --export option\n");
+ "the --export option");
innobase_file_per_table = TRUE;
}
@@ -6184,8 +6375,7 @@ static int main_low(char** argv)
if (xtrabackup_copy_back || xtrabackup_move_back) {
if (!check_if_param_set("datadir")) {
- msg("Error: datadir must be specified.\n");
- return(EXIT_FAILURE);
+ mysql_data_home = get_default_datadir();
}
if (!copy_back())
return(EXIT_FAILURE);
@@ -6213,3 +6403,12 @@ static int get_exepath(char *buf, size_t size, const char *argv0)
return my_realpath(buf, argv0, 0);
}
+
+
+#if defined (__SANITIZE_ADDRESS__) && defined (__linux__)
+/* Avoid LeakSanitizer's false positives. */
+const char* __asan_default_options()
+{
+ return "detect_leaks=0";
+}
+#endif