summaryrefslogtreecommitdiff
path: root/extra/mariabackup
diff options
context:
space:
mode:
Diffstat (limited to 'extra/mariabackup')
-rw-r--r--extra/mariabackup/CMakeLists.txt4
-rw-r--r--extra/mariabackup/backup_copy.cc212
-rw-r--r--extra/mariabackup/backup_mysql.cc57
-rw-r--r--extra/mariabackup/backup_wsrep.h (renamed from extra/mariabackup/wsrep.h)4
-rw-r--r--extra/mariabackup/changed_page_bitmap.cc63
-rw-r--r--extra/mariabackup/encryption_plugin.cc21
-rw-r--r--extra/mariabackup/fil_cur.cc183
-rw-r--r--extra/mariabackup/fil_cur.h21
-rw-r--r--extra/mariabackup/innobackupex.cc21
-rw-r--r--extra/mariabackup/read_filt.cc15
-rw-r--r--extra/mariabackup/read_filt.h8
-rw-r--r--extra/mariabackup/write_filt.cc20
-rw-r--r--extra/mariabackup/xb0xb.h36
-rw-r--r--extra/mariabackup/xtrabackup.cc2636
-rw-r--r--extra/mariabackup/xtrabackup.h50
15 files changed, 1296 insertions, 2055 deletions
diff --git a/extra/mariabackup/CMakeLists.txt b/extra/mariabackup/CMakeLists.txt
index ac15460660c..f7202a7f3b7 100644
--- a/extra/mariabackup/CMakeLists.txt
+++ b/extra/mariabackup/CMakeLists.txt
@@ -30,7 +30,7 @@ ENDIF()
INCLUDE_DIRECTORIES(
${CMAKE_SOURCE_DIR}/include
- ${CMAKE_SOURCE_DIR}/storage/xtradb/include
+ ${CMAKE_SOURCE_DIR}/storage/innodb/include
${CMAKE_SOURCE_DIR}/sql
${CMAKE_CURRENT_SOURCE_DIR}/quicklz
${CMAKE_CURRENT_SOURCE_DIR}
@@ -74,9 +74,9 @@ MYSQL_ADD_EXECUTABLE(mariabackup
backup_mysql.cc
backup_copy.cc
encryption_plugin.cc
- ${PROJECT_SOURCE_DIR}/libmysql/libmysql.c
${PROJECT_SOURCE_DIR}/sql/net_serv.cc
${NT_SERVICE_SOURCE}
+ ${PROJECT_SOURCE_DIR}/libmysqld/libmysql.c
COMPONENT backup
)
diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc
index 156e0b20e7c..d9e2db0cb66 100644
--- a/extra/mariabackup/backup_copy.cc
+++ b/extra/mariabackup/backup_copy.cc
@@ -89,7 +89,7 @@ struct datadir_iter_t {
ulint filepath_len;
char *filepath_rel;
ulint filepath_rel_len;
- os_ib_mutex_t mutex;
+ pthread_mutex_t mutex;
os_file_dir_t dir;
os_file_dir_t dbdir;
os_file_stat_t dbinfo;
@@ -107,7 +107,7 @@ struct datadir_thread_ctxt_t {
datadir_iter_t *it;
uint n_thread;
uint *count;
- os_ib_mutex_t count_mutex;
+ pthread_mutex_t count_mutex;
os_thread_id_t id;
bool ret;
};
@@ -134,12 +134,12 @@ datadir_node_fill(datadir_node_t *node, datadir_iter_t *it)
{
if (node->filepath_len < it->filepath_len) {
free(node->filepath);
- node->filepath = (char*)(ut_malloc(it->filepath_len));
+ node->filepath = (char*)(malloc(it->filepath_len));
node->filepath_len = it->filepath_len;
}
if (node->filepath_rel_len < it->filepath_rel_len) {
free(node->filepath_rel);
- node->filepath_rel = (char*)(ut_malloc(it->filepath_rel_len));
+ node->filepath_rel = (char*)(malloc(it->filepath_rel_len));
node->filepath_rel_len = it->filepath_rel_len;
}
@@ -153,8 +153,8 @@ static
void
datadir_node_free(datadir_node_t *node)
{
- ut_free(node->filepath);
- ut_free(node->filepath_rel);
+ free(node->filepath);
+ free(node->filepath_rel);
memset(node, 0, sizeof(datadir_node_t));
}
@@ -178,10 +178,10 @@ datadir_iter_new(const char *path, bool skip_first_level = true)
{
datadir_iter_t *it;
- it = static_cast<datadir_iter_t *>(ut_malloc(sizeof(datadir_iter_t)));
+ it = static_cast<datadir_iter_t *>(malloc(sizeof(datadir_iter_t)));
memset(it, 0, sizeof(datadir_iter_t));
- it->mutex = os_mutex_create();
+ pthread_mutex_init(&it->mutex, NULL);
it->datadir_path = strdup(path);
it->dir = os_file_opendir(it->datadir_path, TRUE);
@@ -194,20 +194,20 @@ datadir_iter_new(const char *path, bool skip_first_level = true)
it->err = DB_SUCCESS;
it->dbpath_len = FN_REFLEN;
- it->dbpath = static_cast<char*>(ut_malloc(it->dbpath_len));
+ it->dbpath = static_cast<char*>(malloc(it->dbpath_len));
it->filepath_len = FN_REFLEN;
- it->filepath = static_cast<char*>(ut_malloc(it->filepath_len));
+ it->filepath = static_cast<char*>(malloc(it->filepath_len));
it->filepath_rel_len = FN_REFLEN;
- it->filepath_rel = static_cast<char*>(ut_malloc(it->filepath_rel_len));
+ it->filepath_rel = static_cast<char*>(malloc(it->filepath_rel_len));
it->skip_first_level = skip_first_level;
return(it);
error:
- ut_free(it);
+ free(it);
return(NULL);
}
@@ -246,19 +246,15 @@ datadir_iter_next_database(datadir_iter_t *it)
+ strlen (it->dbinfo.name) + 2;
if (len > it->dbpath_len) {
it->dbpath_len = len;
+ free(it->dbpath);
- if (it->dbpath) {
-
- ut_free(it->dbpath);
- }
-
- it->dbpath = static_cast<char*>
- (ut_malloc(it->dbpath_len));
+ it->dbpath = static_cast<char*>(
+ malloc(it->dbpath_len));
}
ut_snprintf(it->dbpath, it->dbpath_len,
"%s/%s", it->datadir_path,
it->dbinfo.name);
- srv_normalize_path_for_win(it->dbpath);
+ os_normalize_path(it->dbpath);
if (it->dbinfo.type == OS_FILE_TYPE_FILE) {
it->is_file = true;
@@ -306,8 +302,8 @@ make_path_n(int n, char **path, ulint *path_len, ...)
va_end(vl);
if (len_needed < *path_len) {
- ut_free(*path);
- *path = static_cast<char*>(ut_malloc(len_needed));
+ free(*path);
+ *path = static_cast<char*>(malloc(len_needed));
}
va_start(vl, path_len);
@@ -378,7 +374,7 @@ datadir_iter_next(datadir_iter_t *it, datadir_node_t *node)
{
bool ret = true;
- os_mutex_enter(it->mutex);
+ pthread_mutex_lock(&it->mutex);
if (datadir_iter_next_file(it)) {
@@ -413,7 +409,7 @@ datadir_iter_next(datadir_iter_t *it, datadir_node_t *node)
ret = false;
done:
- os_mutex_exit(it->mutex);
+ pthread_mutex_unlock(&it->mutex);
return(ret);
}
@@ -427,7 +423,7 @@ static
void
datadir_iter_free(datadir_iter_t *it)
{
- os_mutex_free(it->mutex);
+ pthread_mutex_destroy(&it->mutex);
if (it->dbdir) {
@@ -439,11 +435,11 @@ datadir_iter_free(datadir_iter_t *it)
os_file_closedir(it->dir);
}
- ut_free(it->dbpath);
- ut_free(it->filepath);
- ut_free(it->filepath_rel);
+ free(it->dbpath);
+ free(it->filepath);
+ free(it->filepath_rel);
free(it->datadir_path);
- ut_free(it);
+ free(it);
}
@@ -466,17 +462,17 @@ static
void
datafile_close(datafile_cur_t *cursor)
{
- if (cursor->file != 0) {
+ if (cursor->file != OS_FILE_CLOSED) {
os_file_close(cursor->file);
}
- ut_free(cursor->buf);
+ free(cursor->buf);
}
static
bool
datafile_open(const char *file, datafile_cur_t *cursor, uint thread_n)
{
- ulint success;
+ bool success;
memset(cursor, 0, sizeof(datafile_cur_t));
@@ -490,11 +486,9 @@ datafile_open(const char *file, datafile_cur_t *cursor, uint thread_n)
xb_get_relative_path(cursor->abs_path, FALSE),
sizeof(cursor->rel_path));
- cursor->file = os_file_create_simple_no_error_handling(0,
- cursor->abs_path,
- OS_FILE_OPEN,
- OS_FILE_READ_ONLY,
- &success, 0);
+ cursor->file = os_file_create_simple_no_error_handling(
+ 0, cursor->abs_path,
+ OS_FILE_OPEN, OS_FILE_READ_ALLOW_DELETE, true, &success);
if (!success) {
/* The following call prints an error message */
os_file_get_last_error(TRUE);
@@ -518,7 +512,7 @@ datafile_open(const char *file, datafile_cur_t *cursor, uint thread_n)
posix_fadvise(cursor->file, 0, 0, POSIX_FADV_SEQUENTIAL);
cursor->buf_size = 10 * 1024 * 1024;
- cursor->buf = static_cast<byte *>(ut_malloc((ulint)cursor->buf_size));
+ cursor->buf = static_cast<byte *>(malloc((ulint)cursor->buf_size));
return(true);
}
@@ -528,7 +522,6 @@ static
xb_fil_cur_result_t
datafile_read(datafile_cur_t *cursor)
{
- ulint success;
ulint to_read;
xtrabackup_io_throttling();
@@ -540,14 +533,14 @@ datafile_read(datafile_cur_t *cursor)
return(XB_FIL_CUR_EOF);
}
- success = os_file_read(cursor->file, cursor->buf, cursor->buf_offset,
- to_read);
- if (!success) {
+ if (!os_file_read(IORequestRead,
+ cursor->file, cursor->buf, cursor->buf_offset,
+ to_read)) {
return(XB_FIL_CUR_ERROR);
}
posix_fadvise(cursor->file, cursor->buf_offset, to_read,
- POSIX_FADV_DONTNEED);
+ POSIX_FADV_DONTNEED);
cursor->buf_read = to_read;
cursor->buf_offset += to_read;
@@ -917,13 +910,13 @@ run_data_threads(datadir_iter_t *it, os_thread_func_t func, uint n)
{
datadir_thread_ctxt_t *data_threads;
uint i, count;
- os_ib_mutex_t count_mutex;
+ pthread_mutex_t count_mutex;
bool ret;
data_threads = (datadir_thread_ctxt_t*)
- (ut_malloc(sizeof(datadir_thread_ctxt_t) * n));
+ malloc(sizeof(datadir_thread_ctxt_t) * n);
- count_mutex = os_mutex_create();
+ pthread_mutex_init(&count_mutex, NULL);
count = n;
for (i = 0; i < n; i++) {
@@ -937,15 +930,15 @@ run_data_threads(datadir_iter_t *it, os_thread_func_t func, uint n)
/* Wait for threads to exit */
while (1) {
os_thread_sleep(100000);
- os_mutex_enter(count_mutex);
+ pthread_mutex_lock(&count_mutex);
if (count == 0) {
- os_mutex_exit(count_mutex);
+ pthread_mutex_unlock(&count_mutex);
break;
}
- os_mutex_exit(count_mutex);
+ pthread_mutex_unlock(&count_mutex);
}
- os_mutex_free(count_mutex);
+ pthread_mutex_destroy(&count_mutex);
ret = true;
for (i = 0; i < n; i++) {
@@ -955,7 +948,7 @@ run_data_threads(datadir_iter_t *it, os_thread_func_t func, uint n)
}
}
- ut_free(data_threads);
+ free(data_threads);
return(ret);
}
@@ -974,7 +967,6 @@ copy_file(ds_ctxt_t *datasink,
ds_file_t *dstfile = NULL;
datafile_cur_t cursor;
xb_fil_cur_result_t res;
- const char *action;
if (!datafile_open(src_file_path, &cursor, thread_n)) {
goto error_close;
@@ -991,9 +983,8 @@ copy_file(ds_ctxt_t *datasink,
goto error;
}
- action = xb_get_copy_action();
msg_ts("[%02u] %s %s to %s\n",
- thread_n, action, src_file_path, dstfile->path);
+ thread_n, xb_get_copy_action(), src_file_path, dstfile->path);
/* The main copy loop */
while ((res = datafile_read(&cursor)) == XB_FIL_CUR_SUCCESS) {
@@ -1111,7 +1102,7 @@ read_link_file(const char *ibd_filepath, const char *link_filepath)
while (lastch > 4 && filepath[lastch] <= 0x20) {
filepath[lastch--] = 0x00;
}
- srv_normalize_path_for_win(filepath);
+ os_normalize_path(filepath);
}
tablespace_locations[ibd_filepath] = filepath;
@@ -1629,14 +1620,9 @@ apply_log_finish()
return(true);
}
-extern void
-os_io_init_simple(void);
-
bool
copy_back()
{
- char *innobase_data_file_path_copy;
- ulint i;
bool ret;
datadir_iter_t *it = NULL;
datadir_node_t node;
@@ -1679,24 +1665,16 @@ copy_back()
if (!innobase_data_file_path) {
innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
}
- innobase_data_file_path_copy = strdup(innobase_data_file_path);
- if (!(ret = srv_parse_data_file_paths_and_sizes(
- innobase_data_file_path_copy))) {
+ srv_sys_space.set_path(".");
+
+ if (!srv_sys_space.parse_params(innobase_data_file_path, true)) {
msg("syntax error in innodb_data_file_path\n");
return(false);
}
srv_max_n_threads = 1000;
- //os_sync_mutex = NULL;
- ut_mem_init();
- /* temporally dummy value to avoid crash */
- srv_page_size_shift = 14;
- srv_page_size = (1 << srv_page_size_shift);
- os_sync_init();
- sync_init();
- os_io_init_simple();
- mem_init(srv_mem_pool_size);
+ sync_check_init();
ut_crc32_init();
/* copy undo tablespaces */
@@ -1707,9 +1685,9 @@ copy_back()
ds_data = ds_create(dst_dir, DS_TYPE_LOCAL);
- for (i = 1; i <= srv_undo_tablespaces; i++) {
+ for (ulong i = 1; i <= srv_undo_tablespaces; i++) {
char filename[20];
- sprintf(filename, "undo%03u", (uint)i);
+ sprintf(filename, "undo%03lu", i);
if (!(ret = copy_or_move_file(filename, filename,
dst_dir, 1))) {
goto cleanup;
@@ -1720,29 +1698,30 @@ copy_back()
ds_data = NULL;
}
- /* copy redo logs */
-
dst_dir = (srv_log_group_home_dir && *srv_log_group_home_dir)
- ? srv_log_group_home_dir : mysql_data_home;
-
- ds_data = ds_create(dst_dir, DS_TYPE_LOCAL);
+ ? srv_log_group_home_dir : mysql_data_home;
- for (i = 0; i < (ulong)innobase_log_files_in_group; i++) {
- char filename[20];
- sprintf(filename, "ib_logfile%lu", i);
-
- if (!file_exists(filename)) {
- continue;
- }
+ /* --backup generates a single ib_logfile0, which we must copy
+ if it exists. */
- if (!(ret = copy_or_move_file(filename, filename,
- dst_dir, 1))) {
- goto cleanup;
+ ds_data = ds_create(dst_dir, DS_TYPE_LOCAL);
+ if (!file_exists("ib_logfile0")) {
+ /* After completed --prepare, redo log files are redundant.
+ We must delete any redo logs at the destination, so that
+ the database will not jump to a different log sequence number
+ (LSN). */
+
+ for (uint i = 0; i <= SRV_N_LOG_FILES_MAX + 1; i++) {
+ char filename[FN_REFLEN];
+ snprintf(filename, sizeof filename, "%s/ib_logfile%u",
+ dst_dir, i);
+ unlink(filename);
}
+ } else if (!(ret = copy_or_move_file("ib_logfile0", "ib_logfile0",
+ dst_dir, 1))) {
+ goto cleanup;
}
-
ds_destroy(ds_data);
- ds_data = NULL;
/* copy innodb system tablespace(s) */
@@ -1751,17 +1730,19 @@ copy_back()
ds_data = ds_create(dst_dir, DS_TYPE_LOCAL);
- for (i = 0; i < srv_n_data_files; i++) {
- const char *filename = base_name(srv_data_file_names[i]);
+ for (Tablespace::const_iterator iter(srv_sys_space.begin()),
+ end(srv_sys_space.end());
+ iter != end;
+ ++iter) {
+ const char *filename = base_name(iter->name());
- if (!(ret = copy_or_move_file(filename, srv_data_file_names[i],
+ if (!(ret = copy_or_move_file(filename, iter->name(),
dst_dir, 1))) {
goto cleanup;
}
}
ds_destroy(ds_data);
- ds_data = NULL;
/* copy the rest of tablespaces */
ds_data = ds_create(mysql_data_home, DS_TYPE_LOCAL);
@@ -1771,7 +1752,7 @@ copy_back()
datadir_node_init(&node);
while (datadir_iter_next(it, &node)) {
- const char *ext_list[] = {"backup-my.cnf", "xtrabackup_logfile",
+ const char *ext_list[] = {"backup-my.cnf",
"xtrabackup_binary", "xtrabackup_binlog_info",
"xtrabackup_checkpoints", ".qp", ".pmap", ".tmp",
NULL};
@@ -1817,21 +1798,18 @@ copy_back()
continue;
}
- /* skip redo logs */
- if (sscanf(filename, "ib_logfile%d%c", &i_tmp, &c_tmp) == 1) {
+ /* skip the redo log (it was already copied) */
+ if (!strcmp(filename, "ib_logfile0")) {
continue;
}
/* skip innodb data files */
is_ibdata_file = false;
- for (i = 0; i < srv_n_data_files; i++) {
- const char *ibfile;
-
- ibfile = base_name(srv_data_file_names[i]);
-
- if (strcmp(ibfile, filename) == 0) {
+ for (Tablespace::const_iterator iter(srv_sys_space.begin()),
+ end(srv_sys_space.end()); iter != end; ++iter) {
+ if (strcmp(iter->name(), filename) == 0) {
is_ibdata_file = true;
- continue;
+ break;
}
}
if (is_ibdata_file) {
@@ -1873,20 +1851,13 @@ cleanup:
datadir_node_free(&node);
- free(innobase_data_file_path_copy);
-
if (ds_data != NULL) {
ds_destroy(ds_data);
}
ds_data = NULL;
- //os_sync_free();
- mem_close();
- //os_sync_mutex = NULL;
- ut_free_all_mem();
- sync_close();
- sync_initialized = FALSE;
+ sync_check_close();
return(ret);
}
@@ -1965,9 +1936,9 @@ cleanup:
datadir_node_free(&node);
- os_mutex_enter(ctxt->count_mutex);
+ pthread_mutex_lock(&ctxt->count_mutex);
--(*ctxt->count);
- os_mutex_exit(ctxt->count_mutex);
+ pthread_mutex_unlock(&ctxt->count_mutex);
ctxt->ret = ret;
@@ -1982,10 +1953,7 @@ decrypt_decompress()
datadir_iter_t *it = NULL;
srv_max_n_threads = 1000;
- //os_sync_mutex = NULL;
- ut_mem_init();
- os_sync_init();
- sync_init();
+ sync_check_init();
/* cd to backup directory */
if (my_setwd(xtrabackup_target_dir, MYF(MY_WME)))
@@ -2014,11 +1982,7 @@ decrypt_decompress()
ds_data = NULL;
- sync_close();
- sync_initialized = FALSE;
- //os_sync_free();
- //os_sync_mutex = NULL;
- ut_free_all_mem();
+ sync_check_close();
return(ret);
}
diff --git a/extra/mariabackup/backup_mysql.cc b/extra/mariabackup/backup_mysql.cc
index 2353c7692cb..c6ec54c3a6c 100644
--- a/extra/mariabackup/backup_mysql.cc
+++ b/extra/mariabackup/backup_mysql.cc
@@ -54,6 +54,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "mysqld.h"
#include "encryption_plugin.h"
#include <sstream>
+#include <sql_error.h>
char *tool_name;
@@ -494,7 +495,7 @@ get_mysql_vars(MYSQL *connection)
&& innodb_log_files_in_group_var) {
char *endptr;
- innobase_log_files_in_group = strtol(
+ srv_n_log_files = strtol(
innodb_log_files_in_group_var, &endptr, 10);
ut_ad(*endptr == 0);
}
@@ -503,7 +504,7 @@ get_mysql_vars(MYSQL *connection)
&& innodb_log_file_size_var) {
char *endptr;
- innobase_log_file_size = strtoll(
+ srv_log_file_size = strtoll(
innodb_log_file_size_var, &endptr, 10);
ut_ad(*endptr == 0);
}
@@ -850,9 +851,9 @@ static
void
start_query_killer()
{
- kill_query_thread_stop = os_event_create();
- kill_query_thread_started = os_event_create();
- kill_query_thread_stopped = os_event_create();
+ kill_query_thread_stop = os_event_create(0);
+ kill_query_thread_started = os_event_create(0);
+ kill_query_thread_stopped = os_event_create(0);
os_thread_create(kill_query_thread, NULL, &kill_query_thread_id);
@@ -1368,17 +1369,27 @@ cleanup:
return(result);
}
-static string escape_and_quote(MYSQL *mysql,const char *str)
+struct escape_and_quote
{
- if (!str)
- return "NULL";
- size_t len = strlen(str);
- char* escaped = (char *)alloca(2 * len + 3);
- escaped[0] = '\'';
- size_t new_len = mysql_real_escape_string(mysql, escaped+1, str, len);
- escaped[new_len + 1] = '\'';
- escaped[new_len + 2] = 0;
- return string(escaped);
+ escape_and_quote(MYSQL *mysql, const char *str)
+ : mysql(mysql), str(str) {}
+ MYSQL * const mysql;
+ const char * const str;
+};
+
+static
+std::ostream&
+operator<<(std::ostream& s, const escape_and_quote& eq)
+{
+ if (!eq.str)
+ return s << "NULL";
+ s << '\'';
+ size_t len = strlen(eq.str);
+ char* escaped = (char *)alloca(2 * len + 1);
+ len = mysql_real_escape_string(eq.mysql, escaped, eq.str, len);
+ s << std::string(escaped, len);
+ s << '\'';
+ return s;
}
/*********************************************************************//**
@@ -1395,12 +1406,9 @@ write_xtrabackup_info(MYSQL *connection)
char buf_start_time[100];
char buf_end_time[100];
tm tm;
- ostringstream oss;
+ std::ostringstream oss;
const char *xb_stream_name[] = {"file", "tar", "xbstream"};
-
- ut_ad(xtrabackup_stream_fmt < 3);
-
uuid = read_mysql_one_value(connection, "SELECT UUID()");
server_version = read_mysql_one_value(connection, "SELECT VERSION()");
localtime_r(&history_start_time, &tm);
@@ -1528,28 +1536,21 @@ bool write_backup_config_file()
"# The MySQL server\n"
"[mysqld]\n"
"innodb_checksum_algorithm=%s\n"
- "innodb_log_checksum_algorithm=%s\n"
"innodb_data_file_path=%s\n"
"innodb_log_files_in_group=%lu\n"
- "innodb_log_file_size=%lld\n"
+ "innodb_log_file_size=%llu\n"
"innodb_page_size=%lu\n"
- "innodb_log_block_size=%lu\n"
"innodb_undo_directory=%s\n"
"innodb_undo_tablespaces=%lu\n"
"%s%s\n"
- "%s%s\n"
"%s\n",
innodb_checksum_algorithm_names[srv_checksum_algorithm],
- innodb_checksum_algorithm_names[srv_log_checksum_algorithm],
innobase_data_file_path,
srv_n_log_files,
- innobase_log_file_size,
+ srv_log_file_size,
srv_page_size,
- srv_log_block_size,
srv_undo_dir,
srv_undo_tablespaces,
- innobase_doublewrite_file ? "innodb_doublewrite_file=" : "",
- innobase_doublewrite_file ? innobase_doublewrite_file : "",
innobase_buffer_pool_filename ?
"innodb_buffer_pool_filename=" : "",
innobase_buffer_pool_filename ?
diff --git a/extra/mariabackup/wsrep.h b/extra/mariabackup/backup_wsrep.h
index 7638d1f2b54..6537b304e12 100644
--- a/extra/mariabackup/wsrep.h
+++ b/extra/mariabackup/backup_wsrep.h
@@ -19,8 +19,8 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*******************************************************/
-#ifndef WSREP_H
-#define WSREP_H
+#ifndef BACKUP_WSREP_H
+#define BACKUP_WSREP_H
/***********************************************************************
Store Galera checkpoint info in the 'xtrabackup_galera_info' file, if that
diff --git a/extra/mariabackup/changed_page_bitmap.cc b/extra/mariabackup/changed_page_bitmap.cc
index 86a873ef69c..ce769375a16 100644
--- a/extra/mariabackup/changed_page_bitmap.cc
+++ b/extra/mariabackup/changed_page_bitmap.cc
@@ -193,9 +193,9 @@ log_online_read_bitmap_page(
ut_a(bitmap_file->offset
<= bitmap_file->size - MODIFIED_PAGE_BLOCK_SIZE);
ut_a(bitmap_file->offset % MODIFIED_PAGE_BLOCK_SIZE == 0);
-
- success = os_file_read(bitmap_file->file, page, bitmap_file->offset,
- MODIFIED_PAGE_BLOCK_SIZE);
+ success = os_file_read(IORequestRead,
+ bitmap_file->file, page, bitmap_file->offset,
+ MODIFIED_PAGE_BLOCK_SIZE);
if (UNIV_UNLIKELY(!success)) {
@@ -355,8 +355,7 @@ log_online_setup_bitmap_file_range(
bitmap_files->files =
static_cast<log_online_bitmap_file_range_t::files_t *>
- (ut_malloc(bitmap_files->count
- * sizeof(bitmap_files->files[0])));
+ (malloc(bitmap_files->count * sizeof(bitmap_files->files[0])));
memset(bitmap_files->files, 0,
bitmap_files->count * sizeof(bitmap_files->files[0]));
@@ -426,9 +425,9 @@ log_online_setup_bitmap_file_range(
/****************************************************************//**
Open a bitmap file for reading.
-@return TRUE if opened successfully */
+@return whether opened successfully */
static
-ibool
+bool
log_online_open_bitmap_file_read_only(
/*==================================*/
const char* name, /*!<in: bitmap file
@@ -438,23 +437,21 @@ log_online_open_bitmap_file_read_only(
log_online_bitmap_file_t* bitmap_file) /*!<out: opened bitmap
file */
{
- ibool success = FALSE;
+ bool success = false;
xb_ad(name[0] != '\0');
ut_snprintf(bitmap_file->name, FN_REFLEN, "%s%s", srv_data_home, name);
- bitmap_file->file
- = os_file_create_simple_no_error_handling(0, bitmap_file->name,
- OS_FILE_OPEN,
- OS_FILE_READ_ONLY,
- &success,0);
+ bitmap_file->file = os_file_create_simple_no_error_handling(
+ 0, bitmap_file->name,
+ OS_FILE_OPEN, OS_FILE_READ_ONLY, true, &success);
if (UNIV_UNLIKELY(!success)) {
/* Here and below assume that bitmap file names do not
contain apostrophes, thus no need for ut_print_filename(). */
msg("InnoDB: Warning: error opening the changed page "
"bitmap \'%s\'\n", bitmap_file->name);
- return FALSE;
+ return success;
}
bitmap_file->size = os_file_get_size(bitmap_file->file);
@@ -465,7 +462,7 @@ log_online_open_bitmap_file_read_only(
posix_fadvise(bitmap_file->file, 0, 0, POSIX_FADV_NOREUSE);
#endif
- return TRUE;
+ return success;
}
/****************************************************************//**
@@ -909,6 +906,37 @@ xb_page_bitmap_setup_next_page(
return TRUE;
}
+/** Find the node with the smallest key that greater than equal to search key.
+@param[in] tree red-black tree
+@param[in] key search key
+@return node with the smallest greater-than-or-equal key
+@retval NULL if none was found */
+static
+const ib_rbt_node_t*
+rbt_lower_bound(const ib_rbt_t* tree, const void* key)
+{
+ ut_ad(!tree->cmp_arg);
+ const ib_rbt_node_t* ge = NULL;
+
+ for (const ib_rbt_node_t *node = tree->root->left;
+ node != tree->nil; ) {
+ int result = tree->compare(node->value, key);
+
+ if (result < 0) {
+ node = node->right;
+ } else {
+ ge = node;
+ if (result == 0) {
+ break;
+ }
+
+ node = node->left;
+ }
+ }
+
+ return(ge);
+}
+
/****************************************************************//**
Set up a new bitmap range iterator over a given space id changed
pages in a given bitmap.
@@ -922,8 +950,7 @@ xb_page_bitmap_range_init(
{
byte search_page[MODIFIED_PAGE_BLOCK_SIZE];
xb_page_bitmap_range *result
- = static_cast<xb_page_bitmap_range *>
- (ut_malloc(sizeof(*result)));
+ = static_cast<xb_page_bitmap_range *>(malloc(sizeof(*result)));
memset(result, 0, sizeof(*result));
result->bitmap = bitmap;
@@ -1014,5 +1041,5 @@ xb_page_bitmap_range_deinit(
/*========================*/
xb_page_bitmap_range* bitmap_range) /*! in/out: bitmap range */
{
- ut_free(bitmap_range);
+ free(bitmap_range);
}
diff --git a/extra/mariabackup/encryption_plugin.cc b/extra/mariabackup/encryption_plugin.cc
index 8f7741b057a..76512c185e2 100644
--- a/extra/mariabackup/encryption_plugin.cc
+++ b/extra/mariabackup/encryption_plugin.cc
@@ -8,6 +8,7 @@
#include <vector>
#include <common.h>
#include <backup_mysql.h>
+#include <log0crypt.h>
extern struct st_maria_plugin *mysql_optional_plugins[];
@@ -18,14 +19,14 @@ extern char *xb_plugin_load;
extern char *xb_plugin_dir;
const int PLUGIN_MAX_ARGS = 1024;
-vector<string> backup_plugins_args;
+std::vector<std::string> backup_plugins_args;
const char *QUERY_PLUGIN =
"SELECT plugin_name, plugin_library, @@plugin_dir"
" FROM information_schema.plugins WHERE plugin_type='ENCRYPTION'"
" AND plugin_status='ACTIVE'";
-string encryption_plugin_config;
+std::string encryption_plugin_config;
static void add_to_plugin_load_list(const char *plugin_def)
{
@@ -38,7 +39,7 @@ void encryption_plugin_backup_init(MYSQL *mysql)
{
MYSQL_RES *result;
MYSQL_ROW row;
- ostringstream oss;
+ std::ostringstream oss;
char *argv[PLUGIN_MAX_ARGS];
int argc;
@@ -59,17 +60,17 @@ void encryption_plugin_backup_init(MYSQL *mysql)
if (*p == '\\') *p = '/';
#endif
- string plugin_load(name);
+ std::string plugin_load(name);
if (library)
- plugin_load += string("=") + library;
+ plugin_load += std::string("=") + library;
- oss << "plugin_load=" << plugin_load << endl;
+ oss << "plugin_load=" << plugin_load << std::endl;
/* Required to load the plugin later.*/
add_to_plugin_load_list(plugin_load.c_str());
strncpy(opt_plugin_dir, dir, FN_REFLEN);
- oss << "plugin_dir=" << '"' << dir << '"' << endl;
+ oss << "plugin_dir=" << '"' << dir << '"' << std::endl;
/* Read plugin variables. */
@@ -80,12 +81,12 @@ void encryption_plugin_backup_init(MYSQL *mysql)
result = xb_mysql_query(mysql, query, true, true);
while ((row = mysql_fetch_row(result)))
{
- string arg("--");
+ std::string arg("--");
arg += row[0];
arg += "=";
arg += row[1];
backup_plugins_args.push_back(arg);
- oss << row[0] << "=" << row[1] << endl;
+ oss << row[0] << "=" << row[1] << std::endl;
}
mysql_free_result(result);
@@ -94,7 +95,7 @@ void encryption_plugin_backup_init(MYSQL *mysql)
result = xb_mysql_query(mysql, "select @@innodb_encrypt_log", true, true);
row = mysql_fetch_row(result);
srv_encrypt_log = (row != 0 && row[0][0] == '1');
- oss << "innodb_encrypt_log=" << row[0] << endl;
+ oss << "innodb_encrypt_log=" << row[0] << std::endl;
mysql_free_result(result);
diff --git a/extra/mariabackup/fil_cur.cc b/extra/mariabackup/fil_cur.cc
index 820d8e10c29..9df5f8e8fa3 100644
--- a/extra/mariabackup/fil_cur.cc
+++ b/extra/mariabackup/fil_cur.cc
@@ -24,8 +24,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#include <my_base.h>
-#include <univ.i>
#include <fil0fil.h>
+#include <fsp0fsp.h>
#include <srv0start.h>
#include <trx0sys.h>
@@ -63,7 +63,7 @@ xb_get_relative_path(
prev = NULL;
cur = path;
- while ((next = strchr(cur, SRV_PATH_SEPARATOR)) != NULL) {
+ while ((next = strchr(cur, OS_PATH_SEPARATOR)) != NULL) {
prev = cur;
cur = next + 1;
@@ -96,7 +96,7 @@ xb_fil_node_close_file(
ut_a(node->n_pending_flushes == 0);
ut_a(!node->being_extended);
- if (!node->open) {
+ if (!node->is_open()) {
mutex_exit(&fil_system->mutex);
@@ -106,19 +106,19 @@ xb_fil_node_close_file(
ret = os_file_close(node->handle);
ut_a(ret);
- node->open = FALSE;
+ node->handle = OS_FILE_CLOSED;
ut_a(fil_system->n_open > 0);
fil_system->n_open--;
fil_n_file_opened--;
- if (node->space->purpose == FIL_TABLESPACE &&
+ if (node->space->purpose == FIL_TYPE_TABLESPACE &&
fil_is_user_tablespace_id(node->space->id)) {
ut_a(UT_LIST_GET_LEN(fil_system->LRU) > 0);
/* The node is in the LRU list, remove it */
- UT_LIST_REMOVE(LRU, fil_system->LRU, node);
+ UT_LIST_REMOVE(fil_system->LRU, node);
}
mutex_exit(&fil_system->mutex);
@@ -137,10 +137,7 @@ xb_fil_cur_open(
fil_node_t* node, /*!< in: source tablespace node */
uint thread_n) /*!< thread number for diagnostics */
{
- ulint page_size;
- ulint page_size_shift;
- ulint zip_size;
- ibool success;
+ bool success;
/* Initialize these first so xb_fil_cur_close() handles them correctly
in case of error */
@@ -148,27 +145,26 @@ xb_fil_cur_open(
cursor->node = NULL;
cursor->space_id = node->space->id;
- cursor->is_system = !fil_is_user_tablespace_id(node->space->id);
strncpy(cursor->abs_path, node->name, sizeof(cursor->abs_path));
/* Get the relative path for the destination tablespace name, i.e. the
one that can be appended to the backup root directory. Non-system
- tablespaces may have absolute paths for remote tablespaces in MySQL
- 5.6+. We want to make "local" copies for the backup. */
+ tablespaces may have absolute paths for DATA DIRECTORY.
+ We want to make "local" copies for the backup. */
strncpy(cursor->rel_path,
- xb_get_relative_path(cursor->abs_path, cursor->is_system),
+ xb_get_relative_path(cursor->abs_path, cursor->is_system()),
sizeof(cursor->rel_path));
/* In the backup mode we should already have a tablespace handle created
- by fil_load_single_table_tablespace() unless it is a system
+ by fil_ibd_load() unless it is a system
tablespace. Otherwise we open the file here. */
- if (cursor->is_system || !srv_backup_mode || srv_close_files) {
- node->handle =
- os_file_create_simple_no_error_handling(0, node->name,
- OS_FILE_OPEN,
- OS_FILE_READ_ONLY,
- &success,0);
+ if (cursor->is_system() || srv_operation == SRV_OPERATION_RESTORE
+ || xb_close_files) {
+ node->handle = os_file_create_simple_no_error_handling(
+ 0, node->name,
+ OS_FILE_OPEN,
+ OS_FILE_READ_ALLOW_DELETE, true, &success);
if (!success) {
/* The following call prints an error message */
os_file_get_last_error(TRUE);
@@ -181,22 +177,20 @@ xb_fil_cur_open(
}
mutex_enter(&fil_system->mutex);
- node->open = TRUE;
-
fil_system->n_open++;
fil_n_file_opened++;
- if (node->space->purpose == FIL_TABLESPACE &&
+ if (node->space->purpose == FIL_TYPE_TABLESPACE &&
fil_is_user_tablespace_id(node->space->id)) {
/* Put the node to the LRU list */
- UT_LIST_ADD_FIRST(LRU, fil_system->LRU, node);
+ UT_LIST_ADD_FIRST(fil_system->LRU, node);
}
mutex_exit(&fil_system->mutex);
}
- ut_ad(node->open);
+ ut_ad(node->is_open());
cursor->node = node;
cursor->file = node->handle;
@@ -210,8 +204,8 @@ xb_fil_cur_open(
return(XB_FIL_CUR_ERROR);
}
- if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT
- || srv_unix_file_flush_method == SRV_UNIX_O_DIRECT_NO_FSYNC) {
+ if (srv_file_flush_method == SRV_O_DIRECT
+ || srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC) {
os_file_set_nocache(cursor->file, node->name, "OPEN");
}
@@ -219,32 +213,29 @@ xb_fil_cur_open(
posix_fadvise(cursor->file, 0, 0, POSIX_FADV_SEQUENTIAL);
/* Determine the page size */
- zip_size = xb_get_zip_size(cursor->file);
- if (zip_size == ULINT_UNDEFINED) {
+ ulint flags = xb_get_space_flags(cursor->file);
+ if (flags == ULINT_UNDEFINED) {
xb_fil_cur_close(cursor);
return(XB_FIL_CUR_SKIP);
- } else if (zip_size) {
- page_size = zip_size;
- page_size_shift = get_bit_shift(page_size);
- msg("[%02u] %s is compressed with page size = "
- "%lu bytes\n", thread_n, node->name, page_size);
- if (page_size_shift < 10 || page_size_shift > 14) {
+ }
+
+ if (!fsp_flags_is_valid(flags)) {
+ ulint cflags = fsp_flags_convert_from_101(flags);
+ if (cflags == ULINT_UNDEFINED) {
msg("[%02u] xtrabackup: Error: Invalid "
- "page size: %lu.\n", thread_n, page_size);
- ut_error;
+ "tablespace flags: %x.\n", thread_n, uint(flags));
+ return(XB_FIL_CUR_SKIP);
}
- } else {
- page_size = UNIV_PAGE_SIZE;
- page_size_shift = UNIV_PAGE_SIZE_SHIFT;
+ flags = cflags;
}
+
+ const page_size_t page_size(flags);
cursor->page_size = page_size;
- cursor->page_size_shift = page_size_shift;
- cursor->zip_size = zip_size;
/* Allocate read buffer */
- cursor->buf_size = XB_FIL_CUR_PAGES * page_size;
+ cursor->buf_size = XB_FIL_CUR_PAGES * page_size.physical();
cursor->orig_buf = static_cast<byte *>
- (ut_malloc(cursor->buf_size + UNIV_PAGE_SIZE));
+ (malloc(cursor->buf_size + UNIV_PAGE_SIZE));
cursor->buf = static_cast<byte *>
(ut_align(cursor->orig_buf, UNIV_PAGE_SIZE));
@@ -254,7 +245,8 @@ xb_fil_cur_open(
cursor->buf_page_no = 0;
cursor->thread_n = thread_n;
- cursor->space_size = (ulint)(cursor->statinfo.st_size / page_size);
+ cursor->space_size = (ulint)(cursor->statinfo.st_size
+ / page_size.physical());
cursor->read_filter = read_filter;
cursor->read_filter->init(&cursor->read_filter_ctxt, cursor,
@@ -282,6 +274,8 @@ xb_fil_cur_read(
xb_fil_cur_result_t ret;
ib_int64_t offset;
ib_int64_t to_read;
+ const ulint page_size = cursor->page_size.physical();
+ xb_ad(!cursor->is_system() || page_size == UNIV_PAGE_SIZE);
cursor->read_filter->get_next_batch(&cursor->read_filter_ctxt,
&offset, &to_read);
@@ -296,10 +290,10 @@ xb_fil_cur_read(
xb_a(to_read > 0 && to_read <= 0xFFFFFFFFLL);
- if (to_read % cursor->page_size != 0 &&
- offset + to_read == cursor->statinfo.st_size) {
+ if ((to_read & ~(page_size - 1))
+ && offset + to_read == cursor->statinfo.st_size) {
- if (to_read < (ib_int64_t) cursor->page_size) {
+ if (to_read < (ib_int64_t) page_size) {
msg("[%02u] xtrabackup: Warning: junk at the end of "
"%s:\n", cursor->thread_n, cursor->abs_path);
msg("[%02u] xtrabackup: Warning: offset = %llu, "
@@ -312,12 +306,12 @@ xb_fil_cur_read(
}
to_read = (ib_int64_t) (((ulint) to_read) &
- ~(cursor->page_size - 1));
+ ~(page_size - 1));
}
- xb_a(to_read % cursor->page_size == 0);
+ xb_a((to_read & (page_size - 1)) == 0);
- npages = (ulint) (to_read >> cursor->page_size_shift);
+ npages = (ulint) (to_read / cursor->page_size.physical());
retry_count = 10;
ret = XB_FIL_CUR_SUCCESS;
@@ -328,59 +322,59 @@ read_retry:
cursor->buf_read = 0;
cursor->buf_npages = 0;
cursor->buf_offset = offset;
- cursor->buf_page_no = (ulint)(offset >> cursor->page_size_shift);
+ cursor->buf_page_no = (ulint)(offset / cursor->page_size.physical());
- success = os_file_read(cursor->file, cursor->buf, offset,
- (ulint)to_read);
- if (!success) {
+ FilSpace space(cursor->space_id);
+
+ if (!space()) {
return(XB_FIL_CUR_ERROR);
}
- fil_system_enter();
- fil_space_t *space = fil_space_get_by_id(cursor->space_id);
- fil_system_exit();
+ success = os_file_read(IORequestRead,
+ cursor->file, cursor->buf, offset,
+ (ulint) to_read);
+ if (!success) {
+ return(XB_FIL_CUR_ERROR);
+ }
/* check pages for corruption and re-read if necessary. i.e. in case of
partially written pages */
for (page = cursor->buf, i = 0; i < npages;
- page += cursor->page_size, i++) {
- ib_int64_t page_no = cursor->buf_page_no + i;
-
- bool checksum_ok = fil_space_verify_crypt_checksum(page, cursor->zip_size,space, (ulint)page_no);
-
- if (!checksum_ok &&
- buf_page_is_corrupted(true, page, cursor->zip_size,space)) {
-
- if (cursor->is_system &&
- page_no >= (ib_int64_t)FSP_EXTENT_SIZE &&
- page_no < (ib_int64_t) FSP_EXTENT_SIZE * 3) {
- /* skip doublewrite buffer pages */
- xb_a(cursor->page_size == UNIV_PAGE_SIZE);
+ page += page_size, i++) {
+ ulint page_no = cursor->buf_page_no + i;
+
+ if (cursor->space_id == TRX_SYS_SPACE &&
+ page_no >= FSP_EXTENT_SIZE &&
+ page_no < FSP_EXTENT_SIZE * 3) {
+ /* We ignore the doublewrite buffer pages */
+ } else if (!fil_space_verify_crypt_checksum(
+ page, cursor->page_size, space->id, page_no)
+ && buf_page_is_corrupted(true, page,
+ cursor->page_size,
+ space)) {
+ retry_count--;
+ if (retry_count == 0) {
msg("[%02u] xtrabackup: "
- "Page %lu is a doublewrite buffer page, "
- "skipping.\n", cursor->thread_n, page_no);
- } else {
- retry_count--;
- if (retry_count == 0) {
- msg("[%02u] xtrabackup: "
- "Error: failed to read page after "
- "10 retries. File %s seems to be "
- "corrupted.\n", cursor->thread_n,
- cursor->abs_path);
- ret = XB_FIL_CUR_ERROR;
- break;
- }
+ "Error: failed to read page after "
+ "10 retries. File %s seems to be "
+ "corrupted.\n", cursor->thread_n,
+ cursor->abs_path);
+ ret = XB_FIL_CUR_ERROR;
+ break;
+ }
+
+ if (retry_count == 9) {
msg("[%02u] xtrabackup: "
"Database page corruption detected at page "
- "%lu, retrying...\n", cursor->thread_n,
- page_no);
+ ULINTPF ", retrying...\n",
+ cursor->thread_n, page_no);
+ }
- os_thread_sleep(100000);
+ os_thread_sleep(100000);
- goto read_retry;
- }
+ goto read_retry;
}
- cursor->buf_read += cursor->page_size;
+ cursor->buf_read += page_size;
cursor->buf_npages++;
}
@@ -399,11 +393,10 @@ xb_fil_cur_close(
{
cursor->read_filter->deinit(&cursor->read_filter_ctxt);
- if (cursor->orig_buf != NULL) {
- ut_free(cursor->orig_buf);
- }
+ free(cursor->orig_buf);
+
if (cursor->node != NULL) {
xb_fil_node_close_file(cursor->node);
- cursor->file = XB_FILE_UNDEFINED;
+ cursor->file = OS_FILE_CLOSED;
}
}
diff --git a/extra/mariabackup/fil_cur.h b/extra/mariabackup/fil_cur.h
index f3601823a5a..e3f356a346c 100644
--- a/extra/mariabackup/fil_cur.h
+++ b/extra/mariabackup/fil_cur.h
@@ -27,6 +27,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#include <my_dir.h>
#include "read_filt.h"
+#include "srv0start.h"
struct xb_fil_cur_t {
pfs_os_file_t file; /*!< source file handle */
@@ -36,14 +37,7 @@ struct xb_fil_cur_t {
char abs_path[FN_REFLEN];
/*!< absolute file path */
MY_STAT statinfo; /*!< information about the file */
- ulint zip_size; /*!< compressed page size in bytes or 0
- for uncompressed pages */
- ulint page_size; /*!< = zip_size for compressed pages or
- UNIV_PAGE_SIZE for uncompressed ones */
- ulint page_size_shift;/*!< bit shift corresponding to
- page_size */
- my_bool is_system; /*!< TRUE for system tablespace, FALSE
- otherwise */
+ page_size_t page_size; /*!< page size */
xb_read_filt_t* read_filter; /*!< read filter */
xb_read_filt_ctxt_t read_filter_ctxt;
/*!< read filter context */
@@ -61,6 +55,17 @@ struct xb_fil_cur_t {
uint thread_n; /*!< thread number for diagnostics */
ulint space_id; /*!< ID of tablespace */
ulint space_size; /*!< space size in pages */
+
+ /** TODO: remove this default constructor */
+ xb_fil_cur_t() : page_size(0), read_filter_ctxt() {}
+
+ /** @return whether this is not a file-per-table tablespace */
+ bool is_system() const
+ {
+ ut_ad(space_id != SRV_TMP_SPACE_ID);
+ return(space_id == TRX_SYS_SPACE
+ || srv_is_undo_tablespace(space_id));
+ }
};
typedef enum {
diff --git a/extra/mariabackup/innobackupex.cc b/extra/mariabackup/innobackupex.cc
index 7e97b258489..4fb85208eff 100644
--- a/extra/mariabackup/innobackupex.cc
+++ b/extra/mariabackup/innobackupex.cc
@@ -45,7 +45,6 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <mysql.h>
#include <my_dir.h>
#include <ut0mem.h>
-#include <os0sync.h>
#include <os0file.h>
#include <srv0start.h>
#include <algorithm>
@@ -70,7 +69,6 @@ using std::max;
my_bool opt_ibx_version = FALSE;
my_bool opt_ibx_help = FALSE;
my_bool opt_ibx_apply_log = FALSE;
-my_bool opt_ibx_redo_only = FALSE;
my_bool opt_ibx_incremental = FALSE;
my_bool opt_ibx_notimestamp = FALSE;
@@ -226,21 +224,11 @@ static struct my_option ibx_long_options[] =
GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"apply-log", OPT_APPLY_LOG, "Prepare a backup in BACKUP-DIR by "
- "applying the transaction log file named \"xtrabackup_logfile\" "
- "located in the same directory. Also, create new transaction logs. "
+ "applying the redo log 'ib_logfile0' and creating new redo log. "
"The InnoDB configuration is read from the file \"backup-my.cnf\".",
(uchar*) &opt_ibx_apply_log, (uchar*) &opt_ibx_apply_log,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"redo-only", OPT_REDO_ONLY, "This option should be used when "
- "preparing the base full backup and when merging all incrementals "
- "except the last one. This forces xtrabackup to skip the \"rollback\" "
- "phase and do a \"redo\" only. This is necessary if the backup will "
- "have incremental changes applied to it later. See the xtrabackup "
- "documentation for details.",
- (uchar *) &opt_ibx_redo_only, (uchar *) &opt_ibx_redo_only, 0,
- GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
-
{"copy-back", OPT_COPY_BACK, "Copy all the files in a previously made "
"backup from the backup directory to their original locations.",
(uchar *) &opt_ibx_copy_back, (uchar *) &opt_ibx_copy_back, 0,
@@ -682,7 +670,7 @@ innobackupex [--compress] [--compress-threads=NUMBER-OF-THREADS] [--compress-chu
\n\
innobackupex --apply-log [--use-memory=B]\n\
[--defaults-file=MY.CNF]\n\
- [--export] [--redo-only] [--ibbackup=IBBACKUP-BINARY]\n\
+ [--export] [--ibbackup=IBBACKUP-BINARY]\n\
BACKUP-DIR\n\
\n\
innobackupex --copy-back [--defaults-file=MY.CNF] [--defaults-group=GROUP-NAME] BACKUP-DIR\n\
@@ -710,7 +698,7 @@ process.\n\
\n\
The --apply-log command prepares a backup for starting a MySQL\n\
server on the backup. This command recovers InnoDB data files as specified\n\
-in BACKUP-DIR/backup-my.cnf using BACKUP-DIR/xtrabackup_logfile,\n\
+in BACKUP-DIR/backup-my.cnf using BACKUP-DIR/ib_logfile0,\n\
and creates new InnoDB log files as specified in BACKUP-DIR/backup-my.cnf.\n\
The BACKUP-DIR should be the path to a backup directory created by\n\
xtrabackup. This command runs xtrabackup as a child process, but it does not \n\
@@ -980,9 +968,6 @@ ibx_init()
switch (ibx_mode) {
case IBX_MODE_APPLY_LOG:
xtrabackup_prepare = TRUE;
- if (opt_ibx_redo_only) {
- xtrabackup_apply_log_only = TRUE;
- }
xtrabackup_target_dir = ibx_position_arg;
run = "apply-log";
break;
diff --git a/extra/mariabackup/read_filt.cc b/extra/mariabackup/read_filt.cc
index 05e6b7c86c7..a48591abf29 100644
--- a/extra/mariabackup/read_filt.cc
+++ b/extra/mariabackup/read_filt.cc
@@ -127,10 +127,11 @@ rf_bitmap_get_next_batch(
of pages */
{
ulint start_page_id;
+ const ulint page_size = ctxt->page_size.physical();
- start_page_id = (ulint)(ctxt->offset / ctxt->page_size);
+ start_page_id = (ulint)(ctxt->offset / page_size);
- xb_a (ctxt->offset % ctxt->page_size == 0);
+ xb_a (ctxt->offset % page_size == 0);
if (start_page_id == ctxt->filter_batch_end) {
@@ -146,7 +147,7 @@ rf_bitmap_get_next_batch(
return;
}
- ctxt->offset = next_page_id * ctxt->page_size;
+ ctxt->offset = next_page_id * page_size;
/* Find the end of the current changed page block by searching
for the next cleared bitmap bit */
@@ -162,7 +163,7 @@ rf_bitmap_get_next_batch(
remaining pages. */
*read_batch_len = ctxt->data_file_size - ctxt->offset;
} else {
- *read_batch_len = ctxt->filter_batch_end * ctxt->page_size
+ *read_batch_len = ctxt->filter_batch_end * page_size
- ctxt->offset;
}
@@ -175,9 +176,9 @@ rf_bitmap_get_next_batch(
}
ctxt->offset += *read_batch_len;
- xb_a (ctxt->offset % ctxt->page_size == 0);
- xb_a (*read_batch_start % ctxt->page_size == 0);
- xb_a (*read_batch_len % ctxt->page_size == 0);
+ xb_a (ctxt->offset % page_size == 0);
+ xb_a (*read_batch_start % page_size == 0);
+ xb_a (*read_batch_len % page_size == 0);
}
/****************************************************************//**
diff --git a/extra/mariabackup/read_filt.h b/extra/mariabackup/read_filt.h
index d16f4e1093d..cebc714eed8 100644
--- a/extra/mariabackup/read_filt.h
+++ b/extra/mariabackup/read_filt.h
@@ -27,6 +27,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#include "changed_page_bitmap.h"
+typedef ulint space_id_t;
+
struct xb_fil_cur_t;
/* The read filter context */
@@ -34,15 +36,17 @@ struct xb_read_filt_ctxt_t {
ib_int64_t offset; /*!< current file offset */
ib_int64_t data_file_size; /*!< data file size */
size_t buffer_capacity;/*!< read buffer capacity */
- ib_int64_t space_id; /*!< space id */
+ space_id_t space_id; /*!< space id */
/* The following fields used only in bitmap filter */
/* Move these to union if any other filters are added in future */
xb_page_bitmap_range *bitmap_range; /*!< changed page bitmap range
iterator for space_id */
- size_t page_size; /*!< page size */
+ page_size_t page_size; /*!< page size */
ulint filter_batch_end;/*!< the ending page id of the
current changed page block in
the bitmap */
+ /** TODO: remove this default constructor */
+ xb_read_filt_ctxt_t() : page_size(0) {}
};
/* The read filter */
diff --git a/extra/mariabackup/write_filt.cc b/extra/mariabackup/write_filt.cc
index cf7753bf380..a0633818405 100644
--- a/extra/mariabackup/write_filt.cc
+++ b/extra/mariabackup/write_filt.cc
@@ -67,7 +67,6 @@ wf_incremental_init(xb_write_filt_ctxt_t *ctxt, char *dst_name,
xb_fil_cur_t *cursor)
{
char meta_name[FN_REFLEN];
- xb_delta_info_t info;
ulint buf_size;
xb_wf_incremental_ctxt_t *cp =
&(ctxt->u.wf_incremental_ctxt);
@@ -75,8 +74,9 @@ wf_incremental_init(xb_write_filt_ctxt_t *ctxt, char *dst_name,
ctxt->cursor = cursor;
/* allocate buffer for incremental backup (4096 pages) */
- buf_size = (cursor->page_size / 4 + 1) * cursor->page_size;
- cp->delta_buf_base = static_cast<byte *>(ut_malloc(buf_size));
+ buf_size = (cursor->page_size.physical() / 4 + 1)
+ * cursor->page_size.physical();
+ cp->delta_buf_base = static_cast<byte *>(malloc(buf_size));
memset(cp->delta_buf_base, 0, buf_size);
cp->delta_buf = static_cast<byte *>
(ut_align(cp->delta_buf_base, UNIV_PAGE_SIZE_MAX));
@@ -84,9 +84,7 @@ wf_incremental_init(xb_write_filt_ctxt_t *ctxt, char *dst_name,
/* write delta meta info */
snprintf(meta_name, sizeof(meta_name), "%s%s", dst_name,
XB_DELTA_INFO_SUFFIX);
- info.page_size = cursor->page_size;
- info.zip_size = cursor->zip_size;
- info.space_id = cursor->space_id;
+ const xb_delta_info_t info(cursor->page_size, cursor->space_id);
if (!xb_write_delta_metadata(meta_name, &info)) {
msg("[%02u] xtrabackup: Error: "
"failed to write meta info for %s\n",
@@ -113,8 +111,9 @@ wf_incremental_process(xb_write_filt_ctxt_t *ctxt, ds_file_t *dstfile)
{
ulint i;
xb_fil_cur_t *cursor = ctxt->cursor;
- ulint page_size = cursor->page_size;
byte *page;
+ const ulint page_size
+ = cursor->page_size.physical();
xb_wf_incremental_ctxt_t *cp = &(ctxt->u.wf_incremental_ctxt);
for (i = 0, page = cursor->buf; i < cursor->buf_npages;
@@ -159,7 +158,8 @@ static my_bool
wf_incremental_finalize(xb_write_filt_ctxt_t *ctxt, ds_file_t *dstfile)
{
xb_fil_cur_t *cursor = ctxt->cursor;
- ulint page_size = cursor->page_size;
+ const ulint page_size
+ = cursor->page_size.physical();
xb_wf_incremental_ctxt_t *cp = &(ctxt->u.wf_incremental_ctxt);
if (cp->npages != page_size / 4) {
@@ -184,9 +184,7 @@ wf_incremental_deinit(xb_write_filt_ctxt_t *ctxt)
{
xb_wf_incremental_ctxt_t *cp = &(ctxt->u.wf_incremental_ctxt);
- if (cp->delta_buf_base != NULL) {
- ut_free(cp->delta_buf_base);
- }
+ free(cp->delta_buf_base);
}
/************************************************************************
diff --git a/extra/mariabackup/xb0xb.h b/extra/mariabackup/xb0xb.h
index a8b17f59579..59938a014c6 100644
--- a/extra/mariabackup/xb0xb.h
+++ b/extra/mariabackup/xb0xb.h
@@ -21,43 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef xb0xb_h
#define xb0xb_h
-
-extern void os_io_init_simple(void);
-extern pfs_os_file_t files[1000];
extern const char *innodb_checksum_algorithm_names[];
extern TYPELIB innodb_checksum_algorithm_typelib;
-extern dberr_t open_or_create_data_files(
- bool* create_new_db,
-#ifdef UNIV_LOG_ARCHIVE
- lsn_t* min_arch_log_no,
- lsn_t* max_arch_log_no,
-#endif
- lsn_t* flushed_lsn,
- ulint* sum_of_new_sizes)
- ;
-int
-fil_file_readdir_next_file(
-/*=======================*/
-dberr_t* err, /*!< out: this is set to DB_ERROR if an error
- was encountered, otherwise not changed */
- const char* dirname,/*!< in: directory name or path */
- os_file_dir_t dir, /*!< in: directory stream */
- os_file_stat_t* info) /*!< in/out: buffer where the
- info is returned */;
-fil_space_t*
-fil_space_get_by_name(const char *);
-ibool
-recv_check_cp_is_consistent(const byte* buf);
-void
-innodb_log_checksum_func_update(
-/*============================*/
-ulint algorithm) /*!< in: algorithm */;
-dberr_t
-srv_undo_tablespaces_init(
-/*======================*/
-ibool create_new_db,
-ibool backup_mode,
-const ulint n_conf_tablespaces,
-ulint* n_opened);
#endif
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index baad5b12118..6e9c172efc1 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -4,6 +4,8 @@ XtraBackup: hot backup tool for InnoDB
Originally Created 3/3/2009 Yasufumi Kinoshita
Written by Alexey Kopytov, Aleksandr Kuzminsky, Stewart Smith, Vadim Tkachenko,
Yasufumi Kinoshita, Ignacio Nin and Baron Schwartz.
+(c) 2017, MariaDB Corporation.
+Portions written by Marko Mäkelä.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -41,6 +43,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
//#define XTRABACKUP_TARGET_IS_PLUGIN
+#include <my_config.h>
+#include <unireg.h>
#include <mysql_version.h>
#include <my_base.h>
#include <my_getopt.h>
@@ -61,6 +65,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <dict0priv.h>
#include <lock0lock.h>
#include <log0recv.h>
+#include <log0crypt.h>
#include <row0mysql.h>
#include <row0quiesce.h>
#include <srv0start.h>
@@ -85,7 +90,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "xbstream.h"
#include "changed_page_bitmap.h"
#include "read_filt.h"
-#include "wsrep.h"
+#include "backup_wsrep.h"
#include "innobackupex.h"
#include "backup_mysql.h"
#include "backup_copy.h"
@@ -95,48 +100,39 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <sql_plugin.h>
#include <srv0srv.h>
#include <crc_glue.h>
-
-/* TODO: replace with appropriate macros used in InnoDB 5.6 */
-#define PAGE_ZIP_MIN_SIZE_SHIFT 10
-#define DICT_TF_ZSSIZE_SHIFT 1
-#define DICT_TF_FORMAT_ZIP 1
-#define DICT_TF_FORMAT_SHIFT 5
+#include <log.h>
int sys_var_init();
-my_bool innodb_inited= 0;
-
/* === xtrabackup specific options === */
char xtrabackup_real_target_dir[FN_REFLEN] = "./xtrabackup_backupfiles/";
char *xtrabackup_target_dir= xtrabackup_real_target_dir;
-my_bool xtrabackup_version = FALSE;
-my_bool xtrabackup_backup = FALSE;
-my_bool xtrabackup_prepare = FALSE;
-my_bool xtrabackup_copy_back = FALSE;
-my_bool xtrabackup_move_back = FALSE;
-my_bool xtrabackup_decrypt_decompress = FALSE;
-my_bool xtrabackup_print_param = FALSE;
-
-my_bool xtrabackup_export = FALSE;
-my_bool xtrabackup_apply_log_only = FALSE;
-
-longlong xtrabackup_use_memory = 100*1024*1024L;
-my_bool xtrabackup_create_ib_logfile = FALSE;
-
-long xtrabackup_throttle = 0; /* 0:unlimited */
-lint io_ticket;
-os_event_t wait_throttle = NULL;
-os_event_t log_copying_stop = NULL;
-
-char *xtrabackup_incremental = NULL;
+static my_bool xtrabackup_version;
+my_bool xtrabackup_backup;
+my_bool xtrabackup_prepare;
+my_bool xtrabackup_copy_back;
+my_bool xtrabackup_move_back;
+my_bool xtrabackup_decrypt_decompress;
+my_bool xtrabackup_print_param;
+
+my_bool xtrabackup_export;
+
+longlong xtrabackup_use_memory;
+
+long xtrabackup_throttle; /* 0:unlimited */
+static lint io_ticket;
+static os_event_t wait_throttle;
+static os_event_t log_copying_stop;
+
+char *xtrabackup_incremental;
lsn_t incremental_lsn;
lsn_t incremental_to_lsn;
lsn_t incremental_last_lsn;
-xb_page_bitmap *changed_page_bitmap = NULL;
+xb_page_bitmap *changed_page_bitmap;
-char *xtrabackup_incremental_basedir = NULL; /* for --backup */
-char *xtrabackup_extra_lsndir = NULL; /* for --backup with --extra-lsndir */
-char *xtrabackup_incremental_dir = NULL; /* for --prepare */
+char *xtrabackup_incremental_basedir; /* for --backup */
+char *xtrabackup_extra_lsndir; /* for --backup with --extra-lsndir */
+char *xtrabackup_incremental_dir; /* for --prepare */
char xtrabackup_real_incremental_basedir[FN_REFLEN];
char xtrabackup_real_extra_lsndir[FN_REFLEN];
@@ -144,9 +140,9 @@ char xtrabackup_real_incremental_dir[FN_REFLEN];
char *xtrabackup_tmpdir;
-char *xtrabackup_tables = NULL;
-char *xtrabackup_tables_file = NULL;
-char *xtrabackup_tables_exclude = NULL;
+char *xtrabackup_tables;
+char *xtrabackup_tables_file;
+char *xtrabackup_tables_exclude;
typedef std::list<regex_t> regex_list_t;
static regex_list_t regex_include_list;
@@ -170,17 +166,12 @@ struct xb_filter_entry_struct{
};
typedef struct xb_filter_entry_struct xb_filter_entry_t;
-static ulint thread_nr[SRV_MAX_N_IO_THREADS + 6];
-static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6];
-
lsn_t checkpoint_lsn_start;
lsn_t checkpoint_no_start;
-lsn_t log_copy_scanned_lsn;
-ibool log_copying = TRUE;
-ibool log_copying_running = FALSE;
-ibool io_watching_thread_running = FALSE;
-
-ibool xtrabackup_logfile_is_renamed = FALSE;
+static lsn_t log_copy_scanned_lsn;
+static bool log_copying;
+static bool log_copying_running;
+static bool io_watching_thread_running;
int xtrabackup_parallel;
@@ -199,19 +190,16 @@ ulint xtrabackup_log_copy_interval = 1000;
static ulong max_buf_pool_modified_pct;
/* Ignored option (--log) for MySQL option compatibility */
-char* log_ignored_opt = NULL;
+static char* log_ignored_opt;
/* === metadata of backup === */
#define XTRABACKUP_METADATA_FILENAME "xtrabackup_checkpoints"
-char metadata_type[30] = ""; /*[full-backuped|log-applied|
- full-prepared|incremental]*/
-lsn_t metadata_from_lsn = 0;
-lsn_t metadata_to_lsn = 0;
-lsn_t metadata_last_lsn = 0;
-
-#define XB_LOG_FILENAME "xtrabackup_logfile"
+char metadata_type[30] = ""; /*[full-backuped|log-applied|incremental]*/
+lsn_t metadata_from_lsn;
+lsn_t metadata_to_lsn;
+lsn_t metadata_last_lsn;
-ds_file_t *dst_log_file = NULL;
+static ds_file_t* dst_log_file;
static char mysql_data_home_buff[2];
@@ -227,24 +215,17 @@ ulong innobase_large_page_size = 0;
/* The default values for the following, type long or longlong, start-up
parameters are declared in mysqld.cc: */
-long innobase_additional_mem_pool_size = 1*1024*1024L;
long innobase_buffer_pool_awe_mem_mb = 0;
long innobase_file_io_threads = 4;
long innobase_read_io_threads = 4;
long innobase_write_io_threads = 4;
-long innobase_force_recovery = 0;
long innobase_log_buffer_size = 1024*1024L;
-long innobase_log_files_in_group = 2;
long innobase_open_files = 300L;
longlong innobase_page_size = (1LL << 14); /* 16KB */
-static ulong innobase_log_block_size = 512;
-my_bool innobase_fast_checksum = FALSE;
-char* innobase_doublewrite_file = NULL;
char* innobase_buffer_pool_filename = NULL;
longlong innobase_buffer_pool_size = 8*1024*1024L;
-longlong innobase_log_file_size = 48*1024*1024L;
/* The default values for the following char* start-up parameters
are determined in innobase_init below: */
@@ -256,20 +237,12 @@ char* innobase_data_file_path = NULL;
affects Windows: */
char* innobase_unix_file_flush_method = NULL;
-/* Below we have boolean-valued start-up parameters, and their default
-values */
-
-ulong innobase_fast_shutdown = 1;
-my_bool innobase_use_doublewrite = TRUE;
-my_bool innobase_use_checksums = TRUE;
-my_bool innobase_use_large_pages = FALSE;
-my_bool innobase_file_per_table = FALSE;
-my_bool innobase_locks_unsafe_for_binlog = FALSE;
-my_bool innobase_rollback_on_timeout = FALSE;
-my_bool innobase_create_status_file = FALSE;
-my_bool innobase_adaptive_hash_index = TRUE;
-
-static char *internal_innobase_data_file_path = NULL;
+my_bool innobase_use_doublewrite;
+my_bool innobase_use_large_pages;
+my_bool innobase_file_per_table;
+my_bool innobase_locks_unsafe_for_binlog;
+my_bool innobase_rollback_on_timeout;
+my_bool innobase_create_status_file;
/* The following counter is used to convey information to InnoDB
about server activity: in selects it is not sensible to call
@@ -290,7 +263,7 @@ lsn_t flushed_lsn= 0;
ulong xb_open_files_limit= 0;
char *xb_plugin_dir;
char *xb_plugin_load;
-my_bool xb_close_files= FALSE;
+my_bool xb_close_files;
/* Datasinks */
ds_ctxt_t *ds_data = NULL;
@@ -299,10 +272,6 @@ ds_ctxt_t *ds_redo = NULL;
static bool innobackupex_mode = false;
-static long innobase_log_files_in_group_save;
-static char *srv_log_group_home_dir_save;
-static longlong innobase_log_file_size_save;
-
/* String buffer used by --print-param to accumulate server options as they are
parsed from the defaults file */
static std::ostringstream print_param_str;
@@ -313,6 +282,7 @@ std::set<std::string> param_set;
static ulonglong global_max_value;
extern "C" sig_handler handle_fatal_signal(int sig);
+extern LOGGER logger;
my_bool opt_galera_info = FALSE;
my_bool opt_slave_info = FALSE;
@@ -361,9 +331,6 @@ const char *opt_history = NULL;
#if defined(HAVE_OPENSSL)
my_bool opt_ssl_verify_server_cert = FALSE;
-#if !defined(HAVE_YASSL)
-char *opt_server_public_key = NULL;
-#endif
#endif
/* Whether xtrabackup_binlog_info should be created on recovery */
@@ -383,14 +350,23 @@ xtrabackup_add_datasink(ds_ctxt_t *ds)
}
/* ======== Datafiles iterator ======== */
+struct datafiles_iter_t {
+ fil_system_t *system;
+ fil_space_t *space;
+ fil_node_t *node;
+ ibool started;
+ pthread_mutex_t mutex;
+};
+
+/* ======== Datafiles iterator ======== */
+static
datafiles_iter_t *
datafiles_iter_new(fil_system_t *f_system)
{
datafiles_iter_t *it;
- it = static_cast<datafiles_iter_t *>
- (ut_malloc(sizeof(datafiles_iter_t)));
- it->mutex = os_mutex_create();
+ it = static_cast<datafiles_iter_t *>(malloc(sizeof(datafiles_iter_t)));
+ pthread_mutex_init(&it->mutex, NULL);
it->system = f_system;
it->space = NULL;
@@ -400,12 +376,13 @@ datafiles_iter_new(fil_system_t *f_system)
return it;
}
+static
fil_node_t *
datafiles_iter_next(datafiles_iter_t *it)
{
fil_node_t *new_node;
- os_mutex_enter(it->mutex);
+ pthread_mutex_lock(&it->mutex);
if (it->node == NULL) {
if (it->started)
@@ -422,7 +399,7 @@ datafiles_iter_next(datafiles_iter_t *it)
UT_LIST_GET_NEXT(space_list, it->space);
while (it->space != NULL &&
- (it->space->purpose != FIL_TABLESPACE ||
+ (it->space->purpose != FIL_TYPE_TABLESPACE ||
UT_LIST_GET_LEN(it->space->chain) == 0))
it->space = UT_LIST_GET_NEXT(space_list, it->space);
if (it->space == NULL)
@@ -432,16 +409,17 @@ datafiles_iter_next(datafiles_iter_t *it)
end:
new_node = it->node;
- os_mutex_exit(it->mutex);
+ pthread_mutex_unlock(&it->mutex);
return new_node;
}
+static
void
datafiles_iter_free(datafiles_iter_t *it)
{
- os_mutex_free(it->mutex);
- ut_free(it);
+ pthread_mutex_destroy(&it->mutex);
+ free(it);
}
/* ======== Date copying thread context ======== */
@@ -450,7 +428,7 @@ typedef struct {
datafiles_iter_t *it;
uint num;
uint *count;
- os_ib_mutex_t count_mutex;
+ pthread_mutex_t count_mutex;
os_thread_id_t id;
} data_thread_ctxt_t;
@@ -463,7 +441,6 @@ enum options_xtrabackup
OPT_XTRA_BACKUP,
OPT_XTRA_PREPARE,
OPT_XTRA_EXPORT,
- OPT_XTRA_APPLY_LOG_ONLY,
OPT_XTRA_PRINT_PARAM,
OPT_XTRA_USE_MEMORY,
OPT_XTRA_THROTTLE,
@@ -476,7 +453,6 @@ enum options_xtrabackup
OPT_XTRA_TABLES_FILE,
OPT_XTRA_DATABASES,
OPT_XTRA_DATABASES_FILE,
- OPT_XTRA_CREATE_IB_LOGFILE,
OPT_XTRA_PARALLEL,
OPT_XTRA_STREAM,
OPT_XTRA_COMPRESS,
@@ -484,12 +460,10 @@ enum options_xtrabackup
OPT_XTRA_COMPRESS_CHUNK_SIZE,
OPT_LOG,
OPT_INNODB,
- OPT_INNODB_CHECKSUMS,
OPT_INNODB_DATA_FILE_PATH,
OPT_INNODB_DATA_HOME_DIR,
OPT_INNODB_ADAPTIVE_HASH_INDEX,
OPT_INNODB_DOUBLEWRITE,
- OPT_INNODB_FAST_SHUTDOWN,
OPT_INNODB_FILE_PER_TABLE,
OPT_INNODB_FLUSH_LOG_AT_TRX_COMMIT,
OPT_INNODB_FLUSH_METHOD,
@@ -499,7 +473,6 @@ enum options_xtrabackup
OPT_INNODB_MAX_PURGE_LAG,
OPT_INNODB_ROLLBACK_ON_TIMEOUT,
OPT_INNODB_STATUS_FILE,
- OPT_INNODB_ADDITIONAL_MEM_POOL_SIZE,
OPT_INNODB_AUTOEXTEND_INCREMENT,
OPT_INNODB_BUFFER_POOL_SIZE,
OPT_INNODB_COMMIT_CONCURRENCY,
@@ -510,25 +483,17 @@ enum options_xtrabackup
OPT_INNODB_WRITE_IO_THREADS,
OPT_INNODB_USE_NATIVE_AIO,
OPT_INNODB_PAGE_SIZE,
- OPT_INNODB_LOG_BLOCK_SIZE,
- OPT_INNODB_FAST_CHECKSUM,
- OPT_INNODB_EXTRA_UNDOSLOTS,
- OPT_INNODB_DOUBLEWRITE_FILE,
OPT_INNODB_BUFFER_POOL_FILENAME,
- OPT_INNODB_FORCE_RECOVERY,
OPT_INNODB_LOCK_WAIT_TIMEOUT,
OPT_INNODB_LOG_BUFFER_SIZE,
OPT_INNODB_LOG_FILE_SIZE,
OPT_INNODB_LOG_FILES_IN_GROUP,
OPT_INNODB_OPEN_FILES,
- OPT_INNODB_SYNC_SPIN_LOOPS,
- OPT_INNODB_THREAD_CONCURRENCY,
- OPT_INNODB_THREAD_SLEEP_DELAY,
OPT_XTRA_DEBUG_SYNC,
OPT_INNODB_CHECKSUM_ALGORITHM,
OPT_INNODB_UNDO_DIRECTORY,
OPT_INNODB_UNDO_TABLESPACES,
- OPT_INNODB_LOG_CHECKSUM_ALGORITHM,
+ OPT_INNODB_LOG_CHECKSUMS,
OPT_XTRA_INCREMENTAL_FORCE_SCAN,
OPT_DEFAULTS_GROUP,
OPT_OPEN_FILES_LIMIT,
@@ -563,10 +528,6 @@ enum options_xtrabackup
OPT_BINLOG_INFO,
OPT_XB_SECURE_AUTH,
- OPT_SSL_SSL,
- OPT_SSL_VERIFY_SERVER_CERT,
- OPT_SERVER_PUBLIC_KEY,
-
OPT_XTRA_TABLES_EXCLUDE,
OPT_XTRA_DATABASES_EXCLUDE,
};
@@ -587,10 +548,6 @@ struct my_option xb_client_options[] =
{"export", OPT_XTRA_EXPORT, "create files to import to another database when prepare.",
(G_PTR*) &xtrabackup_export, (G_PTR*) &xtrabackup_export,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"apply-log-only", OPT_XTRA_APPLY_LOG_ONLY,
- "stop recovery process not to progress LSN after applying log when prepare.",
- (G_PTR*) &xtrabackup_apply_log_only, (G_PTR*) &xtrabackup_apply_log_only,
- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"print-param", OPT_XTRA_PRINT_PARAM, "print parameter of mysqld needed for copyback.",
(G_PTR*) &xtrabackup_print_param, (G_PTR*) &xtrabackup_print_param,
0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
@@ -628,7 +585,7 @@ struct my_option xb_client_options[] =
{"databases", OPT_XTRA_DATABASES, "filtering by list of databases.",
(G_PTR*) &xtrabackup_databases, (G_PTR*) &xtrabackup_databases,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"databases_file", OPT_XTRA_TABLES_FILE,
+ {"databases_file", OPT_XTRA_DATABASES_FILE,
"filtering by list of databases in the file.",
(G_PTR*) &xtrabackup_databases_file, (G_PTR*) &xtrabackup_databases_file,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -642,9 +599,6 @@ struct my_option xb_client_options[] =
"Note that this option has a higher priority than --databases.",
(G_PTR*) &xtrabackup_databases_exclude, (G_PTR*) &xtrabackup_databases_exclude,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"create-ib-logfile", OPT_XTRA_CREATE_IB_LOGFILE, "** not work for now** creates ib_logfile* also after '--prepare'. ### If you want create ib_logfile*, only re-execute this command in same options. ###",
- (G_PTR*) &xtrabackup_create_ib_logfile, (G_PTR*) &xtrabackup_create_ib_logfile,
- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"stream", OPT_XTRA_STREAM, "Stream all backup files to the standard output "
"in the specified format."
@@ -922,6 +876,11 @@ struct my_option xb_client_options[] =
uint xb_client_options_count = array_elements(xb_client_options);
+#ifndef DBUG_OFF
+/** Parameters to DBUG */
+static const char *dbug_option;
+#endif
+
struct my_option xb_server_options[] =
{
{"datadir", 'h', "Path to the database root.", (G_PTR*) &mysql_data_home,
@@ -952,40 +911,34 @@ struct my_option xb_server_options[] =
{"innodb", OPT_INNODB, "Ignored option for MySQL option compatibility",
(G_PTR*) &innobase_ignored_opt, (G_PTR*) &innobase_ignored_opt, 0,
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
-
+#ifdef BTR_CUR_HASH_ADAPT
{"innodb_adaptive_hash_index", OPT_INNODB_ADAPTIVE_HASH_INDEX,
"Enable InnoDB adaptive hash index (enabled by default). "
"Disable with --skip-innodb-adaptive-hash-index.",
- (G_PTR*) &innobase_adaptive_hash_index,
- (G_PTR*) &innobase_adaptive_hash_index,
+ &btr_search_enabled,
+ &btr_search_enabled,
0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
- {"innodb_additional_mem_pool_size", OPT_INNODB_ADDITIONAL_MEM_POOL_SIZE,
- "Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures.",
- (G_PTR*) &innobase_additional_mem_pool_size,
- (G_PTR*) &innobase_additional_mem_pool_size, 0, GET_LONG, REQUIRED_ARG,
- 1*1024*1024L, 512*1024L, LONG_MAX, 0, 1024, 0},
+#endif /* BTR_CUR_HASH_ADAPT */
{"innodb_autoextend_increment", OPT_INNODB_AUTOEXTEND_INCREMENT,
"Data file autoextend increment in megabytes",
- (G_PTR*) &srv_auto_extend_increment,
- (G_PTR*) &srv_auto_extend_increment,
+ (G_PTR*) &sys_tablespace_auto_extend_increment,
+ (G_PTR*) &sys_tablespace_auto_extend_increment,
0, GET_ULONG, REQUIRED_ARG, 8L, 1L, 1000L, 0, 1L, 0},
{"innodb_buffer_pool_size", OPT_INNODB_BUFFER_POOL_SIZE,
"The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
(G_PTR*) &innobase_buffer_pool_size, (G_PTR*) &innobase_buffer_pool_size, 0,
GET_LL, REQUIRED_ARG, 8*1024*1024L, 1024*1024L, LONGLONG_MAX, 0,
1024*1024L, 0},
- {"innodb_checksums", OPT_INNODB_CHECKSUMS, "Enable InnoDB checksums validation (enabled by default). \
-Disable with --skip-innodb-checksums.", (G_PTR*) &innobase_use_checksums,
- (G_PTR*) &innobase_use_checksums, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
{"innodb_data_file_path", OPT_INNODB_DATA_FILE_PATH,
"Path to individual files and their sizes.", &innobase_data_file_path,
&innobase_data_file_path, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"innodb_data_home_dir", OPT_INNODB_DATA_HOME_DIR,
"The common part for InnoDB table spaces.", &innobase_data_home_dir,
&innobase_data_home_dir, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
- {"innodb_doublewrite", OPT_INNODB_DOUBLEWRITE, "Enable InnoDB doublewrite buffer (enabled by default). \
-Disable with --skip-innodb-doublewrite.", (G_PTR*) &innobase_use_doublewrite,
- (G_PTR*) &innobase_use_doublewrite, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
+ {"innodb_doublewrite", OPT_INNODB_DOUBLEWRITE,
+ "Enable InnoDB doublewrite buffer during --prepare.",
+ (G_PTR*) &innobase_use_doublewrite,
+ (G_PTR*) &innobase_use_doublewrite, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
{"innodb_io_capacity", OPT_INNODB_IO_CAPACITY,
"Number of IOPs the server can do. Tunes the background IO rate",
(G_PTR*) &srv_io_capacity, (G_PTR*) &srv_io_capacity,
@@ -1013,26 +966,19 @@ Disable with --skip-innodb-doublewrite.", (G_PTR*) &innobase_use_doublewrite,
(G_PTR*) &innobase_unix_file_flush_method, 0, GET_STR, REQUIRED_ARG, 0, 0, 0,
0, 0, 0},
-/* ####### Should we use this option? ####### */
- {"innodb_force_recovery", OPT_INNODB_FORCE_RECOVERY,
- "Helps to save your data in case the disk image of the database becomes corrupt.",
- (G_PTR*) &innobase_force_recovery, (G_PTR*) &innobase_force_recovery, 0,
- GET_LONG, REQUIRED_ARG, 0, 0, 6, 0, 1, 0},
-
{"innodb_log_buffer_size", OPT_INNODB_LOG_BUFFER_SIZE,
"The size of the buffer which InnoDB uses to write log to the log files on disk.",
(G_PTR*) &innobase_log_buffer_size, (G_PTR*) &innobase_log_buffer_size, 0,
GET_LONG, REQUIRED_ARG, 1024*1024L, 256*1024L, LONG_MAX, 0, 1024, 0},
{"innodb_log_file_size", OPT_INNODB_LOG_FILE_SIZE,
- "Size of each log file in a log group.",
- (G_PTR*) &innobase_log_file_size, (G_PTR*) &innobase_log_file_size, 0,
- GET_LL, REQUIRED_ARG, 48*1024*1024L, 1*1024*1024L, LONGLONG_MAX, 0,
- 1024*1024L, 0},
+ "Ignored for mysqld option compatibility",
+ (G_PTR*) &srv_log_file_size, (G_PTR*) &srv_log_file_size, 0,
+ GET_ULL, REQUIRED_ARG, 48 << 20, 1 << 20, 512ULL << 30, 0,
+ UNIV_PAGE_SIZE_MAX, 0},
{"innodb_log_files_in_group", OPT_INNODB_LOG_FILES_IN_GROUP,
- "Number of log files in the log group. InnoDB writes to the files in a "
- "circular fashion. Value 3 is recommended here.",
- &innobase_log_files_in_group, &innobase_log_files_in_group,
- 0, GET_LONG, REQUIRED_ARG, 2, 2, 100, 0, 1, 0},
+ "Ignored for mysqld option compatibility",
+ &srv_n_log_files, &srv_n_log_files,
+ 0, GET_LONG, REQUIRED_ARG, 1, 1, 100, 0, 1, 0},
{"innodb_log_group_home_dir", OPT_INNODB_LOG_GROUP_HOME_DIR,
"Path to InnoDB log files.", &srv_log_group_home_dir,
&srv_log_group_home_dir, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
@@ -1054,25 +1000,17 @@ Disable with --skip-innodb-doublewrite.", (G_PTR*) &innobase_use_doublewrite,
/* Use GET_LL to support numeric suffixes in 5.6 */
GET_LL, REQUIRED_ARG,
(1LL << 14), (1LL << 12), (1LL << UNIV_PAGE_SIZE_SHIFT_MAX), 0, 1L, 0},
- {"innodb_log_block_size", OPT_INNODB_LOG_BLOCK_SIZE,
- "The log block size of the transaction log file. "
- "Changing for created log file is not supported. Use on your own risk!",
- (G_PTR*) &innobase_log_block_size, (G_PTR*) &innobase_log_block_size, 0,
- GET_ULONG, REQUIRED_ARG, 512, 512, 1 << UNIV_PAGE_SIZE_SHIFT_MAX, 0, 1L, 0},
- {"innodb_fast_checksum", OPT_INNODB_FAST_CHECKSUM,
- "Change the algorithm of checksum for the whole of datapage to 4-bytes word based.",
- (G_PTR*) &innobase_fast_checksum,
- (G_PTR*) &innobase_fast_checksum, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
- {"innodb_doublewrite_file", OPT_INNODB_DOUBLEWRITE_FILE,
- "Path to special datafile for doublewrite buffer. (default is "": not used)",
- (G_PTR*) &innobase_doublewrite_file, (G_PTR*) &innobase_doublewrite_file,
- 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"innodb_buffer_pool_filename", OPT_INNODB_BUFFER_POOL_FILENAME,
- "Filename to/from which to dump/load the InnoDB buffer pool",
+ "Ignored for mysqld option compatibility",
(G_PTR*) &innobase_buffer_pool_filename,
(G_PTR*) &innobase_buffer_pool_filename,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+#ifndef DBUG_OFF /* unfortunately "debug" collides with existing options */
+ {"dbug", '#', "Built in DBUG debugger.",
+ &dbug_option, &dbug_option, 0, GET_STR, OPT_ARG,
+ 0, 0, 0, 0, 0, 0},
+#endif
#ifndef __WIN__
{"debug-sync", OPT_XTRA_DEBUG_SYNC,
"Debug sync point. This is only used by the xtrabackup test suite",
@@ -1086,11 +1024,7 @@ Disable with --skip-innodb-doublewrite.", (G_PTR*) &innobase_use_doublewrite,
"INNODB, STRICT_INNODB, NONE, STRICT_NONE]", &srv_checksum_algorithm,
&srv_checksum_algorithm, &innodb_checksum_algorithm_typelib, GET_ENUM,
REQUIRED_ARG, SRV_CHECKSUM_ALGORITHM_INNODB, 0, 0, 0, 0, 0},
- {"innodb_log_checksum_algorithm", OPT_INNODB_LOG_CHECKSUM_ALGORITHM,
- "The algorithm InnoDB uses for log checksumming. [CRC32, STRICT_CRC32, "
- "INNODB, STRICT_INNODB, NONE, STRICT_NONE]", &srv_log_checksum_algorithm,
- &srv_log_checksum_algorithm, &innodb_checksum_algorithm_typelib, GET_ENUM,
- REQUIRED_ARG, SRV_CHECKSUM_ALGORITHM_INNODB, 0, 0, 0, 0, 0},
+
{"innodb_undo_directory", OPT_INNODB_UNDO_DIRECTORY,
"Directory where undo tablespace files live, this path can be absolute.",
&srv_undo_dir, &srv_undo_dir, 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0,
@@ -1116,7 +1050,12 @@ Disable with --skip-innodb-doublewrite.", (G_PTR*) &innobase_use_doublewrite,
{ "innodb-encrypt-log", OPT_INNODB_ENCRYPT_LOG, "encrypton plugin to load",
&srv_encrypt_log, &srv_encrypt_log,
0, GET_BOOL, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
-
+
+ {"innodb-log-checksums", OPT_INNODB_LOG_CHECKSUMS,
+ "Whether to require checksums for InnoDB redo log blocks",
+ &innodb_log_checksums, &innodb_log_checksums,
+ 0, GET_BOOL, REQUIRED_ARG, 1, 0, 0, 0, 0, 0 },
+
{"open_files_limit", OPT_OPEN_FILES_LIMIT, "the maximum number of file "
"descriptors to reserve with setrlimit().",
(G_PTR*) &xb_open_files_limit, (G_PTR*) &xb_open_files_limit, 0, GET_ULONG,
@@ -1270,13 +1209,7 @@ xb_get_one_option(int optid,
break;
case OPT_INNODB_LOG_FILES_IN_GROUP:
-
- ADD_PRINT_PARAM_OPT(innobase_log_files_in_group);
- break;
-
case OPT_INNODB_LOG_FILE_SIZE:
-
- ADD_PRINT_PARAM_OPT(innobase_log_file_size);
break;
case OPT_INNODB_FLUSH_METHOD:
@@ -1289,21 +1222,6 @@ xb_get_one_option(int optid,
ADD_PRINT_PARAM_OPT(innobase_page_size);
break;
- case OPT_INNODB_FAST_CHECKSUM:
-
- ADD_PRINT_PARAM_OPT(!!innobase_fast_checksum);
- break;
-
- case OPT_INNODB_LOG_BLOCK_SIZE:
-
- ADD_PRINT_PARAM_OPT(innobase_log_block_size);
- break;
-
- case OPT_INNODB_DOUBLEWRITE_FILE:
-
- ADD_PRINT_PARAM_OPT(innobase_doublewrite_file);
- break;
-
case OPT_INNODB_UNDO_DIRECTORY:
ADD_PRINT_PARAM_OPT(srv_undo_dir);
@@ -1321,13 +1239,6 @@ xb_get_one_option(int optid,
ADD_PRINT_PARAM_OPT(innodb_checksum_algorithm_names[srv_checksum_algorithm]);
break;
- case OPT_INNODB_LOG_CHECKSUM_ALGORITHM:
-
- ut_a(srv_log_checksum_algorithm <= SRV_CHECKSUM_ALGORITHM_STRICT_NONE);
-
- ADD_PRINT_PARAM_OPT(innodb_checksum_algorithm_names[srv_log_checksum_algorithm]);
- break;
-
case OPT_INNODB_BUFFER_POOL_FILENAME:
ADD_PRINT_PARAM_OPT(innobase_buffer_pool_filename);
@@ -1400,40 +1311,9 @@ xb_get_one_option(int optid,
return 0;
}
-/***********************************************************************
-Initializes log_block_size */
-static
-ibool
-xb_init_log_block_size(void)
-{
- srv_log_block_size = 0;
- if (innobase_log_block_size != 512) {
- uint n_shift = (uint)get_bit_shift(innobase_log_block_size);;
-
- if (n_shift > 0) {
- srv_log_block_size = (ulint)(1LL << n_shift);
- msg("InnoDB: The log block size is set to %lu.\n",
- srv_log_block_size);
- }
- } else {
- srv_log_block_size = 512;
- }
- if (!srv_log_block_size) {
- msg("InnoDB: Error: %lu is not valid value for "
- "innodb_log_block_size.\n", innobase_log_block_size);
- return FALSE;
- }
-
- return TRUE;
-}
-
static my_bool
innodb_init_param(void)
{
- /* innobase_init */
- static char current_dir[3]; /* Set if using current lib */
- my_bool ret;
- char *default_path;
srv_is_being_started = TRUE;
/* === some variables from mysqld === */
memset((G_PTR) &mysql_tmpdir_list, 0, sizeof(mysql_tmpdir_list));
@@ -1465,10 +1345,6 @@ innodb_init_param(void)
srv_page_size = (1 << srv_page_size_shift);
}
- if (!xb_init_log_block_size()) {
- goto error;
- }
-
/* Check that values don't overflow on 32-bit systems. */
if (sizeof(ulint) == 4) {
if (xtrabackup_use_memory > UINT_MAX32) {
@@ -1482,30 +1358,10 @@ innodb_init_param(void)
goto error;
}
-
- if (innobase_log_file_size > UINT_MAX32) {
- msg("xtrabackup: innobase_log_file_size can't be "
- "over 4GB on 32-bit systemsi\n");
-
- goto error;
- }
}
- os_innodb_umask = (ulint)0664;
-
- /* First calculate the default path for innodb_data_home_dir etc.,
- in case the user has not given any value.
-
- Note that when using the embedded server, the datadirectory is not
- necessarily the current directory of this program. */
-
- /* It's better to use current lib, to keep paths short */
- current_dir[0] = FN_CURLIB;
- current_dir[1] = FN_LIBCHAR;
- current_dir[2] = 0;
- default_path = current_dir;
-
- ut_a(default_path);
+ static char default_path[2] = { FN_CURLIB, 0 };
+ fil_path_to_mysql_datadir = default_path;
/* Set InnoDB initialization parameters according to the values
read from MySQL .cnf file */
@@ -1535,37 +1391,20 @@ innodb_init_param(void)
msg("xtrabackup: innodb_data_file_path = %s\n",
innobase_data_file_path);
- /* Since InnoDB edits the argument in the next call, we make another
- copy of it: */
+ /* This is the first time univ_page_size is used.
+ It was initialized to 16k pages before srv_page_size was set */
+ univ_page_size.copy_from(
+ page_size_t(srv_page_size, srv_page_size, false));
- internal_innobase_data_file_path = strdup(innobase_data_file_path);
+ srv_sys_space.set_space_id(TRX_SYS_SPACE);
+ srv_sys_space.set_name("innodb_system");
+ srv_sys_space.set_path(srv_data_home);
+ srv_sys_space.set_flags(FSP_FLAGS_PAGE_SSIZE());
- ret = (my_bool) srv_parse_data_file_paths_and_sizes(
- internal_innobase_data_file_path);
- if (ret == FALSE) {
- msg("xtrabackup: syntax error in innodb_data_file_path\n");
-mem_free_and_error:
- free(internal_innobase_data_file_path);
- internal_innobase_data_file_path = NULL;
+ if (!srv_sys_space.parse_params(innobase_data_file_path, true)) {
goto error;
}
- if (xtrabackup_prepare) {
- /* "--prepare" needs filenames only */
- ulint i;
-
- for (i=0; i < srv_n_data_files; i++) {
- char *p;
-
- p = srv_data_file_names[i];
- while ((p = strchr(p, SRV_PATH_SEPARATOR)) != NULL)
- {
- p++;
- srv_data_file_names[i] = p;
- }
- }
- }
-
/* -------------- Log files ---------------------------*/
/* The default dir for log files is the datadir of MySQL */
@@ -1579,60 +1418,38 @@ mem_free_and_error:
msg("xtrabackup: innodb_log_group_home_dir = %s\n",
srv_log_group_home_dir);
- srv_normalize_path_for_win(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 mem_free_and_error;
+ goto error;
}
srv_adaptive_flushing = FALSE;
- srv_use_sys_malloc = TRUE;
srv_file_format = 1; /* Barracuda */
srv_max_file_format_at_startup = UNIV_FORMAT_MIN; /* on */
/* --------------------------------------------------*/
srv_file_flush_method_str = innobase_unix_file_flush_method;
- srv_n_log_files = (ulint) innobase_log_files_in_group;
- srv_log_file_size = (ulint) innobase_log_file_size;
- msg("xtrabackup: innodb_log_files_in_group = %ld\n",
- srv_n_log_files);
- msg("xtrabackup: innodb_log_file_size = %lld\n",
- (long long int) srv_log_file_size);
-
srv_log_buffer_size = (ulint) innobase_log_buffer_size;
/* We set srv_pool_size here in units of 1 kB. InnoDB internally
changes the value so that it becomes the number of database pages. */
- //srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
srv_buf_pool_size = (ulint) xtrabackup_use_memory;
-
- srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
+ srv_buf_pool_chunk_unit = srv_buf_pool_size;
+ srv_buf_pool_instances = 1;
srv_n_file_io_threads = (ulint) innobase_file_io_threads;
srv_n_read_io_threads = (ulint) innobase_read_io_threads;
srv_n_write_io_threads = (ulint) innobase_write_io_threads;
- srv_force_recovery = (ulint) innobase_force_recovery;
-
srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
- if (!innobase_use_checksums) {
-
- srv_checksum_algorithm = SRV_CHECKSUM_ALGORITHM_NONE;
- }
-
- btr_search_enabled = (char) innobase_adaptive_hash_index;
- btr_search_index_num = 1;
-
os_use_large_pages = (ibool) innobase_use_large_pages;
os_large_page_size = (ulint) innobase_large_page_size;
- static char default_dir[3] = "./";
- srv_arch_dir = default_dir;
row_rollback_on_timeout = (ibool) innobase_rollback_on_timeout;
srv_file_per_table = (my_bool) innobase_file_per_table;
@@ -1650,18 +1467,8 @@ mem_free_and_error:
/* We cannot treat characterset here for now!! */
data_mysql_default_charset_coll = (ulint)default_charset_info->number;
- ut_a(DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL ==
- my_charset_latin1.number);
ut_a(DATA_MYSQL_BINARY_CHARSET_COLL == my_charset_bin.number);
- /* Store the latin1_swedish_ci character ordering table to InnoDB. For
- non-latin1_swedish_ci charsets we use the MySQL comparison functions,
- and consequently we do not need to know the ordering internally in
- InnoDB. */
-
- ut_a(0 == strcmp(my_charset_latin1.name, "latin1_swedish_ci"));
- srv_latin1_ordering = my_charset_latin1.sort_order;
-
//innobase_commit_concurrency_init_default();
/* Since we in this module access directly the fields of a trx
@@ -1675,31 +1482,8 @@ mem_free_and_error:
innobase_start_or_create_for_mysql(). As we don't call it in xtrabackup,
we have to duplicate checks from that function here. */
-#ifdef __WIN__
- switch (os_get_os_version()) {
- case OS_WIN95:
- case OS_WIN31:
- case OS_WINNT:
- /* On Win 95, 98, ME, Win32 subsystem for Windows 3.1,
- and NT use simulated aio. In NT Windows provides async i/o,
- but when run in conjunction with InnoDB Hot Backup, it seemed
- to corrupt the data files. */
-
- srv_use_native_aio = FALSE;
- break;
-
- case OS_WIN2000:
- case OS_WINXP:
- /* On 2000 and XP, async IO is available. */
- srv_use_native_aio = TRUE;
- break;
-
- default:
- /* Vista and later have both async IO and condition variables */
- srv_use_native_aio = TRUE;
- srv_use_native_conditions = TRUE;
- break;
- }
+#ifdef _WIN32
+ srv_use_native_aio = TRUE;
#elif defined(LINUX_NATIVE_AIO)
@@ -1726,7 +1510,9 @@ mem_free_and_error:
srv_undo_dir = my_strdup(".", MYF(MY_FAE));
}
- innodb_log_checksum_func_update(srv_log_checksum_algorithm);
+ log_checksum_algorithm_ptr = innodb_log_checksums || srv_encrypt_log
+ ? log_block_calc_checksum_crc32
+ : log_block_calc_checksum_none;
return(FALSE);
@@ -1735,57 +1521,17 @@ error:
return(TRUE);
}
-static my_bool
-innodb_init(void)
+static bool innodb_init()
{
- int err;
- srv_is_being_started = TRUE;
- err = innobase_start_or_create_for_mysql();
-
+ dberr_t err = innobase_start_or_create_for_mysql();
if (err != DB_SUCCESS) {
- free(internal_innobase_data_file_path);
- internal_innobase_data_file_path = NULL;
- goto error;
+ msg("xtrabackup: innodb_init() returned %d (%s).\n",
+ err, ut_strerr(err));
+ innodb_shutdown();
+ return(TRUE);
}
- /* They may not be needed for now */
-// (void) hash_init(&innobase_open_tables,system_charset_info, 32, 0, 0,
-// (hash_get_key) innobase_get_key, 0, 0);
-// pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
-// pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
-// pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
-// pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
-// pthread_cond_init(&commit_cond, NULL);
-
- innodb_inited= 1;
-
return(FALSE);
-
-error:
- msg("xtrabackup: innodb_init(): Error occured.\n");
- return(TRUE);
-}
-
-static void
-innodb_end()
-{
- srv_fast_shutdown = (ulint) innobase_fast_shutdown;
- innodb_inited = 0;
-
- msg("xtrabackup: starting shutdown with innodb_fast_shutdown = %lu\n",
- srv_fast_shutdown);
-
- innodb_shutdown();
- free(internal_innobase_data_file_path);
- internal_innobase_data_file_path = NULL;
-
- /* They may not be needed for now */
-// hash_free(&innobase_open_tables);
-// pthread_mutex_destroy(&innobase_share_mutex);
-// pthread_mutex_destroy(&prepare_commit_mutex);
-// pthread_mutex_destroy(&commit_threads_m);
-// pthread_mutex_destroy(&commit_cond_m);
-// pthread_cond_destroy(&commit_cond);
}
/* ================= common ================= */
@@ -1940,8 +1686,7 @@ xb_read_delta_metadata(const char *filepath, xb_delta_info_t *info)
my_bool r = TRUE;
/* set defaults */
- info->page_size = ULINT_UNDEFINED;
- info->zip_size = ULINT_UNDEFINED;
+ ulint page_size = ULINT_UNDEFINED, zip_size = 0;
info->space_id = ULINT_UNDEFINED;
fp = fopen(filepath, "r");
@@ -1953,9 +1698,9 @@ xb_read_delta_metadata(const char *filepath, xb_delta_info_t *info)
while (!feof(fp)) {
if (fscanf(fp, "%50s = %50s\n", key, value) == 2) {
if (strcmp(key, "page_size") == 0) {
- info->page_size = strtoul(value, NULL, 10);
+ page_size = strtoul(value, NULL, 10);
} else if (strcmp(key, "zip_size") == 0) {
- info->zip_size = strtoul(value, NULL, 10);
+ zip_size = strtoul(value, NULL, 10);
} else if (strcmp(key, "space_id") == 0) {
info->space_id = strtoul(value, NULL, 10);
}
@@ -1964,10 +1709,14 @@ xb_read_delta_metadata(const char *filepath, xb_delta_info_t *info)
fclose(fp);
- if (info->page_size == ULINT_UNDEFINED) {
+ if (page_size == ULINT_UNDEFINED) {
msg("xtrabackup: page_size is required in %s\n", filepath);
r = FALSE;
+ } else {
+ info->page_size = page_size_t(zip_size ? zip_size : page_size,
+ page_size, zip_size != 0);
}
+
if (info->space_id == ULINT_UNDEFINED) {
msg("xtrabackup: Warning: This backup was taken with XtraBackup 2.0.1 "
"or earlier, some DDL operations between full and incremental "
@@ -1993,7 +1742,10 @@ xb_write_delta_metadata(const char *filename, const xb_delta_info_t *info)
"page_size = %lu\n"
"zip_size = %lu\n"
"space_id = %lu\n",
- info->page_size, info->zip_size, info->space_id);
+ info->page_size.logical(),
+ info->page_size.is_compressed()
+ ? info->page_size.physical() : 0,
+ info->space_id);
len = strlen(buf);
mystat.st_size = len;
@@ -2150,7 +1902,7 @@ check_if_skip_database_by_path(
return(FALSE);
}
- const char* db_name = strrchr(path, SRV_PATH_SEPARATOR);
+ const char* db_name = strrchr(path, OS_PATH_SEPARATOR);
if (db_name == NULL) {
db_name = path;
} else {
@@ -2258,33 +2010,26 @@ check_if_skip_table(
return(FALSE);
}
-/***********************************************************************
-Reads the space flags from a given data file and returns the compressed
-page size, or 0 if the space is not compressed. */
-ulint
-xb_get_zip_size(pfs_os_file_t file)
+/** @return the tablespace flags from a given data file
+@retval ULINT_UNDEFINED if the file is not readable */
+ulint xb_get_space_flags(pfs_os_file_t file)
{
byte *buf;
byte *page;
- ulint zip_size = ULINT_UNDEFINED;
- ibool success;
- ulint space;
+ ulint flags;
- buf = static_cast<byte *>(ut_malloc(2 * UNIV_PAGE_SIZE));
+ buf = static_cast<byte *>(malloc(2 * UNIV_PAGE_SIZE));
page = static_cast<byte *>(ut_align(buf, UNIV_PAGE_SIZE));
- success = os_file_read(file, page, 0, UNIV_PAGE_SIZE);
- if (!success) {
- goto end;
+ if (os_file_read(IORequestRead, file, page, 0, UNIV_PAGE_SIZE)) {
+ flags = fsp_header_get_flags(page);
+ } else {
+ flags = ULINT_UNDEFINED;
}
- space = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
- zip_size = (space == 0 ) ? 0 :
- dict_tf_get_zip_size(fsp_header_get_flags(page));
-end:
- ut_free(buf);
+ free(buf);
- return(zip_size);
+ return(flags);
}
const char*
@@ -2323,7 +2068,6 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n)
xb_write_filt_ctxt_t write_filt_ctxt;
const char *action;
xb_read_filt_t *read_filter;
- ibool is_system;
my_bool rc = FALSE;
/* Get the name and the path for the tablespace. node->name always
@@ -2338,9 +2082,8 @@ xtrabackup_copy_datafile(fil_node_t* node, uint thread_n)
const char* const node_name = node->space->name;
const char* const node_path = node->name;
- is_system = !fil_is_user_tablespace_id(node->space->id);
-
- if (!is_system && check_if_skip_table(node_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);
return(FALSE);
}
@@ -2449,50 +2192,29 @@ skip:
return(FALSE);
}
-extern ibool log_block_checksum_is_ok_or_old_format(const byte* block);
-
-/*******************************************************//**
-Scans log from a buffer and writes new log data to the outpud datasinc.
-@return true if success */
+/** Copy redo log blocks to the data sink.
+@param[in] is_last whether this is the last log segment to copy
+@param[in] start_lsn buffer start LSN
+@param[in] end_lsn buffer end LSN
+@return last copied LSN
+@retval 0 on failure */
static
-bool
-xtrabackup_scan_log_recs(
-/*===============*/
- log_group_t* group, /*!< in: log group */
- bool is_last, /*!< in: whether it is last segment
- to copy */
- lsn_t start_lsn, /*!< in: buffer start lsn */
- lsn_t* contiguous_lsn, /*!< in/out: it is known that all log
- groups contain contiguous log data up
- to this lsn */
- lsn_t* group_scanned_lsn,/*!< out: scanning succeeded up to
- this lsn */
- bool* finished) /*!< out: false if is not able to scan
- any more in this log group */
+lsn_t
+xtrabackup_copy_log(bool is_last, lsn_t start_lsn, lsn_t end_lsn)
{
- lsn_t scanned_lsn;
- ulint data_len;
- ulint write_size;
- const byte* log_block;
-
- ulint scanned_checkpoint_no = 0;
+ lsn_t scanned_lsn = start_lsn;
- *finished = false;
- scanned_lsn = start_lsn;
- log_block = log_sys->buf;
+ const ulint blocks_in_group = log_block_convert_lsn_to_no(
+ log_sys->log.capacity()) - 1;
+ const byte* log_block = log_sys->buf;
- while (log_block < log_sys->buf + RECV_SCAN_SIZE && !*finished) {
+ for (ulint scanned_checkpoint = 0;
+ scanned_lsn < end_lsn;
+ log_block += OS_FILE_LOG_BLOCK_SIZE) {
ulint no = log_block_get_hdr_no(log_block);
ulint scanned_no = log_block_convert_lsn_to_no(scanned_lsn);
- ibool checksum_is_ok =
- log_block_checksum_is_ok_or_old_format(log_block);
-
- if (no != scanned_no && checksum_is_ok) {
- ulint blocks_in_group;
-
- blocks_in_group = log_block_convert_lsn_to_no(
- log_group_get_capacity(group)) - 1;
+ if (no != scanned_no) {
if ((no < scanned_no &&
((scanned_no - no) % blocks_in_group) == 0) ||
no == 0 ||
@@ -2501,15 +2223,15 @@ xtrabackup_scan_log_recs(
blocks_in_group == 0) {
/* old log block, do nothing */
- *finished = true;
break;
}
msg("xtrabackup: error:"
" log block numbers mismatch:\n"
- "xtrabackup: error: expected log block no. %lu,"
- " but got no. %lu from the log file.\n",
- (ulong) scanned_no, (ulong) no);
+ "xtrabackup: error: expected log block no. "
+ ULINTPF ", but got no. " ULINTPF
+ " from the log file.\n",
+ scanned_no, no);
if ((no - scanned_no) % blocks_in_group == 0) {
msg("xtrabackup: error:"
@@ -2520,155 +2242,115 @@ xtrabackup_scan_log_recs(
" log files being too small.\n");
}
- return(false);
- } else if (!checksum_is_ok) {
- /* Garbage or an incompletely written log block */
-
- msg("xtrabackup: warning: Log block checksum mismatch"
- " (block no %lu at lsn " LSN_PF "): \n"
- "expected %lu, calculated checksum %lu\n",
- (ulong) no,
- scanned_lsn,
- (ulong) log_block_get_checksum(log_block),
- (ulong) log_block_calc_checksum(log_block));
- msg("xtrabackup: warning: this is possible when the "
- "log block has not been fully written by the "
- "server, will retry later.\n");
- *finished = true;
- break;
- }
-
- if (log_block_get_flush_bit(log_block)) {
- /* This block was a start of a log flush operation:
- we know that the previous flush operation must have
- been completed for all log groups before this block
- can have been flushed to any of the groups. Therefore,
- we know that log data is contiguous up to scanned_lsn
- in all non-corrupt log groups. */
-
- if (scanned_lsn > *contiguous_lsn) {
-
- *contiguous_lsn = scanned_lsn;
- }
+ return(0);
}
- data_len = log_block_get_data_len(log_block);
-
- if (
- (scanned_checkpoint_no > 0)
- && (log_block_get_checkpoint_no(log_block)
- < scanned_checkpoint_no)
- && (scanned_checkpoint_no
- - log_block_get_checkpoint_no(log_block)
- > 0x80000000UL)) {
+ ulint checkpoint = log_block_get_checkpoint_no(log_block);
+ if (scanned_checkpoint > checkpoint
+ && scanned_checkpoint - checkpoint >= 0x80000000UL) {
/* Garbage from a log buffer flush which was made
before the most recent database recovery */
-
- *finished = true;
break;
}
- scanned_lsn = scanned_lsn + data_len;
- scanned_checkpoint_no = log_block_get_checkpoint_no(log_block);
-
- if (data_len < OS_FILE_LOG_BLOCK_SIZE) {
- /* Log data for this group ends here */
+ scanned_checkpoint = checkpoint;
+ ulint data_len = log_block_get_data_len(log_block);
+ scanned_lsn += data_len;
- *finished = true;
- } else {
- log_block += OS_FILE_LOG_BLOCK_SIZE;
+ if (data_len != OS_FILE_LOG_BLOCK_SIZE) {
+ break;
}
}
- *group_scanned_lsn = scanned_lsn;
-
- /* ===== write log to 'xtrabackup_logfile' ====== */
- if (!*finished) {
- write_size = RECV_SCAN_SIZE;
- } else {
- write_size = (ulint)(ut_uint64_align_up(scanned_lsn,
- OS_FILE_LOG_BLOCK_SIZE) - start_lsn);
- if (!is_last && scanned_lsn % OS_FILE_LOG_BLOCK_SIZE) {
- write_size -= OS_FILE_LOG_BLOCK_SIZE;
- }
+ if (!is_last && scanned_lsn & (OS_FILE_LOG_BLOCK_SIZE - 1)) {
+ /* Omit the partial last block. */
+ scanned_lsn &= ~(OS_FILE_LOG_BLOCK_SIZE - 1);
}
- if (write_size == 0) {
- return(true);
- }
+ log_sys->log.scanned_lsn = scanned_lsn;
- if (srv_encrypt_log) {
- log_encrypt_before_write(scanned_checkpoint_no,
- log_sys->buf, write_size);
- }
+ if (ulint write_size = ulint(ut_uint64_align_up(scanned_lsn,
+ OS_FILE_LOG_BLOCK_SIZE)
+ - start_lsn)) {
+ if (srv_encrypt_log) {
+ log_crypt(log_sys->buf, write_size);
+ }
- if (ds_write(dst_log_file, log_sys->buf, write_size)) {
- msg("xtrabackup: Error: "
- "write to logfile failed\n");
- return(false);
+ if (ds_write(dst_log_file, log_sys->buf, write_size)) {
+ msg("xtrabackup: Error: "
+ "write to logfile failed\n");
+ return(0);
+ }
}
- return(true);
+ return(scanned_lsn);
}
-static my_bool
-xtrabackup_copy_logfile(lsn_t from_lsn, my_bool is_last)
+/** Copy redo log until the current end of the log is reached
+@param is_last whether this is the last run at the end of backup
+@return whether the operation failed */
+static bool
+xtrabackup_copy_logfile(bool is_last)
{
- /* definition from recv_recovery_from_checkpoint_start() */
- lsn_t contiguous_lsn;
-
ut_a(dst_log_file != NULL);
+ ut_ad(recv_sys != NULL);
- /* read from checkpoint_lsn_start to current */
- contiguous_lsn = ut_uint64_align_down(from_lsn, OS_FILE_LOG_BLOCK_SIZE);
-
- /* TODO: We must check the contiguous_lsn still exists in log file.. */
-
- bool finished;
lsn_t start_lsn;
lsn_t end_lsn;
- /* reference recv_group_scan_log_recs() */
-
- start_lsn = contiguous_lsn;
+ start_lsn = ut_uint64_align_down(log_copy_scanned_lsn,
+ OS_FILE_LOG_BLOCK_SIZE);
- do {
+ /* When copying the last part of the log, retry a few times to
+ ensure that all log up to the last checkpoint will be read. */
+ for (unsigned retries = is_last ? 3 : 0;;) {
end_lsn = start_lsn + RECV_SCAN_SIZE;
xtrabackup_io_throttling();
log_mutex_enter();
- log_group_read_log_seg(LOG_RECOVER, log_sys->buf,
- &log_sys->log, start_lsn, end_lsn);
+ lsn_t lsn = log_group_read_log_seg(log_sys->buf, &log_sys->log,
+ start_lsn, end_lsn);
- bool success = xtrabackup_scan_log_recs(
- &log_sys->log, is_last,
- start_lsn, &contiguous_lsn,
- &log_sys->log.scanned_lsn,
- &finished);
+ start_lsn = xtrabackup_copy_log(is_last, start_lsn, lsn);
log_mutex_exit();
- if (!success) {
+ if (!start_lsn) {
ds_close(dst_log_file);
+ dst_log_file = NULL;
msg("xtrabackup: Error: xtrabackup_copy_logfile()"
" failed.\n");
- return(TRUE);
+ return(true);
}
- start_lsn = end_lsn;
- } while (!finished);
+ if (start_lsn == end_lsn) {
+ /* All RECV_SCAN_SIZE bytes that were read
+ were valid redo log. Proceed to read more. */
+ } else if (start_lsn & (OS_FILE_LOG_BLOCK_SIZE - 1)) {
+ /* The end of the log was encountered. */
+ ut_ad(is_last);
+ break;
+ } else if (retries--) {
+ /* Retry copying the last log segment. */
+ ut_ad(is_last);
+ os_thread_sleep(xtrabackup_log_copy_interval * 1000);
+ } else {
+ break;
+ }
+ }
- msg_ts(">> log scanned up to (" LSN_PF ")\n",
- log_sys->log.scanned_lsn);
+ ut_ad(start_lsn == log_sys->log.scanned_lsn);
+
+ msg_ts(">> log scanned up to (" LSN_PF ")\n", start_lsn);
/* update global variable*/
- log_copy_scanned_lsn = log_sys->log.scanned_lsn;
+ log_copy_scanned_lsn = start_lsn;
debug_sync_point("xtrabackup_copy_logfile_pause");
- return(FALSE);
+ return(false);
}
static
@@ -2677,8 +2359,7 @@ void*
#else
ulint
#endif
-log_copying_thread(
- void* arg __attribute__((unused)))
+log_copying_thread(void*)
{
/*
Initialize mysys thread-specific memory so we can
@@ -2686,31 +2367,17 @@ log_copying_thread(
*/
my_thread_init();
- ut_a(dst_log_file != NULL);
-
- log_copying_running = TRUE;
-
- while(log_copying) {
+ while (log_copying) {
os_event_reset(log_copying_stop);
os_event_wait_time_low(log_copying_stop,
xtrabackup_log_copy_interval * 1000ULL,
0);
- if (log_copying) {
- if(xtrabackup_copy_logfile(log_copy_scanned_lsn,
- FALSE)) {
-
- exit(EXIT_FAILURE);
- }
+ if (log_copying && xtrabackup_copy_logfile(false)) {
+ break;
}
}
- /* last copying */
- if(xtrabackup_copy_logfile(log_copy_scanned_lsn, TRUE)) {
-
- exit(EXIT_FAILURE);
- }
-
- log_copying_running = FALSE;
+ log_copying_running = false;
my_thread_end();
os_thread_exit(NULL);
@@ -2724,15 +2391,11 @@ void*
#else
ulint
#endif
-io_watching_thread(
- void* arg)
+io_watching_thread(void*)
{
- (void)arg;
/* currently, for --backup only */
ut_a(xtrabackup_backup);
- io_watching_thread_running = TRUE;
-
while (log_copying) {
os_thread_sleep(1000000); /*1 sec*/
io_ticket = xtrabackup_throttle;
@@ -2743,47 +2406,11 @@ io_watching_thread(
xtrabackup_throttle = 0;
os_event_set(wait_throttle);
- io_watching_thread_running = FALSE;
-
- os_thread_exit(NULL);
-
- return(0);
-}
-
-/************************************************************************
-I/o-handler thread function. */
-static
-
-#ifndef __WIN__
-void*
-#else
-ulint
-#endif
-io_handler_thread(
-/*==============*/
- void* arg)
-{
- ulint segment;
-
-
- segment = *((ulint*)arg);
-
- while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) {
- fil_aio_wait(segment);
- }
-
- /* We count the number of threads in os_thread_exit(). A created
- thread should always use that to exit and not use return() to exit.
- The thread actually never comes here because it is exited in an
- os_event_wait(). */
+ io_watching_thread_running = false;
os_thread_exit(NULL);
-#ifndef __WIN__
- return(NULL); /* Not reached */
-#else
return(0);
-#endif
}
/**************************************************************************
@@ -2816,9 +2443,9 @@ data_copy_thread_func(
}
}
- os_mutex_enter(ctxt->count_mutex);
+ pthread_mutex_lock(&ctxt->count_mutex);
(*ctxt->count)--;
- os_mutex_exit(ctxt->count_mutex);
+ pthread_mutex_unlock(&ctxt->count_mutex);
my_thread_end();
os_thread_exit(NULL);
@@ -2831,7 +2458,7 @@ Initialize the appropriate datasink(s). Both local backups and streaming in the
Otherwise (i.e. when streaming in the 'tar' format) we need 2 separate datasinks
for the data stream (and don't allow parallel data copying) and for metainfo
-files (including xtrabackup_logfile). The second datasink writes to temporary
+files (including ib_logfile0). The second datasink writes to temporary
files first, and then streams them in a serialized way when closed. */
static void
xtrabackup_init_datasinks(void)
@@ -2917,41 +2544,261 @@ static void xtrabackup_destroy_datasinks(void)
ds_redo = NULL;
}
-#define SRV_N_PENDING_IOS_PER_THREAD OS_AIO_N_PENDING_IOS_PER_THREAD
#define SRV_MAX_N_PENDING_SYNC_IOS 100
-/************************************************************************
-@return TRUE if table should be opened. */
+/** Initialize the tablespace cache subsystem. */
static
-ibool
-xb_check_if_open_tablespace(
- const char* db,
- const char* table)
+void
+xb_fil_io_init()
{
- char buf[FN_REFLEN];
-
- snprintf(buf, sizeof(buf), "%s/%s", db, table);
+ fil_init(srv_file_per_table ? 50000 : 5000, LONG_MAX);
+ fsp_init();
+}
- return !check_if_skip_table(buf);
+static
+Datafile*
+xb_new_datafile(const char *name, bool is_remote)
+{
+ if (is_remote) {
+ RemoteDatafile *remote_file = new RemoteDatafile();
+ remote_file->set_name(name);
+ return(remote_file);
+ } else {
+ Datafile *file = new Datafile();
+ file->set_name(name);
+ file->make_filepath(".", name, IBD);
+ return(file);
+ }
}
-/************************************************************************
-Initializes the I/O and tablespace cache subsystems. */
static
void
-xb_fil_io_init(void)
-/*================*/
+xb_load_single_table_tablespace(
+ const char *dirname,
+ const char *filname,
+ bool is_remote)
{
- srv_n_file_io_threads = srv_n_read_io_threads;
+ /* Ignore .isl files on XtraBackup recovery. All tablespaces must be
+ local. */
+ if (is_remote && srv_operation == SRV_OPERATION_RESTORE) {
+ return;
+ }
+ if (check_if_skip_table(filname)) {
+ return;
+ }
- os_aio_init(8 * SRV_N_PENDING_IOS_PER_THREAD,
- srv_n_read_io_threads,
- srv_n_write_io_threads,
- SRV_MAX_N_PENDING_SYNC_IOS);
+ /* The name ends in .ibd or .isl;
+ try opening the file */
+ char* name;
+ size_t dirlen = dirname == NULL ? 0 : strlen(dirname);
+ size_t namelen = strlen(filname);
+ ulint pathlen = dirname == NULL ? namelen + 1: dirlen + namelen + 2;
+ lsn_t flush_lsn;
+ dberr_t err;
+ fil_space_t *space;
- fil_init(srv_file_per_table ? 50000 : 5000, LONG_MAX);
+ name = static_cast<char*>(ut_malloc_nokey(pathlen));
- fsp_init();
+ if (dirname != NULL) {
+ ut_snprintf(name, pathlen, "%s/%s", dirname, filname);
+ name[pathlen - 5] = 0;
+ } else {
+ ut_snprintf(name, pathlen, "%s", filname);
+ name[pathlen - 5] = 0;
+ }
+
+ Datafile *file = xb_new_datafile(name, is_remote);
+
+ if (file->open_read_only(true) != DB_SUCCESS) {
+ ut_free(name);
+ exit(EXIT_FAILURE);
+ }
+
+ err = file->validate_first_page(&flush_lsn);
+
+ if (err == DB_SUCCESS && file->space_id() != SRV_TMP_SPACE_ID) {
+ os_offset_t node_size = os_file_get_size(file->handle());
+ os_offset_t n_pages;
+
+ ut_a(node_size != (os_offset_t) -1);
+
+ n_pages = node_size / page_size_t(file->flags()).physical();
+
+ space = fil_space_create(
+ name, file->space_id(), file->flags(),
+ FIL_TYPE_TABLESPACE, NULL/* TODO: crypt_data */);
+
+ ut_a(space != NULL);
+
+ if (!fil_node_create(file->filepath(), n_pages, space,
+ false, false)) {
+ ut_error;
+ }
+
+ /* by opening the tablespace we forcing node and space objects
+ in the cache to be populated with fields from space header */
+ fil_space_open(space->name);
+
+ if (srv_operation == SRV_OPERATION_RESTORE || xb_close_files) {
+ fil_space_close(space->name);
+ }
+ }
+
+ ut_free(name);
+
+ if (fil_space_crypt_t* crypt_info = file->get_crypt_info()) {
+ fil_space_destroy_crypt_data(&crypt_info);
+ }
+
+ 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);
+ }
+}
+
+/** Scan the database directories under the MySQL datadir, looking for
+.ibd files and determining the space id in each of them.
+@return DB_SUCCESS or error number */
+static
+dberr_t
+xb_load_single_table_tablespaces()
+{
+ int ret;
+ char* dbpath = NULL;
+ ulint dbpath_len = 100;
+ os_file_dir_t dir;
+ os_file_dir_t dbdir;
+ os_file_stat_t dbinfo;
+ os_file_stat_t fileinfo;
+ dberr_t err = DB_SUCCESS;
+
+ /* The datadir of MySQL is always the default directory of mysqld */
+
+ dir = os_file_opendir(fil_path_to_mysql_datadir, true);
+
+ if (dir == NULL) {
+
+ return(DB_ERROR);
+ }
+
+ dbpath = static_cast<char*>(ut_malloc_nokey(dbpath_len));
+
+ /* Scan all directories under the datadir. They are the database
+ directories of MySQL. */
+
+ ret = fil_file_readdir_next_file(&err, fil_path_to_mysql_datadir, dir,
+ &dbinfo);
+ while (ret == 0) {
+ size_t len = strlen(dbinfo.name);
+
+ /* General tablespaces are always at the first level of the
+ data home dir */
+ if (dbinfo.type == OS_FILE_TYPE_FILE && len > 4) {
+ bool is_isl = !strcmp(dbinfo.name + len - 4, ".isl");
+ bool is_ibd = !is_isl
+ && !strcmp(dbinfo.name + len - 4, ".ibd");
+
+ if (is_isl || is_ibd) {
+ xb_load_single_table_tablespace(
+ NULL, dbinfo.name, is_isl);
+ }
+ }
+
+ if (dbinfo.type == OS_FILE_TYPE_FILE
+ || dbinfo.type == OS_FILE_TYPE_UNKNOWN) {
+
+ goto next_datadir_item;
+ }
+
+ /* We found a symlink or a directory; try opening it to see
+ if a symlink is a directory */
+
+ len = strlen(fil_path_to_mysql_datadir)
+ + strlen (dbinfo.name) + 2;
+ if (len > dbpath_len) {
+ dbpath_len = len;
+
+ if (dbpath) {
+ ut_free(dbpath);
+ }
+
+ dbpath = static_cast<char*>(ut_malloc_nokey(dbpath_len));
+ }
+ ut_snprintf(dbpath, dbpath_len,
+ "%s/%s", fil_path_to_mysql_datadir, dbinfo.name);
+ os_normalize_path(dbpath);
+
+ if (check_if_skip_database_by_path(dbpath)) {
+ fprintf(stderr, "Skipping db: %s\n", dbpath);
+ goto next_datadir_item;
+ }
+
+ /* We want wrong directory permissions to be a fatal error for
+ XtraBackup. */
+ dbdir = os_file_opendir(dbpath, true);
+
+ if (dbdir != NULL) {
+
+ /* We found a database directory; loop through it,
+ looking for possible .ibd files in it */
+
+ for (ret = fil_file_readdir_next_file(&err, dbpath,
+ dbdir,
+ &fileinfo);
+ ret == 0;
+ ret = fil_file_readdir_next_file(&err, dbpath,
+ dbdir,
+ &fileinfo)) {
+ if (fileinfo.type == OS_FILE_TYPE_DIR) {
+ continue;
+ }
+
+ size_t len = strlen(fileinfo.name);
+
+ /* We found a symlink or a file */
+ if (len > 4
+ && !strcmp(fileinfo.name + len - 4,
+ ".ibd")) {
+ xb_load_single_table_tablespace(
+ dbinfo.name, fileinfo.name,
+ false);
+ }
+ }
+
+ if (0 != os_file_closedir(dbdir)) {
+ fprintf(stderr, "InnoDB: Warning: could not"
+ " close database directory %s\n",
+ dbpath);
+
+ err = DB_ERROR;
+ }
+
+ } else {
+
+ err = DB_ERROR;
+ break;
+
+ }
+
+next_datadir_item:
+ ret = fil_file_readdir_next_file(&err,
+ fil_path_to_mysql_datadir,
+ dir, &dbinfo);
+ }
+
+ ut_free(dbpath);
+
+ if (0 != os_file_closedir(dir)) {
+ fprintf(stderr,
+ "InnoDB: Error: could not close MySQL datadir\n");
+
+ return(DB_ERROR);
+ }
+
+ return(err);
}
/****************************************************************************
@@ -2961,25 +2808,26 @@ static
dberr_t
xb_load_tablespaces()
{
- ulint i;
bool create_new_db;
dberr_t err;
ulint sum_of_new_sizes;
- lsn_t min_arch_logno, max_arch_logno;
+ lsn_t flush_lsn;
- for (i = 0; i < srv_n_file_io_threads; i++) {
- thread_nr[i] = i;
+ ut_ad(srv_operation == SRV_OPERATION_BACKUP
+ || srv_operation == SRV_OPERATION_RESTORE);
- os_thread_create(io_handler_thread, thread_nr + i,
- thread_ids + i);
- }
+ err = srv_sys_space.check_file_spec(&create_new_db, 0);
- os_thread_sleep(200000); /*0.2 sec*/
+ /* create_new_db must not be true. */
+ if (err != DB_SUCCESS || create_new_db) {
+ msg("xtrabackup: could not find data files at the "
+ "specified datadir\n");
+ return(DB_ERROR);
+ }
+
+ err = srv_sys_space.open_or_create(false, false, &sum_of_new_sizes,
+ &flush_lsn);
- err = open_or_create_data_files(&create_new_db,
- &min_arch_logno, &max_arch_logno,
- &flushed_lsn,
- &sum_of_new_sizes);
if (err != DB_SUCCESS) {
msg("xtrabackup: Could not open or create data files.\n"
"xtrabackup: If you tried to add new data files, and it "
@@ -2997,30 +2845,21 @@ xb_load_tablespaces()
return(err);
}
- /* create_new_db must not be TRUE.. */
- if (create_new_db) {
- msg("xtrabackup: could not find data files at the "
- "specified datadir\n");
- return(DB_ERROR);
- }
-
/* Add separate undo tablespaces to fil_system */
- err = srv_undo_tablespaces_init(FALSE,
- TRUE,
- srv_undo_tablespaces,
- &srv_undo_tablespaces_open);
+ err = srv_undo_tablespaces_init(false);
+
if (err != DB_SUCCESS) {
return(err);
}
- /* It is important to call fil_load_single_table_tablespace() after
+ /* It is important to call xb_load_single_table_tablespaces() after
srv_undo_tablespaces_init(), because fil_is_user_tablespace_id() *
relies on srv_undo_tablespaces_open to be properly initialized */
msg("xtrabackup: Generating a list of tablespaces\n");
- err = fil_load_single_table_tablespaces(xb_check_if_open_tablespace);
+ err = xb_load_single_table_tablespaces();
if (err != DB_SUCCESS) {
return(err);
}
@@ -3049,42 +2888,11 @@ static
void
xb_data_files_close()
{
- ulint i;
-
- /* Shutdown the aio threads. This has been copied from
- innobase_shutdown_for_mysql(). */
-
- srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS;
-
- for (i = 0; i < 1000; i++) {
- os_aio_wake_all_threads_at_shutdown();
-
- if (os_thread_count == 0) {
- break;
- }
- os_thread_sleep(10000);
- }
-
- if (i == 1000) {
- msg("xtrabackup: Warning: %lu threads created by InnoDB"
- " had not exited at shutdown!\n",
- (ulong) os_thread_count);
- }
-
- os_aio_free();
-
+ ut_ad(!os_thread_count);
fil_close_all_files();
-
- /* Free the double write data structures. */
if (buf_dblwr) {
buf_dblwr_free();
}
-
- /* Reset srv_file_io_threads to its default value to avoid confusing
- warning on --prepare in innobase_start_or_create_for_mysql()*/
- srv_n_file_io_threads = 4;
-
- srv_shutdown_state = SRV_SHUTDOWN_NONE;
}
/***********************************************************************
@@ -3103,7 +2911,7 @@ xb_new_filter_entry(
ut_a(namelen <= NAME_LEN * 2 + 1);
entry = static_cast<xb_filter_entry_t *>
- (ut_malloc(sizeof(xb_filter_entry_t) + namelen + 1));
+ (malloc(sizeof(xb_filter_entry_t) + namelen + 1));
memset(entry, '\0', sizeof(xb_filter_entry_t) + namelen + 1);
entry->name = ((char*)entry) + sizeof(xb_filter_entry_t);
strcpy(entry->name, name);
@@ -3402,7 +3210,7 @@ xb_filter_hash_free(hash_table_t* hash)
HASH_DELETE(xb_filter_entry_t, name_hash, hash,
ut_fold_string(prev_table->name), prev_table);
- ut_free(prev_table);
+ free(prev_table);
}
}
@@ -3451,77 +3259,33 @@ static
ulint
open_or_create_log_file(
/*====================*/
- ibool create_new_db, /*!< in: TRUE if we should create a
- new database */
+ fil_space_t* space,
ibool* log_file_created, /*!< out: TRUE if new log file
created */
- ibool log_file_has_been_opened,/*!< in: TRUE if a log file has been
- opened before: then it is an error
- to try to create another log file */
ulint i) /*!< in: log file number in group */
{
- ibool ret;
- os_offset_t size;
char name[10000];
ulint dirnamelen;
- UT_NOT_USED(create_new_db);
- UT_NOT_USED(log_file_has_been_opened);
-
*log_file_created = FALSE;
- srv_normalize_path_for_win(srv_log_group_home_dir);
+ os_normalize_path(srv_log_group_home_dir);
dirnamelen = strlen(srv_log_group_home_dir);
ut_a(dirnamelen < (sizeof name) - 10 - sizeof "ib_logfile");
memcpy(name, srv_log_group_home_dir, dirnamelen);
/* Add a path separator if needed. */
- if (dirnamelen && name[dirnamelen - 1] != SRV_PATH_SEPARATOR) {
- name[dirnamelen++] = SRV_PATH_SEPARATOR;
+ if (dirnamelen && name[dirnamelen - 1] != OS_PATH_SEPARATOR) {
+ name[dirnamelen++] = OS_PATH_SEPARATOR;
}
sprintf(name + dirnamelen, "%s%lu", "ib_logfile", (ulong) i);
- files[i] = os_file_create(innodb_file_log_key, name,
- OS_FILE_OPEN, OS_FILE_NORMAL,
- OS_LOG_FILE, &ret,0);
- if (ret == FALSE) {
- fprintf(stderr, "InnoDB: Error in opening %s\n", name);
-
- return(DB_ERROR);
- }
-
- size = os_file_get_size(files[i]);
-
- if (size != srv_log_file_size * UNIV_PAGE_SIZE) {
-
- fprintf(stderr,
- "InnoDB: Error: log file %s is"
- " of different size " UINT64PF " bytes\n"
- "InnoDB: than specified in the .cnf"
- " file " UINT64PF " bytes!\n",
- name, size, srv_log_file_size * UNIV_PAGE_SIZE);
-
- return(DB_ERROR);
- }
-
- ret = os_file_close(files[i]);
- ut_a(ret);
-
- if (i == 0) {
- /* Create in memory the file space object
- which is for this log group */
-
- fil_space_create(name,
- SRV_LOG_SPACE_FIRST_ID, 0, FIL_TYPE_LOG, 0, 0);
- log_init(srv_n_log_files, srv_log_file_size * UNIV_PAGE_SIZE);
- }
-
ut_a(fil_validate());
- ut_a(fil_node_create(name, (ulint)srv_log_file_size,
- SRV_LOG_SPACE_FIRST_ID, FALSE));
+ ut_a(fil_node_create(name, srv_log_file_size >> srv_page_size_shift,
+ space, false, false));
return(DB_SUCCESS);
}
@@ -3534,20 +3298,8 @@ void
xb_normalize_init_values(void)
/*==========================*/
{
- ulint i;
-
- for (i = 0; i < srv_n_data_files; i++) {
- srv_data_file_sizes[i] = srv_data_file_sizes[i]
- * ((1024 * 1024) / UNIV_PAGE_SIZE);
- }
-
- srv_last_file_size_max = srv_last_file_size_max
- * ((1024 * 1024) / UNIV_PAGE_SIZE);
-
- srv_log_file_size = srv_log_file_size / UNIV_PAGE_SIZE;
-
- srv_log_buffer_size = srv_log_buffer_size / UNIV_PAGE_SIZE;
-
+ srv_sys_space.normalize();
+ srv_log_buffer_size /= UNIV_PAGE_SIZE;
srv_lock_table_size = 5 * (srv_buf_pool_size / UNIV_PAGE_SIZE);
}
@@ -3608,8 +3360,11 @@ end:
#endif
}
-void
-xtrabackup_backup_func(void)
+/** Implement --backup
+@return whether the operation succeeded */
+static
+bool
+xtrabackup_backup_func()
{
MY_STAT stat_info;
lsn_t latest_cp;
@@ -3627,7 +3382,7 @@ xtrabackup_backup_func(void)
if (my_setwd(mysql_real_data_home,MYF(MY_WME)))
{
msg("xtrabackup: cannot my_setwd %s\n", mysql_real_data_home);
- exit(EXIT_FAILURE);
+ return(false);
}
msg("xtrabackup: cd to %s\n", mysql_real_data_home);
@@ -3642,49 +3397,50 @@ xtrabackup_backup_func(void)
srv_n_purge_threads = 1;
srv_read_only_mode = TRUE;
- srv_backup_mode = TRUE;
- srv_close_files = (bool)xb_close_files;
+ srv_operation = SRV_OPERATION_BACKUP;
- if (srv_close_files)
+ if (xb_close_files)
msg("xtrabackup: 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())
- exit(EXIT_FAILURE);
+ if(innodb_init_param()) {
+fail:
+ innodb_shutdown();
+ return(false);
+ }
xb_normalize_init_values();
if (srv_file_flush_method_str == NULL) {
- /* These are the default options */
- srv_unix_file_flush_method = SRV_UNIX_FSYNC;
+ /* These are the default options */
+ srv_file_flush_method = SRV_FSYNC;
} else if (0 == ut_strcmp(srv_file_flush_method_str, "fsync")) {
- srv_unix_file_flush_method = SRV_UNIX_FSYNC;
+ srv_file_flush_method = SRV_FSYNC;
} else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DSYNC")) {
- srv_unix_file_flush_method = SRV_UNIX_O_DSYNC;
+ srv_file_flush_method = SRV_O_DSYNC;
} else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DIRECT")) {
- srv_unix_file_flush_method = SRV_UNIX_O_DIRECT;
+ srv_file_flush_method = SRV_O_DIRECT;
msg("xtrabackup: using O_DIRECT\n");
} else if (0 == ut_strcmp(srv_file_flush_method_str, "littlesync")) {
- srv_unix_file_flush_method = SRV_UNIX_LITTLESYNC;
-
+ srv_file_flush_method = SRV_LITTLESYNC;
} else if (0 == ut_strcmp(srv_file_flush_method_str, "nosync")) {
- srv_unix_file_flush_method = SRV_UNIX_NOSYNC;
+ srv_file_flush_method = SRV_NOSYNC;
} else if (0 == ut_strcmp(srv_file_flush_method_str, "ALL_O_DIRECT")) {
- srv_unix_file_flush_method = SRV_UNIX_ALL_O_DIRECT;
+ srv_file_flush_method = SRV_ALL_O_DIRECT_FSYNC;
msg("xtrabackup: using ALL_O_DIRECT\n");
} else if (0 == ut_strcmp(srv_file_flush_method_str,
"O_DIRECT_NO_FSYNC")) {
- srv_unix_file_flush_method = SRV_UNIX_O_DIRECT_NO_FSYNC;
+ srv_file_flush_method = SRV_O_DIRECT_NO_FSYNC;
msg("xtrabackup: using O_DIRECT_NO_FSYNC\n");
} else {
- msg("xtrabackup: Unrecognized value %s for "
+ msg("xtrabackup: Unrecognized value %s for "
"innodb_flush_method\n", srv_file_flush_method_str);
- exit(EXIT_FAILURE);
+ goto fail;
}
/* We can only use synchronous unbuffered IO on Windows for now */
@@ -3694,8 +3450,8 @@ xtrabackup_backup_func(void)
}
#ifdef _WIN32
- srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
- srv_use_native_aio = FALSE;
+ srv_file_flush_method = SRV_ALL_O_DIRECT_FSYNC;
+ srv_use_native_aio = TRUE;
#endif
if (srv_buf_pool_size >= 1000 * 1024 * 1024) {
@@ -3715,12 +3471,19 @@ xtrabackup_backup_func(void)
computers */
}
- srv_general_init();
+ sync_check_init();
+ ut_d(sync_check_enable());
+ /* Reset the system variables in the recovery module. */
+ recv_sys_var_init();
+ trx_pool_init();
+ row_mysql_init();
+
ut_crc32_init();
crc_init();
+ recv_sys_init();
#ifdef WITH_INNODB_DISALLOW_WRITES
- srv_allow_writes_event = os_event_create();
+ srv_allow_writes_event = os_event_create(0);
os_event_set(srv_allow_writes_event);
#endif
@@ -3734,18 +3497,23 @@ xtrabackup_backup_func(void)
ulint i;
xb_fil_io_init();
+ srv_n_file_io_threads = srv_n_read_io_threads;
+
+ os_aio_init(srv_n_read_io_threads, srv_n_write_io_threads,
+ SRV_MAX_N_PENDING_SYNC_IOS);
log_sys_init();
+ log_init(srv_n_log_files);
+ fil_space_t* space = fil_space_create(
+ "innodb_redo_log", SRV_LOG_SPACE_FIRST_ID, 0,
+ FIL_TYPE_LOG, NULL);
lock_sys_create(srv_lock_table_size);
for (i = 0; i < srv_n_log_files; i++) {
- err = open_or_create_log_file(FALSE, &log_file_created,
- log_opened, i);
+ err = open_or_create_log_file(space, &log_file_created, i);
if (err != DB_SUCCESS) {
-
- //return((int) err);
- exit(EXIT_FAILURE);
+ goto fail;
}
if (log_file_created) {
@@ -3762,15 +3530,14 @@ xtrabackup_backup_func(void)
"xtrabackup: Then delete the existing log files. Edit the .cnf file\n"
"xtrabackup: and start the database again.\n");
- //return(DB_ERROR);
- exit(EXIT_FAILURE);
+ goto fail;
}
}
/* log_file_created must not be TRUE, if online */
if (log_file_created) {
msg("xtrabackup: Something wrong with source files...\n");
- exit(EXIT_FAILURE);
+ goto fail;
}
}
@@ -3781,7 +3548,7 @@ xtrabackup_backup_func(void)
&& (my_mkdir(xtrabackup_extra_lsndir,0777,MYF(0)) < 0)) {
msg("xtrabackup: Error: cannot mkdir %d: %s\n",
my_errno, xtrabackup_extra_lsndir);
- exit(EXIT_FAILURE);
+ goto fail;
}
/* create target dir if not exist */
@@ -3789,12 +3556,10 @@ xtrabackup_backup_func(void)
&& (my_mkdir(xtrabackup_target_dir,0777,MYF(0)) < 0)){
msg("xtrabackup: Error: cannot mkdir %d: %s\n",
my_errno, xtrabackup_target_dir);
- exit(EXIT_FAILURE);
+ goto fail;
}
{
- fil_system_t* f_system = fil_system;
-
/* definition from recv_recovery_from_checkpoint_start() */
ulint max_cp_field;
@@ -3810,14 +3575,17 @@ xtrabackup_backup_func(void)
dberr_t err = recv_find_max_checkpoint(&max_cp_field);
if (err != DB_SUCCESS) {
- exit(EXIT_FAILURE);
+log_fail:
+ log_mutex_exit();
+ goto fail;
}
if (log_sys->log.format == 0) {
old_format:
msg("xtrabackup: Error: cannot process redo log"
" before MariaDB 10.2.2\n");
- exit(EXIT_FAILURE);
+ log_mutex_exit();
+ goto log_fail;
}
ut_ad(!((log_sys->log.format ^ LOG_HEADER_FORMAT_CURRENT)
@@ -3832,7 +3600,7 @@ reread_log_header:
err = recv_find_max_checkpoint(&max_cp_field);
if (err != DB_SUCCESS) {
- exit(EXIT_FAILURE);
+ goto log_fail;
}
if (log_sys->log.format == 0) {
@@ -3842,7 +3610,7 @@ reread_log_header:
ut_ad(!((log_sys->log.format ^ LOG_HEADER_FORMAT_CURRENT)
& ~LOG_HEADER_FORMAT_ENCRYPTED));
- if(checkpoint_no_start != mach_read_from_8(buf + LOG_CHECKPOINT_NO)) {
+ if (checkpoint_no_start != mach_read_from_8(buf + LOG_CHECKPOINT_NO)) {
checkpoint_lsn_start = mach_read_from_8(buf + LOG_CHECKPOINT_LSN);
checkpoint_no_start = mach_read_from_8(buf + LOG_CHECKPOINT_NO);
@@ -3854,34 +3622,50 @@ reread_log_header:
xtrabackup_init_datasinks();
if (!select_history()) {
- exit(EXIT_FAILURE);
+ goto fail;
}
/* open the log file */
memset(&stat_info, 0, sizeof(MY_STAT));
- dst_log_file = ds_open(ds_redo, XB_LOG_FILENAME, &stat_info);
+ dst_log_file = ds_open(ds_redo, "ib_logfile0", &stat_info);
if (dst_log_file == NULL) {
msg("xtrabackup: error: failed to open the target stream for "
- "'%s'.\n", XB_LOG_FILENAME);
- ut_free(log_hdr_buf_);
- exit(EXIT_FAILURE);
+ "'ib_logfile0'.\n");
+ goto fail;
}
/* label it */
- strcpy((char*) log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
- "xtrabkup ");
- ut_sprintf_timestamp(
- (char*) log_hdr_buf + (LOG_FILE_WAS_CREATED_BY_HOT_BACKUP
- + (sizeof "xtrabkup ") - 1));
-
- if (ds_write(dst_log_file, log_hdr_buf, LOG_FILE_HDR_SIZE)) {
+ byte MY_ALIGNED(OS_FILE_LOG_BLOCK_SIZE) log_hdr[OS_FILE_LOG_BLOCK_SIZE];
+ memset(log_hdr, 0, sizeof log_hdr);
+ mach_write_to_4(LOG_HEADER_FORMAT + log_hdr, log_sys->log.format);
+ mach_write_to_8(LOG_HEADER_START_LSN + log_hdr, checkpoint_lsn_start);
+ strcpy(reinterpret_cast<char*>(LOG_HEADER_CREATOR + log_hdr),
+ "Backup " MYSQL_SERVER_VERSION);
+ log_block_set_checksum(log_hdr,
+ log_block_calc_checksum_crc32(log_hdr));
+
+ /* Write the log header. */
+ if (ds_write(dst_log_file, log_hdr, sizeof log_hdr)) {
+ log_write_fail:
msg("xtrabackup: error: write to logfile failed\n");
- ut_free(log_hdr_buf_);
- exit(EXIT_FAILURE);
+ goto fail;
+ }
+ /* Adjust the checkpoint page. */
+ memcpy(log_hdr, buf, OS_FILE_LOG_BLOCK_SIZE);
+ mach_write_to_8(log_hdr + LOG_CHECKPOINT_OFFSET,
+ (checkpoint_lsn_start & (OS_FILE_LOG_BLOCK_SIZE - 1))
+ | LOG_FILE_HDR_SIZE);
+ log_block_set_checksum(log_hdr,
+ log_block_calc_checksum_crc32(log_hdr));
+ /* Write checkpoint page 1 and two empty log pages before the
+ payload. */
+ if (ds_write(dst_log_file, log_hdr, OS_FILE_LOG_BLOCK_SIZE)
+ || !memset(log_hdr, 0, sizeof log_hdr)
+ || ds_write(dst_log_file, log_hdr, sizeof log_hdr)
+ || ds_write(dst_log_file, log_hdr, sizeof log_hdr)) {
+ goto log_write_fail;
}
- ut_free(log_hdr_buf_);
-
/* start flag */
log_copying = TRUE;
@@ -3890,18 +3674,20 @@ reread_log_header:
os_thread_id_t io_watching_thread_id;
io_ticket = xtrabackup_throttle;
- wait_throttle = os_event_create();
+ wait_throttle = os_event_create(0);
+ io_watching_thread_running = true;
os_thread_create(io_watching_thread, NULL,
&io_watching_thread_id);
}
/* copy log file by current position */
- if(xtrabackup_copy_logfile(checkpoint_lsn_start, FALSE))
- exit(EXIT_FAILURE);
+ log_copy_scanned_lsn = checkpoint_lsn_start;
+ if (xtrabackup_copy_logfile(false))
+ goto fail;
-
- log_copying_stop = os_event_create();
+ log_copying_stop = os_event_create(0);
+ log_copying_running = true;
os_thread_create(log_copying_thread, NULL, &log_copying_thread_id);
/* Populate fil_system with tablespaces to copy */
@@ -3909,12 +3695,12 @@ reread_log_header:
if (err != DB_SUCCESS) {
msg("xtrabackup: error: xb_load_tablespaces() failed with"
"error code %u\n", err);
- exit(EXIT_FAILURE);
+ goto fail;
}
/* FLUSH CHANGED_PAGE_BITMAPS call */
if (!flush_changed_page_bitmaps()) {
- exit(EXIT_FAILURE);
+ goto fail;
}
debug_sync_point("xtrabackup_suspend_at_start");
@@ -3939,17 +3725,17 @@ reread_log_header:
"files transfer\n", xtrabackup_parallel);
}
- it = datafiles_iter_new(f_system);
+ it = datafiles_iter_new(fil_system);
if (it == NULL) {
msg("xtrabackup: Error: datafiles_iter_new() failed.\n");
- exit(EXIT_FAILURE);
+ goto fail;
}
/* Create data copying threads */
data_threads = (data_thread_ctxt_t *)
- ut_malloc(sizeof(data_thread_ctxt_t) * xtrabackup_parallel);
+ malloc(sizeof(data_thread_ctxt_t) * xtrabackup_parallel);
count = xtrabackup_parallel;
- count_mutex = os_mutex_create();
+ pthread_mutex_init(&count_mutex, NULL);
for (i = 0; i < (uint) xtrabackup_parallel; i++) {
data_threads[i].it = it;
@@ -3963,16 +3749,16 @@ reread_log_header:
/* Wait for threads to exit */
while (1) {
os_thread_sleep(1000000);
- os_mutex_enter(count_mutex);
- if (count == 0) {
- os_mutex_exit(count_mutex);
+ pthread_mutex_lock(&count_mutex);
+ bool stop = count == 0;
+ pthread_mutex_unlock(&count_mutex);
+ if (stop) {
break;
}
- os_mutex_exit(count_mutex);
}
- os_mutex_free(count_mutex);
- ut_free(data_threads);
+ pthread_mutex_destroy(&count_mutex);
+ free(data_threads);
datafiles_iter_free(it);
if (changed_page_bitmap) {
@@ -3981,7 +3767,7 @@ reread_log_header:
}
if (!backup_start()) {
- exit(EXIT_FAILURE);
+ goto fail;
}
/* read the latest checkpoint lsn */
@@ -4013,11 +3799,19 @@ reread_log_header:
}
msg("\n");
- os_event_free(log_copying_stop);
+ os_event_destroy(log_copying_stop);
+
+ if (!dst_log_file || xtrabackup_copy_logfile(true)) {
+ goto fail;
+ }
+
if (ds_close(dst_log_file)) {
- exit(EXIT_FAILURE);
+ dst_log_file = NULL;
+ goto fail;
}
+ dst_log_file = NULL;
+
if(!xtrabackup_incremental) {
strcpy(metadata_type, "full-backuped");
metadata_from_lsn = 0;
@@ -4030,7 +3824,7 @@ reread_log_header:
if (!xtrabackup_stream_metadata(ds_meta)) {
msg("xtrabackup: Error: failed to stream metadata.\n");
- exit(EXIT_FAILURE);
+ goto fail;
}
if (xtrabackup_extra_lsndir) {
char filename[FN_REFLEN];
@@ -4040,13 +3834,13 @@ reread_log_header:
if (!xtrabackup_write_metadata(filename)) {
msg("xtrabackup: Error: failed to write metadata "
"to '%s'.\n", filename);
- exit(EXIT_FAILURE);
+ goto fail;
}
}
if (!backup_finish()) {
- exit(EXIT_FAILURE);
+ goto fail;
}
xtrabackup_destroy_datasinks();
@@ -4056,319 +3850,29 @@ reread_log_header:
while (io_watching_thread_running) {
os_thread_sleep(1000000);
}
- os_event_free(wait_throttle);
- wait_throttle = NULL;
+ os_event_destroy(wait_throttle);
}
- msg("xtrabackup: Transaction log of lsn (" LSN_PF ") to (" LSN_PF
+ msg("xtrabackup: Redo log (from LSN " LSN_PF " to " LSN_PF
") was copied.\n", checkpoint_lsn_start, log_copy_scanned_lsn);
xb_filters_free();
xb_data_files_close();
- /* Make sure that the latest checkpoint made it to xtrabackup_logfile */
+ /* Make sure that the latest checkpoint was included */
if (latest_cp > log_copy_scanned_lsn) {
msg("xtrabackup: error: last checkpoint LSN (" LSN_PF
") is larger than last copied LSN (" LSN_PF ").\n",
latest_cp, log_copy_scanned_lsn);
- exit(EXIT_FAILURE);
+ goto fail;
}
+
+ innodb_shutdown();
+ return(true);
}
/* ================= prepare ================= */
-static my_bool
-xtrabackup_init_temp_log(void)
-{
- pfs_os_file_t src_file;
- char src_path[FN_REFLEN];
- char dst_path[FN_REFLEN];
- ibool success;
-
- ulint field;
- byte* log_buf= (byte *)malloc(UNIV_PAGE_SIZE_MAX * 128); /* 2 MB */
-
- ib_int64_t file_size;
-
- lsn_t max_no;
- lsn_t max_lsn;
- lsn_t checkpoint_no;
-
- ulint fold;
-
- bool checkpoint_found;
-
- max_no = 0;
-
- if (!log_buf) {
- goto error;
- }
-
- if (!xb_init_log_block_size()) {
- goto error;
- }
-
- if(!xtrabackup_incremental_dir) {
- sprintf(dst_path, "%s/ib_logfile0", xtrabackup_target_dir);
- sprintf(src_path, "%s/%s", xtrabackup_target_dir,
- XB_LOG_FILENAME);
- } else {
- sprintf(dst_path, "%s/ib_logfile0", xtrabackup_incremental_dir);
- sprintf(src_path, "%s/%s", xtrabackup_incremental_dir,
- XB_LOG_FILENAME);
- }
-
- srv_normalize_path_for_win(dst_path);
- srv_normalize_path_for_win(src_path);
-retry:
- src_file = os_file_create_simple_no_error_handling(0, src_path,
- OS_FILE_OPEN,
- OS_FILE_READ_WRITE,
- &success,0);
- if (!success) {
- /* The following call prints an error message */
- os_file_get_last_error(TRUE);
-
- msg("xtrabackup: Warning: cannot open %s. will try to find.\n",
- src_path);
-
- /* check if ib_logfile0 may be xtrabackup_logfile */
- src_file = os_file_create_simple_no_error_handling(0, dst_path,
- OS_FILE_OPEN,
- OS_FILE_READ_WRITE,
- &success,0);
- if (!success) {
- os_file_get_last_error(TRUE);
- msg(" xtrabackup: Fatal error: cannot find %s.\n",
- src_path);
-
- goto error;
- }
-
- success = os_file_read(src_file, log_buf, 0,
- LOG_FILE_HDR_SIZE);
- if (!success) {
- goto error;
- }
-
- if ( ut_memcmp(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
- (byte*)"xtrabkup", (sizeof "xtrabkup") - 1) == 0) {
- msg(" xtrabackup: 'ib_logfile0' seems to be "
- "'xtrabackup_logfile'. will retry.\n");
-
- os_file_close(src_file);
- src_file = XB_FILE_UNDEFINED;
-
- /* rename and try again */
- success = os_file_rename(0, dst_path, src_path);
- if (!success) {
- goto error;
- }
-
- goto retry;
- }
-
- msg(" xtrabackup: Fatal error: cannot find %s.\n",
- src_path);
-
- os_file_close(src_file);
- src_file = XB_FILE_UNDEFINED;
-
- goto error;
- }
-
- file_size = os_file_get_size(src_file);
-
-
- /* TODO: We should skip the following modifies, if it is not the first time. */
-
- /* read log file header */
- success = os_file_read(src_file, log_buf, 0, LOG_FILE_HDR_SIZE);
- if (!success) {
- goto error;
- }
-
- if ( ut_memcmp(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
- (byte*)"xtrabkup", (sizeof "xtrabkup") - 1) != 0 ) {
- msg("xtrabackup: notice: xtrabackup_logfile was already used "
- "to '--prepare'.\n");
- goto skip_modify;
- } else {
- /* clear it later */
- //memset(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
- // ' ', 4);
- }
-
- checkpoint_found = false;
-
- /* read last checkpoint lsn */
- for (field = LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2;
- field += LOG_CHECKPOINT_2 - LOG_CHECKPOINT_1) {
- if (!recv_check_cp_is_consistent(const_cast<const byte *>
- (log_buf + field)))
- goto not_consistent;
-
- checkpoint_no = mach_read_from_8(log_buf + field +
- LOG_CHECKPOINT_NO);
-
- if (checkpoint_no >= max_no) {
-
- max_no = checkpoint_no;
- max_lsn = mach_read_from_8(log_buf + field +
- LOG_CHECKPOINT_LSN);
- checkpoint_found = true;
- }
-not_consistent:
- ;
- }
-
- if (!checkpoint_found) {
- msg("xtrabackup: No valid checkpoint found.\n");
- goto error;
- }
-
-
- /* It seems to be needed to overwrite the both checkpoint area. */
- mach_write_to_8(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_LSN,
- max_lsn);
- mach_write_to_4(log_buf + LOG_CHECKPOINT_1
- + LOG_CHECKPOINT_OFFSET_LOW32,
- LOG_FILE_HDR_SIZE +
- (ulint)(max_lsn -
- ut_uint64_align_down(max_lsn,
- OS_FILE_LOG_BLOCK_SIZE)));
- mach_write_to_4(log_buf + LOG_CHECKPOINT_1
- + LOG_CHECKPOINT_OFFSET_HIGH32, 0);
- fold = ut_fold_binary(log_buf + LOG_CHECKPOINT_1, LOG_CHECKPOINT_CHECKSUM_1);
- mach_write_to_4(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_CHECKSUM_1, fold);
-
- fold = ut_fold_binary(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_LSN,
- LOG_CHECKPOINT_CHECKSUM_2 - LOG_CHECKPOINT_LSN);
- mach_write_to_4(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_CHECKSUM_2, fold);
-
- mach_write_to_8(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_LSN,
- max_lsn);
- mach_write_to_4(log_buf + LOG_CHECKPOINT_2
- + LOG_CHECKPOINT_OFFSET_LOW32,
- LOG_FILE_HDR_SIZE +
- (ulint)(max_lsn -
- ut_uint64_align_down(max_lsn,
- OS_FILE_LOG_BLOCK_SIZE)));
- mach_write_to_4(log_buf + LOG_CHECKPOINT_2
- + LOG_CHECKPOINT_OFFSET_HIGH32, 0);
- fold = ut_fold_binary(log_buf + LOG_CHECKPOINT_2, LOG_CHECKPOINT_CHECKSUM_1);
- mach_write_to_4(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_CHECKSUM_1, fold);
-
- fold = ut_fold_binary(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_LSN,
- LOG_CHECKPOINT_CHECKSUM_2 - LOG_CHECKPOINT_LSN);
- mach_write_to_4(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_CHECKSUM_2, fold);
-
-
- success = os_file_write(src_path, src_file, log_buf, 0,
- LOG_FILE_HDR_SIZE);
- if (!success) {
- goto error;
- }
-
- /* expand file size (9/8) and align to UNIV_PAGE_SIZE_MAX */
-
- if (file_size % UNIV_PAGE_SIZE_MAX) {
- memset(log_buf, 0, UNIV_PAGE_SIZE_MAX);
- success = os_file_write(src_path, src_file, log_buf,
- file_size,
- UNIV_PAGE_SIZE_MAX
- - (ulint) (file_size
- % UNIV_PAGE_SIZE_MAX));
- if (!success) {
- goto error;
- }
-
- file_size = os_file_get_size(src_file);
- }
-
- /* TODO: We should judge whether the file is already expanded or not... */
- {
- ulint expand;
-
- memset(log_buf, 0, UNIV_PAGE_SIZE_MAX * 128);
- expand = (ulint) (file_size / UNIV_PAGE_SIZE_MAX / 8);
-
- for (; expand > 128; expand -= 128) {
- success = os_file_write(src_path, src_file, log_buf,
- file_size,
- UNIV_PAGE_SIZE_MAX * 128);
- if (!success) {
- goto error;
- }
- file_size += UNIV_PAGE_SIZE_MAX * 128;
- }
-
- if (expand) {
- success = os_file_write(src_path, src_file, log_buf,
- file_size,
- expand * UNIV_PAGE_SIZE_MAX);
- if (!success) {
- goto error;
- }
- file_size += UNIV_PAGE_SIZE_MAX * expand;
- }
- }
-
- /* make larger than 2MB */
- if (file_size < 2*1024*1024L) {
- memset(log_buf, 0, UNIV_PAGE_SIZE_MAX);
- while (file_size < 2*1024*1024L) {
- success = os_file_write(src_path, src_file, log_buf,
- file_size,
- UNIV_PAGE_SIZE_MAX);
- if (!success) {
- goto error;
- }
- file_size += UNIV_PAGE_SIZE_MAX;
- }
- file_size = os_file_get_size(src_file);
- }
-
- msg("xtrabackup: xtrabackup_logfile detected: size=" INT64PF ", "
- "start_lsn=(" LSN_PF ")\n", file_size, max_lsn);
-
- os_file_close(src_file);
- src_file = XB_FILE_UNDEFINED;
-
- /* fake InnoDB */
- innobase_log_files_in_group_save = innobase_log_files_in_group;
- srv_log_group_home_dir_save = srv_log_group_home_dir;
- innobase_log_file_size_save = innobase_log_file_size;
-
- srv_log_group_home_dir = NULL;
- innobase_log_file_size = file_size;
- innobase_log_files_in_group = 1;
-
- srv_thread_concurrency = 0;
-
- /* rename 'xtrabackup_logfile' to 'ib_logfile0' */
- success = os_file_rename(0, src_path, dst_path);
- if (!success) {
- goto error;
- }
- xtrabackup_logfile_is_renamed = TRUE;
- free(log_buf);
- return(FALSE);
-
-skip_modify:
- free(log_buf);
- os_file_close(src_file);
- src_file = XB_FILE_UNDEFINED;
- return(FALSE);
-
-error:
- free(log_buf);
- if (src_file != XB_FILE_UNDEFINED)
- os_file_close(src_file);
- msg("xtrabackup: Error: xtrabackup_init_temp_log() failed.\n");
- return(TRUE); /*ERROR*/
-}
-
/***********************************************************************
Generates path to the meta file path from a given path to an incremental .delta
by replacing trailing ".delta" with ".meta", or returns error if 'delta_path'
@@ -4398,31 +3902,30 @@ file. Code adopted from fil_create_new_single_table_tablespace with
the main difference that only disk file is created without updating
the InnoDB in-memory dictionary data structures.
-@return TRUE on success, FALSE on error. */
+@return true on success, false on error. */
static
-ibool
+bool
xb_space_create_file(
/*==================*/
const char* path, /*!<in: path to tablespace */
ulint space_id, /*!<in: space id */
- ulint flags __attribute__((unused)),/*!<in: tablespace
- flags */
+ ulint flags, /*!<in: tablespace flags */
pfs_os_file_t* file) /*!<out: file handle */
{
- ibool ret;
+ bool ret;
byte* buf;
byte* page;
- *file = os_file_create_simple_no_error_handling(0, path, OS_FILE_CREATE,
- OS_FILE_READ_WRITE,
- &ret,0);
+ *file = os_file_create_simple_no_error_handling(
+ 0, path, OS_FILE_CREATE, OS_FILE_READ_WRITE, false, &ret);
if (!ret) {
msg("xtrabackup: cannot create file %s\n", path);
return ret;
}
ret = os_file_set_size(path, *file,
- FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE);
+ FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE,
+ false);
if (!ret) {
msg("xtrabackup: cannot set size for file %s\n", path);
os_file_close(*file);
@@ -4430,7 +3933,7 @@ xb_space_create_file(
return ret;
}
- buf = static_cast<byte *>(ut_malloc(3 * UNIV_PAGE_SIZE));
+ buf = static_cast<byte *>(malloc(3 * UNIV_PAGE_SIZE));
/* Align the memory for file i/o if we might have O_DIRECT set */
page = static_cast<byte *>(ut_align(buf, UNIV_PAGE_SIZE));
@@ -4439,19 +3942,19 @@ xb_space_create_file(
fsp_header_init_fields(page, space_id, flags);
mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, space_id);
- if (!fsp_flags_is_compressed(flags)) {
- buf_flush_init_for_writing(page, NULL, 0);
+ const page_size_t page_size(flags);
- ret = os_file_write(path, *file, page, 0, UNIV_PAGE_SIZE);
- }
- else {
- page_zip_des_t page_zip;
- ulint zip_size;
+ if (!page_size.is_compressed()) {
+ buf_flush_init_for_writing(NULL, page, NULL, 0, false);
- zip_size = fsp_flags_get_zip_size(flags);
+ ret = os_file_write(IORequestWrite, path, *file, page, 0,
+ UNIV_PAGE_SIZE);
+ } else {
+ page_zip_des_t page_zip;
+ ulint zip_size = page_size.physical();
page_zip_set_size(&page_zip, zip_size);
page_zip.data = page + UNIV_PAGE_SIZE;
- fprintf(stderr, "zip_size = %lu\n", zip_size);
+ fprintf(stderr, "zip_size = " ULINTPF "\n", zip_size);
#ifdef UNIV_DEBUG
page_zip.m_start =
@@ -4459,13 +3962,13 @@ xb_space_create_file(
page_zip.m_end = page_zip.m_nonempty =
page_zip.n_blobs = 0;
- buf_flush_init_for_writing(page, &page_zip, 0);
+ buf_flush_init_for_writing(NULL, page, &page_zip, 0, false);
- ret = os_file_write(path, *file, page_zip.data, 0,
- zip_size);
+ ret = os_file_write(IORequestWrite, path, *file,
+ page_zip.data, 0, zip_size);
}
- ut_free(buf);
+ free(buf);
if (!ret) {
msg("xtrabackup: could not write the first page to %s\n",
@@ -4490,35 +3993,32 @@ pfs_os_file_t
xb_delta_open_matching_space(
const char* dbname, /* in: path to destination database dir */
const char* name, /* in: name of delta file (without .delta) */
- ulint space_id, /* in: space id of delta file */
- ulint zip_size, /* in: zip_size of tablespace */
+ const xb_delta_info_t& info,
char* real_name, /* out: full path of destination file */
size_t real_name_len, /* out: buffer size for real_name */
- ibool* success) /* out: indicates error. TRUE = success */
+ bool* success) /* out: indicates error. true = success */
{
char dest_dir[FN_REFLEN];
char dest_space_name[FN_REFLEN];
- ibool ok;
fil_space_t* fil_space;
pfs_os_file_t file;
- ulint tablespace_flags;
xb_filter_entry_t* table;
ut_a(dbname != NULL ||
- !fil_is_user_tablespace_id(space_id) ||
- space_id == ULINT_UNDEFINED);
+ !fil_is_user_tablespace_id(info.space_id) ||
+ info.space_id == ULINT_UNDEFINED);
- *success = FALSE;
+ *success = false;
if (dbname) {
snprintf(dest_dir, FN_REFLEN, "%s/%s",
xtrabackup_target_dir, dbname);
- srv_normalize_path_for_win(dest_dir);
+ os_normalize_path(dest_dir);
snprintf(dest_space_name, FN_REFLEN, "%s/%s", dbname, name);
} else {
snprintf(dest_dir, FN_REFLEN, "%s", xtrabackup_target_dir);
- srv_normalize_path_for_win(dest_dir);
+ os_normalize_path(dest_dir);
snprintf(dest_space_name, FN_REFLEN, "%s", name);
}
@@ -4526,7 +4026,7 @@ xb_delta_open_matching_space(
snprintf(real_name, real_name_len,
"%s/%s",
xtrabackup_target_dir, dest_space_name);
- srv_normalize_path_for_win(real_name);
+ os_normalize_path(real_name);
/* Truncate ".ibd" */
dest_space_name[strlen(dest_space_name) - 4] = '\0';
@@ -4536,13 +4036,26 @@ xb_delta_open_matching_space(
return file;
}
- if (!fil_is_user_tablespace_id(space_id)) {
- goto found;
+ log_mutex_enter();
+ if (!fil_is_user_tablespace_id(info.space_id)) {
+found:
+ /* open the file and return its handle */
+
+ file = os_file_create_simple_no_error_handling(
+ 0, real_name,
+ OS_FILE_OPEN, OS_FILE_READ_WRITE, false, success);
+
+ if (!*success) {
+ msg("xtrabackup: Cannot open file %s\n", real_name);
+ }
+exit:
+ log_mutex_exit();
+ return file;
}
/* remember space name for further reference */
table = static_cast<xb_filter_entry_t *>
- (ut_malloc(sizeof(xb_filter_entry_t) +
+ (malloc(sizeof(xb_filter_entry_t) +
strlen(dest_space_name) + 1));
table->name = ((char*)table) + sizeof(xb_filter_entry_t);
@@ -4555,7 +4068,8 @@ xb_delta_open_matching_space(
mutex_exit(&fil_system->mutex);
if (fil_space != NULL) {
- if (fil_space->id == space_id || space_id == ULINT_UNDEFINED) {
+ if (fil_space->id == info.space_id
+ || info.space_id == ULINT_UNDEFINED) {
/* we found matching space */
goto found;
} else {
@@ -4568,8 +4082,10 @@ xb_delta_open_matching_space(
msg("xtrabackup: Renaming %s to %s.ibd\n",
fil_space->name, tmpname);
- if (!fil_rename_tablespace(NULL, fil_space->id,
- tmpname, NULL))
+ if (!fil_rename_tablespace(
+ fil_space->id,
+ fil_space->chain.start->name,
+ tmpname, NULL))
{
msg("xtrabackup: Cannot rename %s to %s\n",
fil_space->name, tmpname);
@@ -4578,14 +4094,14 @@ xb_delta_open_matching_space(
}
}
- if (space_id == ULINT_UNDEFINED)
+ if (info.space_id == ULINT_UNDEFINED)
{
msg("xtrabackup: Error: Cannot 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(space_id);
+ fil_space = fil_space_get_by_id(info.space_id);
mutex_exit(&fil_system->mutex);
if (fil_space != NULL) {
char tmpname[FN_REFLEN];
@@ -4595,7 +4111,9 @@ xb_delta_open_matching_space(
msg("xtrabackup: Renaming %s to %s\n",
fil_space->name, dest_space_name);
- if (!fil_rename_tablespace(NULL, fil_space->id, tmpname,
+ if (!fil_rename_tablespace(fil_space->id,
+ fil_space->chain.start->name,
+ tmpname,
NULL))
{
msg("xtrabackup: Cannot rename %s to %s\n",
@@ -4607,49 +4125,30 @@ xb_delta_open_matching_space(
}
/* No matching space found. create the new one. */
-
- if (!fil_space_create(dest_space_name, space_id, 0,
- FIL_TABLESPACE, 0, false)) {
+ const ulint flags = info.page_size.is_compressed()
+ ? get_bit_shift(info.page_size.physical()
+ >> (UNIV_ZIP_SIZE_SHIFT_MIN - 1))
+ << FSP_FLAGS_POS_ZIP_SSIZE
+ | FSP_FLAGS_MASK_POST_ANTELOPE
+ | FSP_FLAGS_MASK_ATOMIC_BLOBS
+ | (info.page_size.logical() == UNIV_PAGE_SIZE_ORIG
+ ? 0
+ : get_bit_shift(info.page_size.logical()
+ >> (UNIV_ZIP_SIZE_SHIFT_MIN - 1))
+ << FSP_FLAGS_POS_PAGE_SSIZE)
+ : FSP_FLAGS_PAGE_SSIZE();
+ ut_ad(page_size_t(flags).equals_to(info.page_size));
+
+ if (fil_space_create(dest_space_name, info.space_id, flags,
+ FIL_TYPE_TABLESPACE, 0)) {
+ *success = xb_space_create_file(real_name, info.space_id,
+ flags, &file);
+ } else {
msg("xtrabackup: Cannot create tablespace %s\n",
- dest_space_name);
- goto exit;
+ dest_space_name);
}
- /* Calculate correct tablespace flags for compressed tablespaces. */
- if (!zip_size || zip_size == ULINT_UNDEFINED) {
- tablespace_flags = 0;
- }
- else {
- tablespace_flags
- = (get_bit_shift(zip_size >> PAGE_ZIP_MIN_SIZE_SHIFT
- << 1)
- << DICT_TF_ZSSIZE_SHIFT)
- | DICT_TF_COMPACT
- | (DICT_TF_FORMAT_ZIP << DICT_TF_FORMAT_SHIFT);
- ut_a(dict_tf_get_zip_size(tablespace_flags)
- == zip_size);
- }
- *success = xb_space_create_file(real_name, space_id, tablespace_flags,
- &file);
goto exit;
-
-found:
- /* open the file and return it's handle */
-
- file = os_file_create_simple_no_error_handling(0, real_name,
- OS_FILE_OPEN,
- OS_FILE_READ_WRITE,
- &ok,0);
-
- if (ok) {
- *success = TRUE;
- } else {
- msg("xtrabackup: Cannot open file %s\n", real_name);
- }
-
-exit:
-
- return file;
}
/************************************************************************
@@ -4670,13 +4169,13 @@ xtrabackup_apply_delta(
char dst_path[FN_REFLEN];
char meta_path[FN_REFLEN];
char space_name[FN_REFLEN];
- ibool success;
+ bool success;
ibool last_buffer = FALSE;
ulint page_in_buffer;
ulint incremental_buffers = 0;
- xb_delta_info_t info;
+ xb_delta_info_t info(univ_page_size, SRV_TMP_SPACE_ID);
ulint page_size;
ulint page_size_shift;
byte* incremental_buffer_base = NULL;
@@ -4706,15 +4205,15 @@ xtrabackup_apply_delta(
goto error;
}
- srv_normalize_path_for_win(dst_path);
- srv_normalize_path_for_win(src_path);
- srv_normalize_path_for_win(meta_path);
+ os_normalize_path(dst_path);
+ os_normalize_path(src_path);
+ os_normalize_path(meta_path);
if (!xb_read_delta_metadata(meta_path, &info)) {
goto error;
}
- page_size = info.page_size;
+ page_size = info.page_size.physical();
page_size_shift = get_bit_shift(page_size);
msg("xtrabackup: page size for %s is %lu bytes\n",
src_path, page_size);
@@ -4725,10 +4224,9 @@ xtrabackup_apply_delta(
goto error;
}
- src_file = os_file_create_simple_no_error_handling(0, src_path,
- OS_FILE_OPEN,
- OS_FILE_READ_WRITE,
- &success,0);
+ src_file = os_file_create_simple_no_error_handling(
+ 0, src_path,
+ OS_FILE_OPEN, OS_FILE_READ_WRITE, false, &success);
if (!success) {
os_file_get_last_error(TRUE);
msg("xtrabackup: error: cannot open %s\n", src_path);
@@ -4740,7 +4238,7 @@ xtrabackup_apply_delta(
os_file_set_nocache(src_file, src_path, "OPEN");
dst_file = xb_delta_open_matching_space(
- dbname, space_name, info.space_id, info.zip_size,
+ dbname, space_name, info,
dst_path, sizeof(dst_path), &success);
if (!success) {
msg("xtrabackup: error: cannot open %s\n", dst_path);
@@ -4753,8 +4251,7 @@ xtrabackup_apply_delta(
/* allocate buffer for incremental backup (4096 pages) */
incremental_buffer_base = static_cast<byte *>
- (ut_malloc((page_size / 4 + 1) *
- page_size));
+ (malloc((page_size / 4 + 1) * page_size));
incremental_buffer = static_cast<byte *>
(ut_align(incremental_buffer_base,
page_size));
@@ -4768,8 +4265,8 @@ xtrabackup_apply_delta(
/* first block of block cluster */
offset = ((incremental_buffers * (page_size / 4))
<< page_size_shift);
- success = os_file_read(src_file, incremental_buffer,
- offset, page_size);
+ success = os_file_read(IORequestRead, src_file,
+ incremental_buffer, offset, page_size);
if (!success) {
goto error;
}
@@ -4787,6 +4284,9 @@ xtrabackup_apply_delta(
goto error;
}
+ /* FIXME: If the .delta modifies FSP_SIZE on page 0,
+ extend the file to that size. */
+
for (page_in_buffer = 1; page_in_buffer < page_size / 4;
page_in_buffer++) {
if (mach_read_from_4(incremental_buffer + page_in_buffer * 4)
@@ -4797,8 +4297,9 @@ xtrabackup_apply_delta(
ut_a(last_buffer || page_in_buffer == page_size / 4);
/* read whole of the cluster */
- success = os_file_read(src_file, incremental_buffer,
- offset, page_in_buffer * page_size);
+ success = os_file_read(IORequestRead, src_file,
+ incremental_buffer,
+ offset, page_in_buffer * page_size);
if (!success) {
goto error;
}
@@ -4815,7 +4316,8 @@ xtrabackup_apply_delta(
if (offset_on_page == 0xFFFFFFFFUL)
break;
- success = os_file_write(dst_path, dst_file,
+ success = os_file_write(IORequestWrite,
+ dst_path, dst_file,
incremental_buffer +
page_in_buffer * page_size,
(offset_on_page <<
@@ -4829,20 +4331,18 @@ xtrabackup_apply_delta(
incremental_buffers++;
}
- if (incremental_buffer_base)
- ut_free(incremental_buffer_base);
- if (src_file != XB_FILE_UNDEFINED)
+ free(incremental_buffer_base);
+ if (src_file != OS_FILE_CLOSED)
os_file_close(src_file);
- if (dst_file != XB_FILE_UNDEFINED)
+ if (dst_file != OS_FILE_CLOSED)
os_file_close(dst_file);
return TRUE;
error:
- if (incremental_buffer_base)
- ut_free(incremental_buffer_base);
- if (src_file != XB_FILE_UNDEFINED)
+ free(incremental_buffer_base);
+ if (src_file != OS_FILE_CLOSED)
os_file_close(src_file);
- if (dst_file != XB_FILE_UNDEFINED)
+ if (dst_file != OS_FILE_CLOSED)
os_file_close(dst_file);
msg("xtrabackup: Error: xtrabackup_apply_delta(): "
"failed to apply %s to %s.\n", src_path, dst_path);
@@ -4903,9 +4403,7 @@ xb_process_datadir(
const char* path, /*!<in: datadir path */
const char* suffix, /*!<in: suffix to match
against */
- handle_datadir_entry_func_t func, /*!<in: callback */
- void* data) /*!<in: additional argument for
- callback */
+ handle_datadir_entry_func_t func) /*!<in: callback */
{
ulint ret;
char dbpath[FN_REFLEN];
@@ -4940,7 +4438,7 @@ xb_process_datadir(
suffix)) {
if (!func(
path, NULL,
- fileinfo.name, data))
+ fileinfo.name, NULL))
{
return(FALSE);
}
@@ -4976,7 +4474,7 @@ next_file_item_1:
sprintf(dbpath, "%s/%s", path,
dbinfo.name);
- srv_normalize_path_for_win(dbpath);
+ os_normalize_path(dbpath);
dbdir = os_file_opendir(dbpath, FALSE);
@@ -5001,7 +4499,7 @@ next_file_item_1:
if (!func(
path,
dbinfo.name,
- fileinfo.name, data))
+ fileinfo.name, NULL))
{
return(FALSE);
}
@@ -5033,82 +4531,9 @@ ibool
xtrabackup_apply_deltas()
{
return xb_process_datadir(xtrabackup_incremental_dir, ".delta",
- xtrabackup_apply_delta, NULL);
-}
-
-static my_bool
-xtrabackup_close_temp_log(my_bool clear_flag)
-{
- pfs_os_file_t src_file;
- char src_path[FN_REFLEN];
- char dst_path[FN_REFLEN];
- ibool success;
- byte log_buf[UNIV_PAGE_SIZE_MAX];
-
- if (!xtrabackup_logfile_is_renamed)
- return(FALSE);
-
- /* rename 'ib_logfile0' to 'xtrabackup_logfile' */
- if(!xtrabackup_incremental_dir) {
- sprintf(dst_path, "%s/ib_logfile0", xtrabackup_target_dir);
- sprintf(src_path, "%s/%s", xtrabackup_target_dir,
- XB_LOG_FILENAME);
- } else {
- sprintf(dst_path, "%s/ib_logfile0", xtrabackup_incremental_dir);
- sprintf(src_path, "%s/%s", xtrabackup_incremental_dir,
- XB_LOG_FILENAME);
- }
-
- srv_normalize_path_for_win(dst_path);
- srv_normalize_path_for_win(src_path);
-
- success = os_file_rename(0, dst_path, src_path);
- if (!success) {
- goto error;
- }
- xtrabackup_logfile_is_renamed = FALSE;
-
- if (!clear_flag)
- return(FALSE);
-
- /* clear LOG_FILE_WAS_CREATED_BY_HOT_BACKUP field */
- src_file = os_file_create_simple_no_error_handling(0, src_path,
- OS_FILE_OPEN,
- OS_FILE_READ_WRITE,
- &success,0);
- if (!success) {
- goto error;
- }
-
- success = os_file_read(src_file, log_buf, 0, LOG_FILE_HDR_SIZE);
- if (!success) {
- goto error;
- }
-
- memset(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, ' ', 4);
-
- success = os_file_write(src_path, src_file, log_buf, 0,
- LOG_FILE_HDR_SIZE);
- if (!success) {
- goto error;
- }
-
- os_file_close(src_file);
- src_file = XB_FILE_UNDEFINED;
-
- innobase_log_files_in_group = innobase_log_files_in_group_save;
- srv_log_group_home_dir = srv_log_group_home_dir_save;
- innobase_log_file_size = innobase_log_file_size_save;
-
- return(FALSE);
-error:
- if (src_file != XB_FILE_UNDEFINED)
- os_file_close(src_file);
- msg("xtrabackup: Error: xtrabackup_close_temp_log() failed.\n");
- return(TRUE); /*ERROR*/
+ xtrabackup_apply_delta);
}
-
/*********************************************************************//**
Write the meta data (index user fields) config file.
@return true in case of success otherwise false. */
@@ -5359,14 +4784,15 @@ xb_export_cfg_write_header(
}
/* The table name includes the NUL byte. */
- ut_a(table->name != 0);
- len = (ib_uint32_t)strlen(table->name) + 1;
+ const char* table_name = table->name.m_name;
+ ut_a(table_name != 0);
+ len = (ib_uint32_t)strlen(table_name) + 1;
/* Write the table name. */
mach_write_to_4(value, len);
if (fwrite(&value, 1, sizeof(value), file) != sizeof(value)
- || fwrite(table->name, 1, len, file) != len) {
+ || fwrite(table_name, 1, len, file) != len) {
msg("xtrabackup: Error: writing table name.");
@@ -5456,48 +4882,38 @@ static
void
innodb_free_param()
{
- srv_free_paths_and_sizes();
- free(internal_innobase_data_file_path);
- internal_innobase_data_file_path = NULL;
+ srv_sys_space.shutdown();
free_tmpdir(&mysql_tmpdir_list);
}
-/**************************************************************************
-Store the current binary log coordinates in a specified file.
-@return 'false' on error. */
+/** Store the current binary log coordinates in a specified file.
+@param[in] filename file name
+@param[in] name binary log file name
+@param[in] pos binary log file position
+@return whether the operation succeeded */
static bool
-store_binlog_info(
-/*==============*/
- const char *filename) /*!< in: output file name */
+store_binlog_info(const char* filename, const char* name, ulonglong pos)
{
- FILE *fp;
-
- if (trx_sys_mysql_bin_log_name[0] == '\0') {
- return(true);
- }
-
- fp = fopen(filename, "w");
+ FILE *fp = fopen(filename, "w");
if (!fp) {
msg("xtrabackup: failed to open '%s'\n", filename);
return(false);
}
- fprintf(fp, "%s\t" UINT64PF "\n",
- trx_sys_mysql_bin_log_name, trx_sys_mysql_bin_log_pos);
+ fprintf(fp, "%s\t%llu\n", name, pos);
fclose(fp);
return(true);
}
-static void
-xtrabackup_prepare_func(int argc, char ** argv)
+/** Implement --prepare
+@return whether the operation succeeded */
+static bool
+xtrabackup_prepare_func(char** argv)
{
- ulint err;
datafiles_iter_t *it;
- fil_node_t *node;
- fil_space_t *space;
char metadata_path[FN_REFLEN];
/* cd to target-dir */
@@ -5506,10 +4922,11 @@ xtrabackup_prepare_func(int argc, char ** argv)
{
msg("xtrabackup: cannot my_setwd %s\n",
xtrabackup_real_target_dir);
- exit(EXIT_FAILURE);
+ return(false);
}
msg("xtrabackup: cd to %s\n", xtrabackup_real_target_dir);
+ int argc; for (argc = 0; argv[argc]; argc++) {}
encryption_plugin_prepare_init(argc, argv);
xtrabackup_target_dir= mysql_data_home_buff;
@@ -5525,116 +4942,100 @@ xtrabackup_prepare_func(int argc, char ** argv)
if (!xtrabackup_read_metadata(metadata_path)) {
msg("xtrabackup: Error: failed to read metadata from '%s'\n",
metadata_path);
- exit(EXIT_FAILURE);
+ return(false);
}
if (!strcmp(metadata_type, "full-backuped")) {
+ if (xtrabackup_incremental) {
+ msg("xtrabackup: error: applying incremental backup "
+ "needs a prepared target.\n");
+ return(false);
+ }
msg("xtrabackup: This target seems to be not prepared yet.\n");
} else if (!strcmp(metadata_type, "log-applied")) {
- msg("xtrabackup: This target seems to be already "
- "prepared with --apply-log-only.\n");
- goto skip_check;
- } else if (!strcmp(metadata_type, "full-prepared")) {
msg("xtrabackup: This target seems to be already prepared.\n");
} else {
- msg("xtrabackup: This target seems not to have correct "
- "metadata...\n");
- exit(EXIT_FAILURE);
+ msg("xtrabackup: This target does not have correct metadata.\n");
+ return(false);
}
- if (xtrabackup_incremental) {
- msg("xtrabackup: error: applying incremental backup "
- "needs target prepared with --apply-log-only.\n");
- exit(EXIT_FAILURE);
- }
-skip_check:
- if (xtrabackup_incremental
- && metadata_to_lsn != incremental_lsn) {
+ bool ok = !xtrabackup_incremental
+ || metadata_to_lsn == incremental_lsn;
+ if (!ok) {
msg("xtrabackup: error: This incremental backup seems "
"not to be proper for the target.\n"
"xtrabackup: Check 'to_lsn' of the target and "
"'from_lsn' of the incremental.\n");
- exit(EXIT_FAILURE);
+ return(false);
}
- /* Create logfiles for recovery from 'xtrabackup_logfile', before start InnoDB */
srv_max_n_threads = 1000;
+ srv_undo_logs = 1;
srv_n_purge_threads = 1;
- ut_mem_init();
- /* temporally dummy value to avoid crash */
- srv_page_size_shift = 14;
- srv_page_size = (1 << srv_page_size_shift);
- os_sync_init();
- sync_init();
- os_io_init_simple();
- mem_init(srv_mem_pool_size);
- ut_crc32_init();
-
-#ifdef WITH_INNODB_DISALLOW_WRITES
- srv_allow_writes_event = os_event_create();
- os_event_set(srv_allow_writes_event);
-#endif
xb_filters_init();
- if (xtrabackup_init_temp_log())
- goto error_cleanup;
+ srv_log_group_home_dir = NULL;
+ srv_thread_concurrency = 1;
- if(innodb_init_param()) {
- goto error_cleanup;
- }
+ if (xtrabackup_incremental) {
+ if (innodb_init_param()) {
+error_cleanup:
+ xb_filters_free();
+ return(false);
+ }
- xb_normalize_init_values();
+ xb_normalize_init_values();
+ sync_check_init();
+ ut_d(sync_check_enable());
+ ut_crc32_init();
+ recv_sys_init();
+ log_sys_init();
+ recv_recovery_on = true;
- if (xtrabackup_incremental) {
- err = xb_data_files_init();
+#ifdef WITH_INNODB_DISALLOW_WRITES
+ srv_allow_writes_event = os_event_create(0);
+ os_event_set(srv_allow_writes_event);
+#endif
+
+ dberr_t err = xb_data_files_init();
if (err != DB_SUCCESS) {
msg("xtrabackup: error: xb_data_files_init() failed "
- "with error code %lu\n", err);
+ "with error %s\n", ut_strerr(err));
goto error_cleanup;
}
- }
- if (xtrabackup_incremental) {
+
inc_dir_tables_hash = hash_create(1000);
- if(!xtrabackup_apply_deltas()) {
- xb_data_files_close();
- xb_filter_hash_free(inc_dir_tables_hash);
- goto error_cleanup;
- }
- }
- if (xtrabackup_incremental) {
+ ok = xtrabackup_apply_deltas();
+
xb_data_files_close();
- }
- if (xtrabackup_incremental) {
- /* Cleanup datadir from tablespaces deleted between full and
- incremental backups */
- xb_process_datadir("./", ".ibd", rm_if_not_found, NULL);
+ if (ok) {
+ /* Cleanup datadir from tablespaces deleted
+ between full and incremental backups */
+
+ xb_process_datadir("./", ".ibd", rm_if_not_found);
+ }
xb_filter_hash_free(inc_dir_tables_hash);
- }
- if (fil_system) {
+
fil_close();
+#ifdef WITH_INNODB_DISALLOW_WRITES
+ os_event_destroy(srv_allow_writes_event);
+#endif
+ innodb_free_param();
+ log_shutdown();
+ sync_check_close();
+ if (!ok) goto error_cleanup;
}
- mem_close();
- ut_free_all_mem();
-
- innodb_free_param();
- sync_close();
- sync_initialized = FALSE;
-
- /* Reset the configuration as it might have been changed by
- xb_data_files_init(). */
- if(innodb_init_param()) {
+ if (innodb_init_param()) {
goto error_cleanup;
}
- srv_apply_log_only = (bool) xtrabackup_apply_log_only;
-
/* increase IO threads */
- if(srv_n_file_io_threads < 10) {
+ if (srv_n_file_io_threads < 10) {
srv_n_read_io_threads = 4;
srv_n_write_io_threads = 4;
}
@@ -5649,85 +5050,51 @@ skip_check:
srv_max_dirty_pages_pct_lwm = srv_max_buf_pool_modified_pct;
}
- if(innodb_init())
+ if (innodb_init()) {
goto error_cleanup;
-
- if (xtrabackup_incremental) {
-
- it = datafiles_iter_new(fil_system);
- if (it == NULL) {
- msg("xtrabackup: Error: datafiles_iter_new() failed.\n");
- exit(EXIT_FAILURE);
- }
-
- while ((node = datafiles_iter_next(it)) != NULL) {
- byte *header;
- ulint size;
- ulint actual_size;
- mtr_t mtr;
- buf_block_t *block;
- ulint flags;
-
- space = node->space;
-
- /* Align space sizes along with fsp header. We want to process
- each space once, so skip all nodes except the first one in a
- multi-node space. */
- if (UT_LIST_GET_PREV(chain, node) != NULL) {
- continue;
- }
-
- mtr_start(&mtr);
-
- mtr_s_lock(fil_space_get_latch(space->id, &flags), &mtr);
-
- block = buf_page_get(space->id,
- dict_tf_get_zip_size(flags),
- 0, RW_S_LATCH, &mtr);
- header = FSP_HEADER_OFFSET + buf_block_get_frame(block);
-
- size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES,
- &mtr);
-
- mtr_commit(&mtr);
-
- fil_extend_space_to_desired_size(&actual_size, space->id, size);
}
- datafiles_iter_free(it);
-
- } /* if (xtrabackup_incremental) */
-
if (xtrabackup_export) {
+#if 1 // FIXME: remove the option or fix the logic
+ /* In MariaDB 10.2, undo log processing would need the
+ ability to evaluate indexed virtual columns, and we
+ have not initialized the necessary infrastructure. */
+ msg("xtrabackup: --export does not work!\n");
+ ok = false;
+ } else if (xtrabackup_export) {
+#endif
msg("xtrabackup: export option is specified.\n");
+
+ /* To allow subsequent MariaDB server startup independent
+ of the value of --innodb-log-checksums,
+ unconditionally enable redo log checksums. */
+ log_checksum_algorithm_ptr = log_block_calc_checksum_crc32;
+
pfs_os_file_t info_file;
char info_file_path[FN_REFLEN];
- ibool success;
+ bool success;
char table_name[FN_REFLEN];
byte* page;
byte* buf = NULL;
- buf = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE * 2));
+ buf = static_cast<byte *>(malloc(UNIV_PAGE_SIZE * 2));
page = static_cast<byte *>(ut_align(buf, UNIV_PAGE_SIZE));
- /* flush insert buffer at shutdwon */
- innobase_fast_shutdown = 0;
-
it = datafiles_iter_new(fil_system);
if (it == NULL) {
msg("xtrabackup: Error: datafiles_iter_new() "
"failed.\n");
- exit(EXIT_FAILURE);
- }
- while ((node = datafiles_iter_next(it)) != NULL) {
+ ok = false;
+ } else
+ while (fil_node_t *node = datafiles_iter_next(it)) {
int len;
char *next, *prev, *p;
dict_table_t* table;
dict_index_t* index;
ulint n_index;
- space = node->space;
+ const fil_space_t* space = node->space;
/* treat file_per_table only */
if (!fil_is_user_tablespace_id(space->id)) {
@@ -5782,15 +5149,14 @@ skip_check:
"than 31 indexes, .exp file was not "
"generated. Table will fail to import "
"on server version prior to 5.6.\n",
- table->name);
+ table->name.m_name);
goto next_node;
}
/* init exp file */
- memset(page, 0, UNIV_PAGE_SIZE);
- mach_write_to_4(page , 0x78706f72UL);
- mach_write_to_4(page + 4, 0x74696e66UL);/*"xportinf"*/
+ memcpy(page, "xportinf", 8);
mach_write_to_4(page + 8, n_index);
+ memset(page + 12, 0, UNIV_PAGE_SIZE - 12);
strncpy((char *) page + 12,
table_name, 500);
@@ -5810,7 +5176,7 @@ skip_check:
msg("xtrabackup: name=%s, "
"id.low=%lu, page=%lu\n",
- index->name,
+ index->name(),
(ulint)(index->id &
0xFFFFFFFFUL),
(ulint) index->page);
@@ -5818,18 +5184,18 @@ skip_check:
n_index++;
}
- srv_normalize_path_for_win(info_file_path);
+ os_normalize_path(info_file_path);
info_file = os_file_create(
0,
info_file_path,
OS_FILE_OVERWRITE,
OS_FILE_NORMAL, OS_DATA_FILE,
- &success,0);
+ false, &success);
if (!success) {
os_file_get_last_error(TRUE);
goto next_node;
}
- success = os_file_write(info_file_path,
+ success = os_file_write(IORequestWrite, info_file_path,
info_file, page,
0, UNIV_PAGE_SIZE);
if (!success) {
@@ -5842,76 +5208,73 @@ skip_check:
goto next_node;
}
next_node:
- if (info_file != XB_FILE_UNDEFINED) {
+ if (info_file != OS_FILE_CLOSED) {
os_file_close(info_file);
- info_file = XB_FILE_UNDEFINED;
+ info_file = OS_FILE_CLOSED;
}
mutex_exit(&(dict_sys->mutex));
}
- ut_free(buf);
+ free(buf);
}
- /* print the binary log position */
- trx_sys_print_mysql_binlog_offset();
- msg("\n");
-
- /* output to xtrabackup_binlog_pos_innodb and (if
- backup_safe_binlog_info was available on the server) to
- xtrabackup_binlog_info. In the latter case xtrabackup_binlog_pos_innodb
- becomes redundant and is created only for compatibility. */
- if (!store_binlog_info("xtrabackup_binlog_pos_innodb") ||
- (recover_binlog_info &&
- !store_binlog_info(XTRABACKUP_BINLOG_INFO))) {
+ if (ok) {
+ mtr_t mtr;
+ mtr.start();
+ const trx_sysf_t* sys_header = trx_sysf_get(&mtr);
+
+ if (mach_read_from_4(TRX_SYS_MYSQL_LOG_INFO
+ + TRX_SYS_MYSQL_LOG_MAGIC_N_FLD
+ + sys_header)
+ == TRX_SYS_MYSQL_LOG_MAGIC_N) {
+ ulonglong pos = mach_read_from_8(
+ TRX_SYS_MYSQL_LOG_INFO
+ + TRX_SYS_MYSQL_LOG_OFFSET
+ + sys_header);
+ const char* name = reinterpret_cast<const char*>(
+ TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_NAME
+ + sys_header);
+ msg("Last binlog file %s, position %llu\n", name, pos);
+
+ /* output to xtrabackup_binlog_pos_innodb and
+ (if backup_safe_binlog_info was available on
+ the server) to xtrabackup_binlog_info. In the
+ latter case xtrabackup_binlog_pos_innodb
+ becomes redundant and is created only for
+ compatibility. */
+ ok = store_binlog_info(
+ "xtrabackup_binlog_pos_innodb", name, pos)
+ && (!recover_binlog_info || store_binlog_info(
+ XTRABACKUP_BINLOG_INFO,
+ name, pos));
+ }
- exit(EXIT_FAILURE);
+ mtr.commit();
}
/* Check whether the log is applied enough or not. */
- if ((xtrabackup_incremental
- && srv_start_lsn < incremental_to_lsn)
- ||(!xtrabackup_incremental
- && srv_start_lsn < metadata_to_lsn)) {
+ const lsn_t target_lsn = xtrabackup_incremental
+ ? incremental_to_lsn : metadata_to_lsn;
+ if ((srv_start_lsn || fil_space_get(SRV_LOG_SPACE_FIRST_ID))
+ && srv_start_lsn < target_lsn) {
msg("xtrabackup: error: "
- "The transaction log file is corrupted.\n"
- "xtrabackup: error: "
- "The log was not applied to the intended LSN!\n");
- msg("xtrabackup: Log applied to lsn " LSN_PF "\n",
- srv_start_lsn);
- if (xtrabackup_incremental) {
- msg("xtrabackup: The intended lsn is " LSN_PF "\n",
- incremental_to_lsn);
- } else {
- msg("xtrabackup: The intended lsn is " LSN_PF "\n",
- metadata_to_lsn);
- }
- exit(EXIT_FAILURE);
+ "The log was only applied up to LSN " LSN_PF
+ ", instead of " LSN_PF "\n",
+ srv_start_lsn, target_lsn);
+ ok = false;
}
#ifdef WITH_WSREP
- xb_write_galera_info(xtrabackup_incremental);
+ else if (ok) xb_write_galera_info(xtrabackup_incremental);
#endif
- innodb_end();
-
- innodb_free_param();
-
- sync_initialized = FALSE;
-
- /* re-init necessary components */
- ut_mem_init();
- os_sync_init();
- sync_init();
- os_io_init_simple();
-
- if(xtrabackup_close_temp_log(TRUE))
- exit(EXIT_FAILURE);
+ innodb_shutdown();
+ innodb_free_param();
/* output to metadata file */
- {
+ if (ok) {
char filename[FN_REFLEN];
- strcpy(metadata_type, srv_apply_log_only ?
- "log-applied" : "full-prepared");
+ strcpy(metadata_type, "log-applied");
if(xtrabackup_incremental
&& metadata_to_lsn < incremental_to_lsn)
@@ -5925,73 +5288,21 @@ next_node:
msg("xtrabackup: Error: failed to write metadata "
"to '%s'\n", filename);
- exit(EXIT_FAILURE);
- }
-
- if(xtrabackup_extra_lsndir) {
+ ok = false;
+ } else if (xtrabackup_extra_lsndir) {
sprintf(filename, "%s/%s", xtrabackup_extra_lsndir, XTRABACKUP_METADATA_FILENAME);
if (!xtrabackup_write_metadata(filename)) {
msg("xtrabackup: Error: failed to write "
"metadata to '%s'\n", filename);
- exit(EXIT_FAILURE);
+ ok = false;
}
}
}
- if (!apply_log_finish()) {
- exit(EXIT_FAILURE);
- }
-
- sync_close();
- sync_initialized = FALSE;
- if (fil_system) {
- fil_close();
- }
-
- ut_free_all_mem();
-
- /* start InnoDB once again to create log files */
-
- if (!xtrabackup_apply_log_only) {
-
- /* xtrabackup_incremental_dir is used to indicate that
- we are going to apply incremental backup. Here we already
- applied incremental backup and are about to do final prepare
- of the full backup */
- xtrabackup_incremental_dir = NULL;
-
- if(innodb_init_param()) {
- goto error;
- }
-
- srv_apply_log_only = false;
-
- /* increase IO threads */
- if(srv_n_file_io_threads < 10) {
- srv_n_read_io_threads = 4;
- srv_n_write_io_threads = 4;
- }
-
- srv_shutdown_state = SRV_SHUTDOWN_NONE;
-
- if(innodb_init())
- goto error;
-
- innodb_end();
- innodb_free_param();
-
- }
-
- xb_filters_free();
-
- return;
+ if (ok) ok = apply_log_finish();
-error_cleanup:
- xtrabackup_close_temp_log(FALSE);
xb_filters_free();
-
-error:
- exit(EXIT_FAILURE);
+ return ok;
}
/**************************************************************************
@@ -6084,7 +5395,8 @@ extern void init_signals(void);
/* Messages . Avoid loading errmsg.sys file */
void setup_error_messages()
{
- static const char *all_msgs[ER_ERROR_LAST - ER_ERROR_FIRST +1];
+ static const char *my_msgs[ERRORS_PER_RANGE];
+ static const char **all_msgs[] = { my_msgs, my_msgs, my_msgs, my_msgs };
my_default_lc_messages = &my_locale_en_US;
my_default_lc_messages->errmsgs->errmsgs = all_msgs;
@@ -6111,24 +5423,20 @@ void setup_error_messages()
};
for (int i = 0; i < (int)array_elements(all_msgs); i++)
- all_msgs[i] = "Unknown error";
+ all_msgs[0][i] = "Unknown error";
for (int i = 0; i < (int)array_elements(xb_msgs); i++)
- all_msgs[xb_msgs[i].id - ER_ERROR_FIRST] = xb_msgs[i].fmt;
+ all_msgs[0][xb_msgs[i].id - ER_ERROR_FIRST] = xb_msgs[i].fmt;
}
-extern my_bool(*dict_check_if_skip_table)(const char* name) ;
-
void
handle_options(int argc, char **argv, char ***argv_client, char ***argv_server)
{
/* Setup some variables for Innodb.*/
- srv_xtrabackup = true;
-
+ srv_operation = SRV_OPERATION_RESTORE;
files_charset_info = &my_charset_utf8_general_ci;
- dict_check_if_skip_table = check_if_skip_table;
setup_error_messages();
sys_var_init();
@@ -6312,25 +5620,21 @@ handle_options(int argc, char **argv, char ***argv_client, char ***argv_server)
}
}
-/* ================= main =================== */
-extern my_bool(*fil_check_if_skip_database_by_path)(const char* name);
+static int main_low(char** argv);
+/* ================= main =================== */
int main(int argc, char **argv)
{
char **client_defaults, **server_defaults;
- char cwd[FN_REFLEN];
- static char INNOBACKUPEX_EXE[]= "innobackupex";
+ static char INNOBACKUPEX_EXE[]= "innobackupex";
if (argc > 1 && (strcmp(argv[1], "--innobackupex") == 0))
{
argv++;
argc--;
- argv[0] = INNOBACKUPEX_EXE;
+ argv[0] = INNOBACKUPEX_EXE;
innobackupex_mode = true;
}
- /* Setup skip fil_load_single_tablespaces callback.*/
- fil_check_if_skip_database_by_path = check_if_skip_database_by_path;
-
init_signals();
MY_INIT(argv[0]);
@@ -6349,30 +5653,69 @@ int main(int argc, char **argv)
system_charset_info = &my_charset_utf8_general_ci;
key_map_full.set_all();
+ logger.init_base();
+ logger.set_handlers(LOG_FILE, LOG_NONE, LOG_NONE);
+ mysql_mutex_init(key_LOCK_error_log, &LOCK_error_log,
+ MY_MUTEX_INIT_FAST);
+
handle_options(argc, argv, &client_defaults, &server_defaults);
- int argc_server;
- for (argc_server = 0; server_defaults[argc_server]; argc_server++) {}
+#ifndef DBUG_OFF
+ if (dbug_option) {
+ DBUG_SET_INITIAL(dbug_option);
+ DBUG_SET(dbug_option);
+ }
+#endif
- int argc_client;
- for (argc_client = 0; client_defaults[argc_client]; argc_client++) {}
+ int status = main_low(server_defaults);
+ backup_cleanup();
if (innobackupex_mode) {
+ ibx_cleanup();
+ }
+
+ free_defaults(client_defaults);
+ free_defaults(server_defaults);
+
+#ifndef DBUG_OFF
+ if (dbug_option) {
+ DBUG_END();
+ }
+#endif
+
+ if (THR_THD)
+ (void) pthread_key_delete(THR_THD);
+
+ logger.cleanup_base();
+ mysql_mutex_destroy(&LOCK_error_log);
+
+ if (status == EXIT_SUCCESS) {
+ msg_ts("completed OK!\n");
+ }
+
+ return status;
+}
+
+static int main_low(char** argv)
+{
+ if (innobackupex_mode) {
if (!ibx_init()) {
- exit(EXIT_FAILURE);
+ return(EXIT_FAILURE);
}
}
- if ((!xtrabackup_print_param) && (!xtrabackup_prepare) && (strcmp(mysql_data_home, "./") == 0)) {
+ if (!xtrabackup_print_param && !xtrabackup_prepare
+ && !strcmp(mysql_data_home, "./")) {
if (!xtrabackup_print_param)
usage();
msg("\nxtrabackup: Error: Please set parameter 'datadir'\n");
- exit(EXIT_FAILURE);
+ return(EXIT_FAILURE);
}
/* Expand target-dir, incremental-basedir, etc. */
+ char cwd[FN_REFLEN];
my_getwd(cwd, sizeof(cwd), MYF(0));
my_load_path(xtrabackup_real_target_dir,
@@ -6438,7 +5781,7 @@ int main(int argc, char **argv)
if (error) {
msg("xtrabackup: value '%s' may be wrong format for "
"incremental option.\n", xtrabackup_incremental);
- exit(EXIT_FAILURE);
+ return(EXIT_FAILURE);
}
} else if (xtrabackup_backup && xtrabackup_incremental_basedir) {
char filename[FN_REFLEN];
@@ -6448,7 +5791,7 @@ int main(int argc, char **argv)
if (!xtrabackup_read_metadata(filename)) {
msg("xtrabackup: error: failed to read metadata from "
"%s\n", filename);
- exit(EXIT_FAILURE);
+ return(EXIT_FAILURE);
}
incremental_lsn = metadata_to_lsn;
@@ -6461,7 +5804,7 @@ int main(int argc, char **argv)
if (!xtrabackup_read_metadata(filename)) {
msg("xtrabackup: error: failed to read metadata from "
"%s\n", filename);
- exit(EXIT_FAILURE);
+ return(EXIT_FAILURE);
}
incremental_lsn = metadata_from_lsn;
@@ -6478,15 +5821,13 @@ int main(int argc, char **argv)
}
if (!xb_init()) {
- exit(EXIT_FAILURE);
+ return(EXIT_FAILURE);
}
/* --print-param */
if (xtrabackup_print_param) {
-
printf("%s", print_param_str.str().c_str());
-
- exit(EXIT_SUCCESS);
+ return(EXIT_SUCCESS);
}
print_version();
@@ -6512,7 +5853,7 @@ int main(int argc, char **argv)
if (xtrabackup_decrypt_decompress) num++;
if (num != 1) { /* !XOR (for now) */
usage();
- exit(EXIT_FAILURE);
+ return(EXIT_FAILURE);
}
}
@@ -6523,41 +5864,28 @@ int main(int argc, char **argv)
#endif
/* --backup */
- if (xtrabackup_backup)
- xtrabackup_backup_func();
+ if (xtrabackup_backup && !xtrabackup_backup_func()) {
+ return(EXIT_FAILURE);
+ }
/* --prepare */
- if (xtrabackup_prepare) {
- xtrabackup_prepare_func(argc_server, server_defaults);
+ if (xtrabackup_prepare
+ && !xtrabackup_prepare_func(argv)) {
+ return(EXIT_FAILURE);
}
if (xtrabackup_copy_back || xtrabackup_move_back) {
if (!check_if_param_set("datadir")) {
msg("Error: datadir must be specified.\n");
- exit(EXIT_FAILURE);
+ return(EXIT_FAILURE);
}
if (!copy_back())
- exit(EXIT_FAILURE);
+ return(EXIT_FAILURE);
}
if (xtrabackup_decrypt_decompress && !decrypt_decompress()) {
- exit(EXIT_FAILURE);
- }
-
- backup_cleanup();
-
- if (innobackupex_mode) {
- ibx_cleanup();
+ return(EXIT_FAILURE);
}
-
- free_defaults(client_defaults);
- free_defaults(server_defaults);
-
- if (THR_THD)
- (void) pthread_key_delete(THR_THD);
-
- msg_ts("completed OK!\n");
-
- exit(EXIT_SUCCESS);
+ return(EXIT_SUCCESS);
}
diff --git a/extra/mariabackup/xtrabackup.h b/extra/mariabackup/xtrabackup.h
index eafc848fd43..b883194ef86 100644
--- a/extra/mariabackup/xtrabackup.h
+++ b/extra/mariabackup/xtrabackup.h
@@ -26,26 +26,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#include "xbstream.h"
#include "changed_page_bitmap.h"
-#ifdef __WIN__
-#define XB_FILE_UNDEFINED INVALID_HANDLE_VALUE
-#else
-#define XB_FILE_UNDEFINED (-1)
-#endif
+struct xb_delta_info_t
+{
+ xb_delta_info_t(page_size_t page_size, ulint space_id)
+ : page_size(page_size), space_id(space_id) {}
-typedef struct {
- ulint page_size;
- ulint zip_size;
- ulint space_id;
-} xb_delta_info_t;
-
-/* ======== Datafiles iterator ======== */
-typedef struct {
- fil_system_t *system;
- fil_space_t *space;
- fil_node_t *node;
- ibool started;
- os_ib_mutex_t mutex;
-} datafiles_iter_t;
+ page_size_t page_size;
+ ulint space_id;
+};
/* value of the --incremental option */
extern lsn_t incremental_lsn;
@@ -84,15 +72,11 @@ extern ibool xtrabackup_compress;
extern my_bool xtrabackup_backup;
extern my_bool xtrabackup_prepare;
-extern my_bool xtrabackup_apply_log_only;
extern my_bool xtrabackup_copy_back;
extern my_bool xtrabackup_move_back;
extern my_bool xtrabackup_decrypt_decompress;
extern char *innobase_data_file_path;
-extern char *innobase_doublewrite_file;
-extern longlong innobase_log_file_size;
-extern long innobase_log_files_in_group;
extern longlong innobase_page_size;
extern int xtrabackup_parallel;
@@ -108,9 +92,7 @@ extern "C"{
}
#endif
extern my_bool xtrabackup_export;
-extern char *xtrabackup_incremental_basedir;
extern char *xtrabackup_extra_lsndir;
-extern char *xtrabackup_incremental_dir;
extern ulint xtrabackup_log_copy_interval;
extern char *xtrabackup_stream_str;
extern long xtrabackup_throttle;
@@ -166,14 +148,9 @@ void xtrabackup_io_throttling(void);
my_bool xb_write_delta_metadata(const char *filename,
const xb_delta_info_t *info);
-datafiles_iter_t *datafiles_iter_new(fil_system_t *f_system);
-fil_node_t *datafiles_iter_next(datafiles_iter_t *it);
-void datafiles_iter_free(datafiles_iter_t *it);
-
-/***********************************************************************
-Reads the space flags from a given data file and returns the compressed
-page size, or 0 if the space is not compressed. */
-ulint xb_get_zip_size(pfs_os_file_t file);
+/** @return the tablespace flags from a given data file
+@retval ULINT_UNDEFINED if the file is not readable */
+ulint xb_get_space_flags(pfs_os_file_t file);
/************************************************************************
Checks if a table specified as a name in the form "database/name" (InnoDB 5.6)
@@ -204,17 +181,10 @@ bool
check_if_param_set(const char *param);
#if defined(HAVE_OPENSSL)
-extern my_bool opt_use_ssl;
extern my_bool opt_ssl_verify_server_cert;
-#if !defined(HAVE_YASSL)
-extern char *opt_server_public_key;
-#endif
#endif
-void
-xtrabackup_backup_func(void);
-
my_bool
xb_get_one_option(int optid,
const struct my_option *opt __attribute__((unused)),