2017-04-18 20:43:20 +02:00
|
|
|
/******************************************************
|
|
|
|
hot backup tool for InnoDB
|
|
|
|
(c) 2009-2015 Percona LLC and/or its affiliates
|
2017-04-18 21:05:57 +02:00
|
|
|
(c) 2017 MariaDB
|
2017-04-18 20:43:20 +02:00
|
|
|
Originally Created 3/3/2009 Yasufumi Kinoshita
|
|
|
|
Written by Alexey Kopytov, Aleksandr Kuzminsky, Stewart Smith, Vadim Tkachenko,
|
|
|
|
Yasufumi Kinoshita, Ignacio Nin and Baron Schwartz.
|
|
|
|
|
|
|
|
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
|
|
|
|
the Free Software Foundation; version 2 of the License.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program; if not, write to the Free Software
|
2019-05-11 21:19:05 +02:00
|
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
*******************************************************
|
|
|
|
|
|
|
|
This file incorporates work covered by the following copyright and
|
|
|
|
permission notice:
|
|
|
|
|
|
|
|
Copyright (c) 2000, 2011, MySQL AB & Innobase Oy. All Rights Reserved.
|
|
|
|
|
|
|
|
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 the Free Software
|
|
|
|
Foundation; version 2 of the License.
|
|
|
|
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
2019-05-11 18:25:02 +02:00
|
|
|
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
|
|
|
|
Street, Fifth Floor, Boston, MA 02110-1335 USA
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
*******************************************************/
|
|
|
|
|
|
|
|
#include <my_global.h>
|
2023-12-03 13:09:43 +01:00
|
|
|
#include <my_config.h>
|
|
|
|
#include <unireg.h>
|
|
|
|
#include <datadict.h>
|
2017-04-18 20:43:20 +02:00
|
|
|
#include <os0file.h>
|
|
|
|
#include <my_dir.h>
|
|
|
|
#include <ut0mem.h>
|
|
|
|
#include <srv0start.h>
|
|
|
|
#include <fil0fil.h>
|
2017-11-07 22:02:39 +01:00
|
|
|
#include <trx0sys.h>
|
2017-04-18 20:43:20 +02:00
|
|
|
#include <set>
|
|
|
|
#include <string>
|
|
|
|
#include <mysqld.h>
|
|
|
|
#include <sstream>
|
|
|
|
#include "fil_cur.h"
|
|
|
|
#include "xtrabackup.h"
|
|
|
|
#include "common.h"
|
|
|
|
#include "backup_copy.h"
|
2022-04-15 17:21:54 +02:00
|
|
|
#include "backup_debug.h"
|
2017-04-18 20:43:20 +02:00
|
|
|
#include "backup_mysql.h"
|
2017-04-18 21:05:57 +02:00
|
|
|
#include <btr0btr.h>
|
2022-11-09 13:41:19 +01:00
|
|
|
#ifdef _WIN32
|
|
|
|
#include <direct.h> /* rmdir */
|
|
|
|
#endif
|
2024-10-03 07:15:48 +02:00
|
|
|
#include <functional>
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2020-04-28 01:06:11 +02:00
|
|
|
#ifdef _WIN32
|
|
|
|
#include <aclapi.h>
|
|
|
|
#endif
|
|
|
|
|
2023-12-03 13:09:43 +01:00
|
|
|
#ifdef MYSQL_CLIENT
|
|
|
|
#define WAS_MYSQL_CLIENT 1
|
|
|
|
#undef MYSQL_CLIENT
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "table.h"
|
|
|
|
|
|
|
|
#ifdef WAS_MYSQL_CLIENT
|
|
|
|
#define MYSQL_CLIENT 1
|
|
|
|
#undef WAS_MYSQL_CLIENT
|
|
|
|
#endif
|
2020-05-11 22:01:40 +02:00
|
|
|
|
2018-06-07 16:13:54 +02:00
|
|
|
#define ROCKSDB_BACKUP_DIR "#rocksdb"
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
/* locations of tablespaces read from .isl files */
|
|
|
|
static std::map<std::string, std::string> tablespace_locations;
|
|
|
|
|
|
|
|
/* Whether LOCK BINLOG FOR BACKUP has been issued during backup */
|
|
|
|
bool binlog_locked;
|
|
|
|
|
2023-04-12 09:40:46 +02:00
|
|
|
static void rocksdb_backup_checkpoint(ds_ctxt *ds_data);
|
|
|
|
static void rocksdb_copy_back(ds_ctxt *ds_data);
|
2018-06-07 16:13:54 +02:00
|
|
|
|
|
|
|
static bool is_abs_path(const char *path)
|
|
|
|
{
|
|
|
|
#ifdef _WIN32
|
|
|
|
return path[0] && path[1] == ':' && (path[2] == '/' || path[2] == '\\');
|
|
|
|
#else
|
|
|
|
return path[0] == '/';
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2017-04-18 20:43:20 +02:00
|
|
|
/************************************************************************
|
|
|
|
Struct represents file or directory. */
|
|
|
|
struct datadir_node_t {
|
|
|
|
ulint dbpath_len;
|
|
|
|
char *filepath;
|
|
|
|
ulint filepath_len;
|
|
|
|
char *filepath_rel;
|
|
|
|
ulint filepath_rel_len;
|
|
|
|
bool is_empty_dir;
|
|
|
|
bool is_file;
|
|
|
|
};
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Holds the state needed to enumerate files in MySQL data directory. */
|
|
|
|
struct datadir_iter_t {
|
|
|
|
char *datadir_path;
|
|
|
|
char *dbpath;
|
|
|
|
ulint dbpath_len;
|
|
|
|
char *filepath;
|
|
|
|
ulint filepath_len;
|
|
|
|
char *filepath_rel;
|
|
|
|
ulint filepath_rel_len;
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
pthread_mutex_t mutex;
|
2017-04-18 20:43:20 +02:00
|
|
|
os_file_dir_t dir;
|
|
|
|
os_file_dir_t dbdir;
|
|
|
|
os_file_stat_t dbinfo;
|
|
|
|
os_file_stat_t fileinfo;
|
|
|
|
dberr_t err;
|
|
|
|
bool is_empty_dir;
|
|
|
|
bool is_file;
|
|
|
|
bool skip_first_level;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Represents the context of the thread processing MySQL data directory. */
|
|
|
|
struct datadir_thread_ctxt_t {
|
|
|
|
datadir_iter_t *it;
|
|
|
|
uint n_thread;
|
|
|
|
uint *count;
|
2018-09-20 20:27:59 +02:00
|
|
|
pthread_mutex_t* count_mutex;
|
2017-04-18 20:43:20 +02:00
|
|
|
bool ret;
|
|
|
|
};
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Retirn true if character if file separator */
|
|
|
|
bool
|
|
|
|
is_path_separator(char c)
|
|
|
|
{
|
|
|
|
return(c == FN_LIBCHAR || c == FN_LIBCHAR2);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Fill the node struct. Memory for node need to be allocated and freed by
|
|
|
|
the caller. It is caller responsibility to initialize node with
|
|
|
|
datadir_node_init and cleanup the memory with datadir_node_free.
|
|
|
|
Node can not be shared between threads. */
|
|
|
|
static
|
|
|
|
void
|
|
|
|
datadir_node_fill(datadir_node_t *node, datadir_iter_t *it)
|
|
|
|
{
|
|
|
|
if (node->filepath_len < it->filepath_len) {
|
|
|
|
free(node->filepath);
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
node->filepath = (char*)(malloc(it->filepath_len));
|
2017-04-18 20:43:20 +02:00
|
|
|
node->filepath_len = it->filepath_len;
|
|
|
|
}
|
|
|
|
if (node->filepath_rel_len < it->filepath_rel_len) {
|
|
|
|
free(node->filepath_rel);
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
node->filepath_rel = (char*)(malloc(it->filepath_rel_len));
|
2017-04-18 20:43:20 +02:00
|
|
|
node->filepath_rel_len = it->filepath_rel_len;
|
|
|
|
}
|
|
|
|
|
|
|
|
strcpy(node->filepath, it->filepath);
|
|
|
|
strcpy(node->filepath_rel, it->filepath_rel);
|
|
|
|
node->is_empty_dir = it->is_empty_dir;
|
|
|
|
node->is_file = it->is_file;
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
void
|
|
|
|
datadir_node_free(datadir_node_t *node)
|
|
|
|
{
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
free(node->filepath);
|
|
|
|
free(node->filepath_rel);
|
2017-04-18 20:43:20 +02:00
|
|
|
memset(node, 0, sizeof(datadir_node_t));
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
void
|
|
|
|
datadir_node_init(datadir_node_t *node)
|
|
|
|
{
|
|
|
|
memset(node, 0, sizeof(datadir_node_t));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Create the MySQL data directory iterator. Memory needs to be released
|
|
|
|
with datadir_iter_free. Position should be advanced with
|
|
|
|
datadir_iter_next_file. Iterator can be shared between multiple
|
|
|
|
threads. It is guaranteed that each thread receives unique file from
|
|
|
|
data directory into its local node struct. */
|
|
|
|
static
|
|
|
|
datadir_iter_t *
|
|
|
|
datadir_iter_new(const char *path, bool skip_first_level = true)
|
|
|
|
{
|
|
|
|
datadir_iter_t *it;
|
|
|
|
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
it = static_cast<datadir_iter_t *>(malloc(sizeof(datadir_iter_t)));
|
2021-09-01 18:21:34 +02:00
|
|
|
if (!it)
|
|
|
|
goto error;
|
2017-04-18 20:43:20 +02:00
|
|
|
memset(it, 0, sizeof(datadir_iter_t));
|
|
|
|
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
pthread_mutex_init(&it->mutex, NULL);
|
2017-04-18 20:43:20 +02:00
|
|
|
it->datadir_path = strdup(path);
|
|
|
|
|
2021-05-18 11:13:18 +02:00
|
|
|
it->dir = os_file_opendir(it->datadir_path);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2021-05-18 11:13:18 +02:00
|
|
|
if (it->dir == IF_WIN(INVALID_HANDLE_VALUE, nullptr)) {
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
it->err = DB_SUCCESS;
|
|
|
|
|
|
|
|
it->dbpath_len = FN_REFLEN;
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
it->dbpath = static_cast<char*>(malloc(it->dbpath_len));
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
it->filepath_len = FN_REFLEN;
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
it->filepath = static_cast<char*>(malloc(it->filepath_len));
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
it->filepath_rel_len = FN_REFLEN;
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
it->filepath_rel = static_cast<char*>(malloc(it->filepath_rel_len));
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
it->skip_first_level = skip_first_level;
|
|
|
|
|
|
|
|
return(it);
|
|
|
|
|
|
|
|
error:
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
free(it);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
return(NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
bool
|
|
|
|
datadir_iter_next_database(datadir_iter_t *it)
|
|
|
|
{
|
|
|
|
if (it->dbdir != NULL) {
|
2021-05-18 11:13:18 +02:00
|
|
|
if (os_file_closedir_failed(it->dbdir)) {
|
2017-04-18 20:43:20 +02:00
|
|
|
msg("Warning: could not"
|
2019-01-14 22:28:23 +01:00
|
|
|
" close database directory %s", it->dbpath);
|
2017-04-18 20:43:20 +02:00
|
|
|
it->err = DB_ERROR;
|
|
|
|
|
|
|
|
}
|
|
|
|
it->dbdir = NULL;
|
|
|
|
}
|
|
|
|
|
2017-04-18 21:05:57 +02:00
|
|
|
while (os_file_readdir_next_file(it->datadir_path,
|
2017-04-18 20:43:20 +02:00
|
|
|
it->dir, &it->dbinfo) == 0) {
|
|
|
|
ulint len;
|
|
|
|
|
|
|
|
if ((it->dbinfo.type == OS_FILE_TYPE_FILE
|
|
|
|
&& it->skip_first_level)
|
|
|
|
|| it->dbinfo.type == OS_FILE_TYPE_UNKNOWN) {
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We found a symlink or a directory; try opening it to see
|
|
|
|
if a symlink is a directory */
|
|
|
|
|
|
|
|
len = strlen(it->datadir_path)
|
|
|
|
+ strlen (it->dbinfo.name) + 2;
|
|
|
|
if (len > it->dbpath_len) {
|
|
|
|
it->dbpath_len = len;
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
free(it->dbpath);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
it->dbpath = static_cast<char*>(
|
|
|
|
malloc(it->dbpath_len));
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
2017-11-11 22:07:24 +01:00
|
|
|
snprintf(it->dbpath, it->dbpath_len, "%s/%s",
|
|
|
|
it->datadir_path, it->dbinfo.name);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
if (it->dbinfo.type == OS_FILE_TYPE_FILE) {
|
|
|
|
it->is_file = true;
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
2017-04-19 15:09:03 +02:00
|
|
|
if (check_if_skip_database_by_path(it->dbpath)) {
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Skipping db: %s", it->dbpath);
|
2017-04-19 15:09:03 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-04-18 20:43:20 +02:00
|
|
|
/* We want wrong directory permissions to be a fatal error for
|
|
|
|
XtraBackup. */
|
2021-05-18 11:13:18 +02:00
|
|
|
it->dbdir = os_file_opendir(it->dbpath);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2021-05-18 11:13:18 +02:00
|
|
|
if (it->dir != IF_WIN(INVALID_HANDLE_VALUE, nullptr)) {
|
2017-04-18 20:43:20 +02:00
|
|
|
it->is_file = false;
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Concatenate n parts into single path */
|
|
|
|
static
|
|
|
|
void
|
|
|
|
make_path_n(int n, char **path, ulint *path_len, ...)
|
|
|
|
{
|
|
|
|
ulint len_needed = n + 1;
|
|
|
|
char *p;
|
|
|
|
int i;
|
|
|
|
va_list vl;
|
|
|
|
|
|
|
|
ut_ad(n > 0);
|
|
|
|
|
|
|
|
va_start(vl, path_len);
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
p = va_arg(vl, char*);
|
|
|
|
len_needed += strlen(p);
|
|
|
|
}
|
|
|
|
va_end(vl);
|
|
|
|
|
|
|
|
if (len_needed < *path_len) {
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
free(*path);
|
|
|
|
*path = static_cast<char*>(malloc(len_needed));
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
va_start(vl, path_len);
|
|
|
|
p = va_arg(vl, char*);
|
|
|
|
strcpy(*path, p);
|
|
|
|
for (i = 1; i < n; i++) {
|
|
|
|
size_t plen;
|
|
|
|
p = va_arg(vl, char*);
|
|
|
|
plen = strlen(*path);
|
|
|
|
if (!is_path_separator((*path)[plen - 1])) {
|
|
|
|
(*path)[plen] = FN_LIBCHAR;
|
|
|
|
(*path)[plen + 1] = 0;
|
|
|
|
}
|
|
|
|
strcat(*path + plen, p);
|
|
|
|
}
|
|
|
|
va_end(vl);
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
bool
|
|
|
|
datadir_iter_next_file(datadir_iter_t *it)
|
|
|
|
{
|
|
|
|
if (it->is_file && it->dbpath) {
|
|
|
|
make_path_n(2, &it->filepath, &it->filepath_len,
|
|
|
|
it->datadir_path, it->dbinfo.name);
|
|
|
|
|
|
|
|
make_path_n(1, &it->filepath_rel, &it->filepath_rel_len,
|
|
|
|
it->dbinfo.name);
|
|
|
|
|
|
|
|
it->is_empty_dir = false;
|
|
|
|
it->is_file = false;
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!it->dbpath || !it->dbdir) {
|
|
|
|
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
2017-04-18 21:05:57 +02:00
|
|
|
while (os_file_readdir_next_file(it->dbpath, it->dbdir,
|
2017-04-18 20:43:20 +02:00
|
|
|
&it->fileinfo) == 0) {
|
|
|
|
|
|
|
|
if (it->fileinfo.type == OS_FILE_TYPE_DIR) {
|
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* We found a symlink or a file */
|
|
|
|
make_path_n(3, &it->filepath, &it->filepath_len,
|
|
|
|
it->datadir_path, it->dbinfo.name,
|
|
|
|
it->fileinfo.name);
|
|
|
|
|
|
|
|
make_path_n(2, &it->filepath_rel, &it->filepath_rel_len,
|
|
|
|
it->dbinfo.name, it->fileinfo.name);
|
|
|
|
|
|
|
|
it->is_empty_dir = false;
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
bool
|
|
|
|
datadir_iter_next(datadir_iter_t *it, datadir_node_t *node)
|
|
|
|
{
|
|
|
|
bool ret = true;
|
|
|
|
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
pthread_mutex_lock(&it->mutex);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
if (datadir_iter_next_file(it)) {
|
|
|
|
|
|
|
|
datadir_node_fill(node, it);
|
|
|
|
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (datadir_iter_next_database(it)) {
|
|
|
|
|
|
|
|
if (datadir_iter_next_file(it)) {
|
|
|
|
|
|
|
|
datadir_node_fill(node, it);
|
|
|
|
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
make_path_n(2, &it->filepath, &it->filepath_len,
|
|
|
|
it->datadir_path, it->dbinfo.name);
|
|
|
|
|
|
|
|
make_path_n(1, &it->filepath_rel, &it->filepath_rel_len,
|
|
|
|
it->dbinfo.name);
|
|
|
|
|
|
|
|
it->is_empty_dir = true;
|
|
|
|
|
|
|
|
datadir_node_fill(node, it);
|
|
|
|
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* nothing found */
|
|
|
|
ret = false;
|
|
|
|
|
|
|
|
done:
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
pthread_mutex_unlock(&it->mutex);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Interface to read MySQL data file sequentially. One should open file
|
|
|
|
with datafile_open to get cursor and close the cursor with
|
|
|
|
datafile_close. Cursor can not be shared between multiple
|
|
|
|
threads. */
|
|
|
|
static
|
|
|
|
void
|
|
|
|
datadir_iter_free(datadir_iter_t *it)
|
|
|
|
{
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
pthread_mutex_destroy(&it->mutex);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
if (it->dbdir) {
|
|
|
|
|
|
|
|
os_file_closedir(it->dbdir);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (it->dir) {
|
|
|
|
|
|
|
|
os_file_closedir(it->dir);
|
|
|
|
}
|
|
|
|
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
free(it->dbpath);
|
|
|
|
free(it->filepath);
|
|
|
|
free(it->filepath_rel);
|
2017-04-18 20:43:20 +02:00
|
|
|
free(it->datadir_path);
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
free(it);
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Holds the state needed to copy single data file. */
|
|
|
|
struct datafile_cur_t {
|
2017-05-19 12:59:43 +02:00
|
|
|
pfs_os_file_t file;
|
2017-04-18 20:43:20 +02:00
|
|
|
char rel_path[FN_REFLEN];
|
|
|
|
char abs_path[FN_REFLEN];
|
|
|
|
MY_STAT statinfo;
|
|
|
|
uint thread_n;
|
|
|
|
byte* buf;
|
2017-04-18 21:05:57 +02:00
|
|
|
size_t buf_size;
|
|
|
|
size_t buf_read;
|
|
|
|
size_t buf_offset;
|
2018-08-03 11:21:13 +02:00
|
|
|
|
|
|
|
explicit datafile_cur_t(const char* filename = NULL) :
|
2019-12-05 05:42:31 +01:00
|
|
|
file(), thread_n(0), buf(NULL), buf_size(0),
|
2018-08-03 11:21:13 +02:00
|
|
|
buf_read(0), buf_offset(0)
|
|
|
|
{
|
|
|
|
memset(rel_path, 0, sizeof rel_path);
|
|
|
|
if (filename) {
|
2019-11-04 14:52:54 +01:00
|
|
|
strncpy(abs_path, filename, sizeof abs_path - 1);
|
2018-08-03 11:21:13 +02:00
|
|
|
abs_path[(sizeof abs_path) - 1] = 0;
|
|
|
|
} else {
|
|
|
|
abs_path[0] = '\0';
|
|
|
|
}
|
|
|
|
rel_path[0] = '\0';
|
|
|
|
memset(&statinfo, 0, sizeof statinfo);
|
|
|
|
}
|
2017-04-18 20:43:20 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
static
|
|
|
|
void
|
|
|
|
datafile_close(datafile_cur_t *cursor)
|
|
|
|
{
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
if (cursor->file != OS_FILE_CLOSED) {
|
2017-04-18 20:43:20 +02:00
|
|
|
os_file_close(cursor->file);
|
|
|
|
}
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
free(cursor->buf);
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
bool
|
|
|
|
datafile_open(const char *file, datafile_cur_t *cursor, uint thread_n)
|
|
|
|
{
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
bool success;
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2018-08-03 11:21:13 +02:00
|
|
|
new (cursor) datafile_cur_t(file);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
/* 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. */
|
|
|
|
strncpy(cursor->rel_path,
|
|
|
|
xb_get_relative_path(cursor->abs_path, FALSE),
|
2019-03-06 10:22:27 +01:00
|
|
|
(sizeof cursor->rel_path) - 1);
|
|
|
|
cursor->rel_path[(sizeof cursor->rel_path) - 1] = '\0';
|
2017-04-18 20:43:20 +02:00
|
|
|
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
cursor->file = os_file_create_simple_no_error_handling(
|
|
|
|
0, cursor->abs_path,
|
|
|
|
OS_FILE_OPEN, OS_FILE_READ_ALLOW_DELETE, true, &success);
|
2017-04-18 20:43:20 +02:00
|
|
|
if (!success) {
|
|
|
|
/* The following call prints an error message */
|
|
|
|
os_file_get_last_error(TRUE);
|
|
|
|
|
2019-01-14 22:28:23 +01:00
|
|
|
msg(thread_n,"error: cannot open "
|
|
|
|
"file %s", cursor->abs_path);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
2017-04-18 21:05:57 +02:00
|
|
|
if (!my_stat(cursor->abs_path, &cursor->statinfo, 0)) {
|
2019-01-14 22:28:23 +01:00
|
|
|
msg(thread_n, "error: cannot stat %s", cursor->abs_path);
|
2017-04-18 20:43:20 +02:00
|
|
|
datafile_close(cursor);
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
posix_fadvise(cursor->file, 0, 0, POSIX_FADV_SEQUENTIAL);
|
|
|
|
|
|
|
|
cursor->buf_size = 10 * 1024 * 1024;
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
cursor->buf = static_cast<byte *>(malloc((ulint)cursor->buf_size));
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static
|
|
|
|
xb_fil_cur_result_t
|
|
|
|
datafile_read(datafile_cur_t *cursor)
|
|
|
|
{
|
|
|
|
ulint to_read;
|
|
|
|
|
|
|
|
xtrabackup_io_throttling();
|
|
|
|
|
2017-04-18 21:05:57 +02:00
|
|
|
to_read = (ulint)MY_MIN(cursor->statinfo.st_size - cursor->buf_offset,
|
2017-04-18 20:43:20 +02:00
|
|
|
cursor->buf_size);
|
|
|
|
|
|
|
|
if (to_read == 0) {
|
|
|
|
return(XB_FIL_CUR_EOF);
|
|
|
|
}
|
|
|
|
|
2019-04-25 15:29:55 +02:00
|
|
|
if (os_file_read(IORequestRead,
|
2022-11-30 09:54:03 +01:00
|
|
|
cursor->file, cursor->buf, cursor->buf_offset,
|
|
|
|
to_read, nullptr) != DB_SUCCESS) {
|
2017-04-18 20:43:20 +02:00
|
|
|
return(XB_FIL_CUR_ERROR);
|
|
|
|
}
|
|
|
|
|
|
|
|
posix_fadvise(cursor->file, cursor->buf_offset, to_read,
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
POSIX_FADV_DONTNEED);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
cursor->buf_read = to_read;
|
|
|
|
cursor->buf_offset += to_read;
|
|
|
|
|
|
|
|
return(XB_FIL_CUR_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Check to see if a file exists.
|
|
|
|
Takes name of the file to check.
|
|
|
|
@return true if file exists. */
|
|
|
|
bool
|
|
|
|
file_exists(const char *filename)
|
|
|
|
{
|
|
|
|
MY_STAT stat_arg;
|
|
|
|
|
|
|
|
if (!my_stat(filename, &stat_arg, MYF(0))) {
|
|
|
|
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Trim leading slashes from absolute path so it becomes relative */
|
|
|
|
const char *
|
|
|
|
trim_dotslash(const char *path)
|
|
|
|
{
|
|
|
|
while (*path) {
|
|
|
|
if (is_path_separator(*path)) {
|
|
|
|
++path;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (*path == '.' && is_path_separator(path[1])) {
|
|
|
|
path += 2;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return(path);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Check if string ends with given suffix.
|
|
|
|
@return true if string ends with given suffix. */
|
|
|
|
bool
|
|
|
|
ends_with(const char *str, const char *suffix)
|
|
|
|
{
|
|
|
|
size_t suffix_len = strlen(suffix);
|
|
|
|
size_t str_len = strlen(str);
|
|
|
|
return(str_len >= suffix_len
|
|
|
|
&& strcmp(str + str_len - suffix_len, suffix) == 0);
|
|
|
|
}
|
|
|
|
|
2023-12-03 13:09:43 +01:00
|
|
|
bool starts_with(const char *str, const char *prefix)
|
2017-04-18 21:05:57 +02:00
|
|
|
{
|
|
|
|
return strncmp(str, prefix, strlen(prefix)) == 0;
|
|
|
|
}
|
|
|
|
|
2017-04-18 20:43:20 +02:00
|
|
|
/************************************************************************
|
|
|
|
Create directories recursively.
|
|
|
|
@return 0 if directories created successfully. */
|
|
|
|
static
|
|
|
|
int
|
|
|
|
mkdirp(const char *pathname, int Flags, myf MyFlags)
|
|
|
|
{
|
2018-06-29 13:00:00 +02:00
|
|
|
char *parent, *p;
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
/* make a parent directory path */
|
2018-08-05 01:36:59 +02:00
|
|
|
if (!(parent= strdup(pathname)))
|
2018-06-29 13:00:00 +02:00
|
|
|
return(-1);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
for (p = parent + strlen(parent);
|
2018-08-08 17:29:35 +02:00
|
|
|
!is_path_separator(*p) && p != parent; p--) ;
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
*p = 0;
|
|
|
|
|
|
|
|
/* try to make parent directory */
|
|
|
|
if (p != parent && mkdirp(parent, Flags, MyFlags) != 0) {
|
2018-06-29 13:00:00 +02:00
|
|
|
free(parent);
|
2017-04-18 20:43:20 +02:00
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* make this one if parent has been made */
|
|
|
|
if (my_mkdir(pathname, Flags, MyFlags) == 0) {
|
2018-06-29 13:00:00 +02:00
|
|
|
free(parent);
|
2017-04-18 20:43:20 +02:00
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if it already exists that is fine */
|
|
|
|
if (errno == EEXIST) {
|
2018-06-29 13:00:00 +02:00
|
|
|
free(parent);
|
2017-04-18 20:43:20 +02:00
|
|
|
return(0);
|
|
|
|
}
|
|
|
|
|
2018-06-29 13:00:00 +02:00
|
|
|
free(parent);
|
2017-04-18 20:43:20 +02:00
|
|
|
return(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Return true if first and second arguments are the same path. */
|
|
|
|
bool
|
|
|
|
equal_paths(const char *first, const char *second)
|
|
|
|
{
|
2017-04-18 21:05:57 +02:00
|
|
|
#ifdef HAVE_REALPATH
|
2018-06-29 13:00:00 +02:00
|
|
|
char *real_first, *real_second;
|
|
|
|
int result;
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2018-06-29 13:00:00 +02:00
|
|
|
real_first = realpath(first, 0);
|
|
|
|
if (real_first == NULL) {
|
2017-04-18 20:43:20 +02:00
|
|
|
return false;
|
|
|
|
}
|
2018-06-29 13:00:00 +02:00
|
|
|
|
|
|
|
real_second = realpath(second, 0);
|
|
|
|
if (real_second == NULL) {
|
|
|
|
free(real_first);
|
2017-04-18 20:43:20 +02:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2018-06-29 13:00:00 +02:00
|
|
|
result = strcmp(real_first, real_second);
|
|
|
|
free(real_first);
|
|
|
|
free(real_second);
|
|
|
|
return result == 0;
|
2017-04-18 21:05:57 +02:00
|
|
|
#else
|
|
|
|
return strcmp(first, second) == 0;
|
|
|
|
#endif
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Check if directory exists. Optionally create directory if doesn't
|
|
|
|
exist.
|
|
|
|
@return true if directory exists and if it was created successfully. */
|
|
|
|
bool
|
|
|
|
directory_exists(const char *dir, bool create)
|
|
|
|
{
|
|
|
|
os_file_dir_t os_dir;
|
|
|
|
MY_STAT stat_arg;
|
|
|
|
char errbuf[MYSYS_STRERROR_SIZE];
|
|
|
|
|
|
|
|
if (my_stat(dir, &stat_arg, MYF(0)) == NULL) {
|
|
|
|
|
|
|
|
if (!create) {
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mkdirp(dir, 0777, MYF(0)) < 0) {
|
2017-04-18 21:05:57 +02:00
|
|
|
my_strerror(errbuf, sizeof(errbuf), my_errno);
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Can not create directory %s: %s", dir, errbuf);
|
2017-04-18 20:43:20 +02:00
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* could be symlink */
|
2021-05-18 11:13:18 +02:00
|
|
|
os_dir = os_file_opendir(dir);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2021-05-18 11:13:18 +02:00
|
|
|
if (os_dir == IF_WIN(INVALID_HANDLE_VALUE, nullptr)) {
|
2017-04-18 21:05:57 +02:00
|
|
|
my_strerror(errbuf, sizeof(errbuf), my_errno);
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Can not open directory %s: %s", dir,
|
2017-04-18 21:05:57 +02:00
|
|
|
errbuf);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
os_file_closedir(os_dir);
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Check that directory exists and it is empty. */
|
|
|
|
static
|
|
|
|
bool
|
|
|
|
directory_exists_and_empty(const char *dir, const char *comment)
|
|
|
|
{
|
|
|
|
os_file_dir_t os_dir;
|
|
|
|
dberr_t err;
|
|
|
|
os_file_stat_t info;
|
|
|
|
bool empty;
|
|
|
|
|
|
|
|
if (!directory_exists(dir, true)) {
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
2021-05-18 11:13:18 +02:00
|
|
|
os_dir = os_file_opendir(dir);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2021-05-18 11:13:18 +02:00
|
|
|
if (os_dir == IF_WIN(INVALID_HANDLE_VALUE, nullptr)) {
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("%s can not open directory %s", comment, dir);
|
2017-04-18 20:43:20 +02:00
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
empty = (fil_file_readdir_next_file(&err, dir, os_dir, &info) != 0);
|
|
|
|
|
|
|
|
os_file_closedir(os_dir);
|
|
|
|
|
|
|
|
if (!empty) {
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("%s directory %s is not empty!", comment, dir);
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return(empty);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Check if file name ends with given set of suffixes.
|
|
|
|
@return true if it does. */
|
|
|
|
bool
|
|
|
|
filename_matches(const char *filename, const char **ext_list)
|
|
|
|
{
|
|
|
|
const char **ext;
|
|
|
|
|
|
|
|
for (ext = ext_list; *ext; ext++) {
|
|
|
|
if (ends_with(filename, *ext)) {
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
2023-12-03 13:09:43 +01:00
|
|
|
// TODO: the code can be used to find storage engine of partitions
|
|
|
|
/*
|
2017-04-18 20:43:20 +02:00
|
|
|
static
|
2023-12-03 13:09:43 +01:00
|
|
|
bool is_aria_frm_or_par(const char *path) {
|
|
|
|
if (!ends_with(path, ".frm") && !ends_with(path, ".par"))
|
|
|
|
return false;
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2023-12-03 13:09:43 +01:00
|
|
|
const char *frm_path = path;
|
|
|
|
if (ends_with(path, ".par")) {
|
|
|
|
size_t frm_path_len = strlen(path);
|
|
|
|
DBUG_ASSERT(frm_path_len > strlen("frm"));
|
|
|
|
frm_path = strdup(path);
|
|
|
|
strcpy(const_cast<char *>(frm_path) + frm_path_len - strlen("frm"), "frm");
|
|
|
|
}
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2023-12-03 13:09:43 +01:00
|
|
|
bool result = false;
|
|
|
|
File file;
|
|
|
|
uchar header[40];
|
|
|
|
legacy_db_type dbt;
|
|
|
|
|
|
|
|
if ((file= mysql_file_open(key_file_frm, frm_path, O_RDONLY | O_SHARE, MYF(0)))
|
|
|
|
< 0)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
if (mysql_file_read(file, (uchar*) header, sizeof(header), MYF(MY_NABP)))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
if (!strncmp((char*) header, "TYPE=VIEW\n", 10))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
if (!is_binary_frm_header(header))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
dbt = (legacy_db_type)header[3];
|
|
|
|
|
|
|
|
if (dbt == DB_TYPE_ARIA) {
|
|
|
|
result = true;
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
2023-12-03 13:09:43 +01:00
|
|
|
else if (dbt == DB_TYPE_PARTITION_DB) {
|
|
|
|
MY_STAT state;
|
|
|
|
uchar *frm_image= 0;
|
|
|
|
// uint n_length;
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2023-12-03 13:09:43 +01:00
|
|
|
if (mysql_file_fstat(file, &state, MYF(MY_WME)))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
if (mysql_file_seek(file, 0, SEEK_SET, MYF(MY_WME)))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
if (read_string(file, &frm_image, (size_t)state.st_size))
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
dbt = (legacy_db_type)frm_image[61];
|
|
|
|
if (dbt == DB_TYPE_ARIA) {
|
|
|
|
result = true;
|
|
|
|
}
|
|
|
|
my_free(frm_image);
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
2023-12-03 13:09:43 +01:00
|
|
|
err:
|
|
|
|
if (file >= 0)
|
|
|
|
mysql_file_close(file, MYF(MY_WME));
|
|
|
|
if (frm_path != path)
|
|
|
|
free(const_cast<char *>(frm_path));
|
|
|
|
return result;
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
2023-12-03 13:09:43 +01:00
|
|
|
*/
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2023-12-03 13:09:43 +01:00
|
|
|
void parse_db_table_from_file_path(
|
|
|
|
const char *filepath, char *dbname, char *tablename) {
|
|
|
|
dbname[0] = '\0';
|
|
|
|
tablename[0] = '\0';
|
|
|
|
const char *dbname_start = nullptr;
|
|
|
|
const char *tablename_start = filepath;
|
|
|
|
const char *const_ptr;
|
|
|
|
while ((const_ptr = strchr(tablename_start, FN_LIBCHAR)) != NULL) {
|
|
|
|
dbname_start = tablename_start;
|
|
|
|
tablename_start = const_ptr + 1;
|
|
|
|
}
|
|
|
|
if (!dbname_start)
|
|
|
|
return;
|
|
|
|
size_t dbname_len = tablename_start - dbname_start - 1;
|
|
|
|
if (dbname_len >= FN_REFLEN)
|
|
|
|
dbname_len = FN_REFLEN-1;
|
|
|
|
strmake(dbname, dbname_start, dbname_len);
|
|
|
|
strmake(tablename, tablename_start, FN_REFLEN-1);
|
|
|
|
char *ptr;
|
|
|
|
if ((ptr = strchr(tablename, '.')))
|
|
|
|
*ptr = '\0';
|
|
|
|
if ((ptr = strstr(tablename, "#P#")))
|
|
|
|
*ptr = '\0';
|
2024-10-26 13:38:45 +02:00
|
|
|
if ((ptr = strstr(tablename, "#i#")))
|
|
|
|
*ptr = '\0';
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
2023-12-03 13:09:43 +01:00
|
|
|
bool is_system_table(const char *dbname, const char *tablename)
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(dbname);
|
|
|
|
DBUG_ASSERT(tablename);
|
|
|
|
|
2024-05-30 15:04:00 +02:00
|
|
|
Lex_ident_db lex_dbname;
|
|
|
|
Lex_ident_table lex_tablename;
|
2023-12-03 13:09:43 +01:00
|
|
|
lex_dbname.str = dbname;
|
|
|
|
lex_dbname.length = strlen(dbname);
|
|
|
|
lex_tablename.str = tablename;
|
|
|
|
lex_tablename.length = strlen(tablename);
|
|
|
|
|
2024-05-30 15:04:00 +02:00
|
|
|
TABLE_CATEGORY tg = get_table_category(lex_dbname, lex_tablename);
|
2023-12-03 13:09:43 +01:00
|
|
|
|
|
|
|
return (tg == TABLE_CATEGORY_LOG) || (tg == TABLE_CATEGORY_SYSTEM);
|
|
|
|
}
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
/************************************************************************
|
2023-12-03 13:09:43 +01:00
|
|
|
Copy data file for backup. Also check if it is allowed to copy by
|
|
|
|
comparing its name to the list of known data file types and checking
|
|
|
|
if passes the rules for partial backup.
|
|
|
|
@return true if file backed up or skipped successfully. */
|
2017-04-18 20:43:20 +02:00
|
|
|
static
|
|
|
|
bool
|
2023-12-03 13:09:43 +01:00
|
|
|
datafile_copy_backup(ds_ctxt *ds_data, const char *filepath, uint thread_n)
|
2017-04-18 20:43:20 +02:00
|
|
|
{
|
2023-12-03 13:09:43 +01:00
|
|
|
const char *ext_list[] = {".frm", ".isl", ".TRG", ".TRN", ".opt", ".par",
|
|
|
|
NULL};
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
/* Get the name and the path for the tablespace. node->name always
|
|
|
|
contains the path (which may be absolute for remote tablespaces in
|
|
|
|
5.6+). space->name contains the tablespace name in the form
|
|
|
|
"./database/table.ibd" (in 5.5-) or "database/table" (in 5.6+). For a
|
|
|
|
multi-node shared tablespace, space->name contains the name of the first
|
|
|
|
node, but that's irrelevant, since we only need node_name to match them
|
|
|
|
against filters, and the shared tablespace is always copied regardless
|
|
|
|
of the filters value. */
|
|
|
|
|
|
|
|
if (check_if_skip_table(filepath)) {
|
2023-12-03 13:09:43 +01:00
|
|
|
msg(thread_n,"Skipping %s.", filepath);
|
2017-04-18 20:43:20 +02:00
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (filename_matches(filepath, ext_list)) {
|
2023-12-03 13:09:43 +01:00
|
|
|
return ds_data->copy_file(filepath, filepath, thread_n);
|
|
|
|
}
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
2023-04-12 09:40:46 +02:00
|
|
|
bool ds_ctxt_t::backup_file_print_buf(const char *filename,
|
|
|
|
const char *buf, int buf_len)
|
2017-04-18 20:43:20 +02:00
|
|
|
{
|
|
|
|
ds_file_t *dstfile = NULL;
|
|
|
|
MY_STAT stat; /* unused for now */
|
|
|
|
const char *action;
|
|
|
|
|
|
|
|
memset(&stat, 0, sizeof(stat));
|
|
|
|
|
|
|
|
stat.st_size = buf_len;
|
|
|
|
stat.st_mtime = my_time(0);
|
|
|
|
|
2023-04-12 09:40:46 +02:00
|
|
|
dstfile = ds_open(this, filename, &stat);
|
2017-04-18 20:43:20 +02:00
|
|
|
if (dstfile == NULL) {
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("error: Can't open the destination stream for %s",
|
|
|
|
filename);
|
2017-04-18 20:43:20 +02:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
action = xb_get_copy_action("Writing");
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("%s %s", action, filename);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
if (buf_len == -1) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ds_write(dstfile, buf, buf_len)) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* close */
|
2019-01-14 22:28:23 +01:00
|
|
|
msg(" ...done");
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
if (ds_close(dstfile)) {
|
|
|
|
goto error_close;
|
|
|
|
}
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
|
|
|
|
error:
|
|
|
|
if (dstfile != NULL) {
|
|
|
|
ds_close(dstfile);
|
|
|
|
}
|
|
|
|
|
|
|
|
error_close:
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Error: backup file failed.");
|
2017-04-18 20:43:20 +02:00
|
|
|
return(false); /*ERROR*/
|
|
|
|
|
MDEV-22929 MariaBackup option to report and/or continue when corruption is encountered
The new option --log-innodb-page-corruption is introduced.
When this option is set, backup is not interrupted if innodb corrupted
page is detected. Instead it logs all found corrupted pages in
innodb_corrupted_pages file in backup directory and finishes with error.
For incremental backup corrupted pages are also copied to .delta file,
because we can't do LSN check for such pages during backup,
innodb_corrupted_pages will also be created in incremental backup
directory.
During --prepare, corrupted pages list is read from the file just after
redo log is applied, and each page from the list is checked if it is allocated
in it's tablespace or not. If it is not allocated, then it is zeroed out,
flushed to the tablespace and removed from the list. If all pages are removed
from the list, then --prepare is finished successfully and
innodb_corrupted_pages file is removed from backup directory. Otherwise
--prepare is finished with error message and innodb_corrupted_pages contains
the list of the pages, which are detected as corrupted during backup, and are
allocated in their tablespaces, what means backup directory contains corrupted
innodb pages, and backup can not be considered as consistent.
For incremental --prepare corrupted pages from .delta files are applied
to the base backup, innodb_corrupted_pages is read from both base in
incremental directories, and the same action is proceded for corrupted
pages list as for full --prepare. innodb_corrupted_pages file is
modified or removed only in base directory.
If DDL happens during backup, it is also processed at the end of backup
to have correct tablespace names in innodb_corrupted_pages.
2020-08-20 15:49:40 +02:00
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
bool
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_ctxt_t::backup_file_vprintf(const char *filename,
|
|
|
|
const char *fmt, va_list ap)
|
MDEV-22929 MariaBackup option to report and/or continue when corruption is encountered
The new option --log-innodb-page-corruption is introduced.
When this option is set, backup is not interrupted if innodb corrupted
page is detected. Instead it logs all found corrupted pages in
innodb_corrupted_pages file in backup directory and finishes with error.
For incremental backup corrupted pages are also copied to .delta file,
because we can't do LSN check for such pages during backup,
innodb_corrupted_pages will also be created in incremental backup
directory.
During --prepare, corrupted pages list is read from the file just after
redo log is applied, and each page from the list is checked if it is allocated
in it's tablespace or not. If it is not allocated, then it is zeroed out,
flushed to the tablespace and removed from the list. If all pages are removed
from the list, then --prepare is finished successfully and
innodb_corrupted_pages file is removed from backup directory. Otherwise
--prepare is finished with error message and innodb_corrupted_pages contains
the list of the pages, which are detected as corrupted during backup, and are
allocated in their tablespaces, what means backup directory contains corrupted
innodb pages, and backup can not be considered as consistent.
For incremental --prepare corrupted pages from .delta files are applied
to the base backup, innodb_corrupted_pages is read from both base in
incremental directories, and the same action is proceded for corrupted
pages list as for full --prepare. innodb_corrupted_pages file is
modified or removed only in base directory.
If DDL happens during backup, it is also processed at the end of backup
to have correct tablespace names in innodb_corrupted_pages.
2020-08-20 15:49:40 +02:00
|
|
|
{
|
|
|
|
char *buf = 0;
|
|
|
|
int buf_len;
|
|
|
|
buf_len = vasprintf(&buf, fmt, ap);
|
|
|
|
bool result = backup_file_print_buf(filename, buf, buf_len);
|
|
|
|
free(buf);
|
|
|
|
return result;
|
|
|
|
}
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
bool
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_ctxt_t::backup_file_printf(const char *filename, const char *fmt, ...)
|
2017-04-18 20:43:20 +02:00
|
|
|
{
|
|
|
|
bool result;
|
|
|
|
va_list ap;
|
|
|
|
|
|
|
|
va_start(ap, fmt);
|
|
|
|
|
|
|
|
result = backup_file_vprintf(filename, fmt, ap);
|
|
|
|
|
|
|
|
va_end(ap);
|
|
|
|
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static
|
|
|
|
bool
|
2021-03-17 08:03:06 +01:00
|
|
|
run_data_threads(datadir_iter_t *it, void (*func)(datadir_thread_ctxt_t *ctxt), uint n)
|
2017-04-18 20:43:20 +02:00
|
|
|
{
|
|
|
|
datadir_thread_ctxt_t *data_threads;
|
|
|
|
uint i, count;
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
pthread_mutex_t count_mutex;
|
2017-04-18 20:43:20 +02:00
|
|
|
bool ret;
|
|
|
|
|
|
|
|
data_threads = (datadir_thread_ctxt_t*)
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
malloc(sizeof(datadir_thread_ctxt_t) * n);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
pthread_mutex_init(&count_mutex, NULL);
|
2017-04-18 20:43:20 +02:00
|
|
|
count = n;
|
|
|
|
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
data_threads[i].it = it;
|
|
|
|
data_threads[i].n_thread = i + 1;
|
|
|
|
data_threads[i].count = &count;
|
2018-09-20 20:27:59 +02:00
|
|
|
data_threads[i].count_mutex = &count_mutex;
|
2021-03-17 08:03:06 +01:00
|
|
|
std::thread(func, data_threads + i).detach();
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Wait for threads to exit */
|
|
|
|
while (1) {
|
2021-03-16 14:09:41 +01:00
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
pthread_mutex_lock(&count_mutex);
|
2017-04-18 20:43:20 +02:00
|
|
|
if (count == 0) {
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
pthread_mutex_unlock(&count_mutex);
|
2017-04-18 20:43:20 +02:00
|
|
|
break;
|
|
|
|
}
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
pthread_mutex_unlock(&count_mutex);
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
pthread_mutex_destroy(&count_mutex);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
ret = true;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
ret = data_threads[i].ret && ret;
|
|
|
|
if (!data_threads[i].ret) {
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Error: thread %u failed.", i);
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
free(data_threads);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Copy file for backup/restore.
|
|
|
|
@return true in case of success. */
|
|
|
|
bool
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_ctxt_t::copy_file(const char *src_file_path,
|
|
|
|
const char *dst_file_path,
|
2023-12-03 13:09:43 +01:00
|
|
|
uint thread_n,
|
|
|
|
bool rewrite)
|
2017-04-18 20:43:20 +02:00
|
|
|
{
|
|
|
|
char dst_name[FN_REFLEN];
|
|
|
|
ds_file_t *dstfile = NULL;
|
|
|
|
datafile_cur_t cursor;
|
|
|
|
xb_fil_cur_result_t res;
|
2023-04-12 09:40:46 +02:00
|
|
|
DBUG_ASSERT(datasink->remove);
|
2023-12-03 13:09:43 +01:00
|
|
|
const char *dst_path = convert_dst(dst_file_path);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
if (!datafile_open(src_file_path, &cursor, thread_n)) {
|
2017-04-21 00:50:53 +02:00
|
|
|
goto error_close;
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
strncpy(dst_name, cursor.rel_path, sizeof(dst_name));
|
|
|
|
|
2023-12-03 13:09:43 +01:00
|
|
|
dstfile = ds_open(this, dst_path, &cursor.statinfo, rewrite);
|
2017-04-18 20:43:20 +02:00
|
|
|
if (dstfile == NULL) {
|
2019-01-14 22:28:23 +01:00
|
|
|
msg(thread_n,"error: "
|
|
|
|
"cannot open the destination stream for %s", dst_name);
|
2017-04-18 20:43:20 +02:00
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
2019-01-14 22:28:23 +01:00
|
|
|
msg(thread_n, "%s %s to %s", xb_get_copy_action(), src_file_path, dstfile->path);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
/* The main copy loop */
|
|
|
|
while ((res = datafile_read(&cursor)) == XB_FIL_CUR_SUCCESS) {
|
|
|
|
|
|
|
|
if (ds_write(dstfile, cursor.buf, cursor.buf_read)) {
|
|
|
|
goto error;
|
|
|
|
}
|
2021-03-31 14:23:56 +02:00
|
|
|
DBUG_EXECUTE_IF("copy_file_error", errno=ENOSPC;goto error;);
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (res == XB_FIL_CUR_ERROR) {
|
|
|
|
goto error;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* close */
|
2019-01-14 22:28:23 +01:00
|
|
|
msg(thread_n," ...done");
|
2017-04-18 20:43:20 +02:00
|
|
|
datafile_close(&cursor);
|
|
|
|
if (ds_close(dstfile)) {
|
|
|
|
goto error_close;
|
|
|
|
}
|
|
|
|
return(true);
|
|
|
|
|
|
|
|
error:
|
|
|
|
datafile_close(&cursor);
|
|
|
|
if (dstfile != NULL) {
|
2023-04-12 09:40:46 +02:00
|
|
|
datasink->remove(dstfile->path);
|
2017-04-18 20:43:20 +02:00
|
|
|
ds_close(dstfile);
|
|
|
|
}
|
|
|
|
|
|
|
|
error_close:
|
2019-01-14 22:28:23 +01:00
|
|
|
msg(thread_n,"Error: copy_file() failed.");
|
2017-04-18 20:43:20 +02:00
|
|
|
return(false); /*ERROR*/
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Try to move file by renaming it. If source and destination are on
|
|
|
|
different devices fall back to copy and unlink.
|
|
|
|
@return true in case of success. */
|
|
|
|
bool
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_ctxt_t::move_file(const char *src_file_path,
|
|
|
|
const char *dst_file_path,
|
|
|
|
const char *dst_dir, uint thread_n)
|
2017-04-18 20:43:20 +02:00
|
|
|
{
|
|
|
|
char errbuf[MYSYS_STRERROR_SIZE];
|
|
|
|
char dst_file_path_abs[FN_REFLEN];
|
|
|
|
char dst_dir_abs[FN_REFLEN];
|
|
|
|
size_t dirname_length;
|
|
|
|
|
2017-11-11 22:07:24 +01:00
|
|
|
snprintf(dst_file_path_abs, sizeof(dst_file_path_abs),
|
|
|
|
"%s/%s", dst_dir, dst_file_path);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
dirname_part(dst_dir_abs, dst_file_path_abs, &dirname_length);
|
|
|
|
|
|
|
|
if (!directory_exists(dst_dir_abs, true)) {
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (file_exists(dst_file_path_abs)) {
|
|
|
|
msg("Error: Move file %s to %s failed: Destination "
|
2019-01-14 22:28:23 +01:00
|
|
|
"file exists", src_file_path, dst_file_path_abs);
|
2017-04-18 20:43:20 +02:00
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
2019-01-14 22:28:23 +01:00
|
|
|
msg(thread_n,"Moving %s to %s", src_file_path, dst_file_path_abs);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
if (my_rename(src_file_path, dst_file_path_abs, MYF(0)) != 0) {
|
|
|
|
if (my_errno == EXDEV) {
|
2021-03-31 14:23:56 +02:00
|
|
|
/* Fallback to copy/unlink */
|
2023-04-12 09:40:46 +02:00
|
|
|
if(!copy_file(src_file_path,
|
2021-03-31 14:23:56 +02:00
|
|
|
dst_file_path, thread_n))
|
|
|
|
return false;
|
2019-01-14 22:28:23 +01:00
|
|
|
msg(thread_n,"Removing %s", src_file_path);
|
2017-04-18 20:43:20 +02:00
|
|
|
if (unlink(src_file_path) != 0) {
|
2017-04-18 21:05:57 +02:00
|
|
|
my_strerror(errbuf, sizeof(errbuf), errno);
|
2021-03-31 14:23:56 +02:00
|
|
|
msg("Warning: unlink %s failed: %s",
|
2017-04-18 20:43:20 +02:00
|
|
|
src_file_path,
|
2017-04-18 21:05:57 +02:00
|
|
|
errbuf);
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
2021-03-31 14:23:56 +02:00
|
|
|
return true;
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
2017-04-18 21:05:57 +02:00
|
|
|
my_strerror(errbuf, sizeof(errbuf), my_errno);
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Can not move file %s to %s: %s",
|
2017-04-18 20:43:20 +02:00
|
|
|
src_file_path, dst_file_path_abs,
|
2017-04-18 21:05:57 +02:00
|
|
|
errbuf);
|
2017-04-18 20:43:20 +02:00
|
|
|
return(false);
|
|
|
|
}
|
2019-01-14 22:28:23 +01:00
|
|
|
msg(thread_n," ...done");
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Read link from .isl file if any and store it in the global map associated
|
|
|
|
with given tablespace. */
|
|
|
|
static
|
|
|
|
void
|
|
|
|
read_link_file(const char *ibd_filepath, const char *link_filepath)
|
|
|
|
{
|
|
|
|
char *filepath= NULL;
|
|
|
|
|
|
|
|
FILE *file = fopen(link_filepath, "r+b");
|
|
|
|
if (file) {
|
|
|
|
filepath = static_cast<char*>(malloc(OS_FILE_MAX_PATH));
|
|
|
|
|
|
|
|
os_file_read_string(file, filepath, OS_FILE_MAX_PATH);
|
|
|
|
fclose(file);
|
|
|
|
|
MDEV-25312 Replace fil_space_t::name with fil_space_t::name()
A consistency check for fil_space_t::name is causing recovery failures
in MDEV-25180 (Atomic ALTER TABLE). So, we'd better remove that field
altogether.
fil_space_t::name was more or less a copy of dict_table_t::name
(except for some special cases), and it was not being used for
anything useful.
There used to be a name_hash, but it had been removed already in
commit a75dbfd7183cc96680f3e3e684fd36500dac8158 (MDEV-12266).
We will also remove os_normalize_path(), OS_PATH_SEPARATOR,
OS_PATH_SEPATOR_ALT. On Microsoft Windows, we will treat \ and /
roughly in the same way. The intention is that for per-table
tablespaces, the filenames will always follow the pattern
prefix/databasename/tablename.ibd. (Any \ in the prefix must not
be converted.)
ut_basename_noext(): Remove (unused function).
read_link_file(): Replaces RemoteDatafile::read_link_file().
We will ensure that the last two path component separators are
forward slashes (converting up to 2 trailing backslashes on
Microsoft Windows), so that everywhere else we can
assume that data file names end in "/databasename/tablename.ibd".
Note: On Microsoft Windows, path names that start with \\?\ must
not contain / as path component separators. Previously, such paths
did work in the DATA DIRECTORY argument of InnoDB tables.
Reviewed by: Vladislav Vaintroub
2021-04-07 17:01:13 +02:00
|
|
|
if (size_t len = strlen(filepath)) {
|
2017-04-18 20:43:20 +02:00
|
|
|
/* Trim whitespace from end of filepath */
|
MDEV-25312 Replace fil_space_t::name with fil_space_t::name()
A consistency check for fil_space_t::name is causing recovery failures
in MDEV-25180 (Atomic ALTER TABLE). So, we'd better remove that field
altogether.
fil_space_t::name was more or less a copy of dict_table_t::name
(except for some special cases), and it was not being used for
anything useful.
There used to be a name_hash, but it had been removed already in
commit a75dbfd7183cc96680f3e3e684fd36500dac8158 (MDEV-12266).
We will also remove os_normalize_path(), OS_PATH_SEPARATOR,
OS_PATH_SEPATOR_ALT. On Microsoft Windows, we will treat \ and /
roughly in the same way. The intention is that for per-table
tablespaces, the filenames will always follow the pattern
prefix/databasename/tablename.ibd. (Any \ in the prefix must not
be converted.)
ut_basename_noext(): Remove (unused function).
read_link_file(): Replaces RemoteDatafile::read_link_file().
We will ensure that the last two path component separators are
forward slashes (converting up to 2 trailing backslashes on
Microsoft Windows), so that everywhere else we can
assume that data file names end in "/databasename/tablename.ibd".
Note: On Microsoft Windows, path names that start with \\?\ must
not contain / as path component separators. Previously, such paths
did work in the DATA DIRECTORY argument of InnoDB tables.
Reviewed by: Vladislav Vaintroub
2021-04-07 17:01:13 +02:00
|
|
|
ulint lastch = len - 1;
|
2017-04-18 20:43:20 +02:00
|
|
|
while (lastch > 4 && filepath[lastch] <= 0x20) {
|
|
|
|
filepath[lastch--] = 0x00;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tablespace_locations[ibd_filepath] = filepath;
|
|
|
|
}
|
|
|
|
free(filepath);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Return the location of given .ibd if it was previously read
|
|
|
|
from .isl file.
|
|
|
|
@return NULL or destination .ibd file path. */
|
|
|
|
static
|
|
|
|
const char *
|
|
|
|
tablespace_filepath(const char *ibd_filepath)
|
|
|
|
{
|
|
|
|
std::map<std::string, std::string>::iterator it;
|
|
|
|
|
|
|
|
it = tablespace_locations.find(ibd_filepath);
|
|
|
|
|
|
|
|
if (it != tablespace_locations.end()) {
|
|
|
|
return it->second.c_str();
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/************************************************************************
|
|
|
|
Copy or move file depending on current mode.
|
|
|
|
@return true in case of success. */
|
|
|
|
static
|
|
|
|
bool
|
2023-04-12 09:40:46 +02:00
|
|
|
copy_or_move_file(ds_ctxt *datasink0, const char *src_file_path,
|
2017-04-18 20:43:20 +02:00
|
|
|
const char *dst_file_path,
|
|
|
|
const char *dst_dir,
|
2018-06-07 16:13:54 +02:00
|
|
|
uint thread_n,
|
|
|
|
bool copy = xtrabackup_copy_back)
|
2017-04-18 20:43:20 +02:00
|
|
|
{
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_ctxt_t *datasink = datasink0; /* copy to datadir by default */
|
2017-04-18 20:43:20 +02:00
|
|
|
char filedir[FN_REFLEN];
|
|
|
|
size_t filedir_len;
|
|
|
|
bool ret;
|
|
|
|
|
|
|
|
/* read the link from .isl file */
|
|
|
|
if (ends_with(src_file_path, ".isl")) {
|
|
|
|
char *ibd_filepath;
|
|
|
|
|
|
|
|
ibd_filepath = strdup(src_file_path);
|
|
|
|
strcpy(ibd_filepath + strlen(ibd_filepath) - 3, "ibd");
|
|
|
|
|
|
|
|
read_link_file(ibd_filepath, src_file_path);
|
|
|
|
|
|
|
|
free(ibd_filepath);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* check if there is .isl file */
|
|
|
|
if (ends_with(src_file_path, ".ibd")) {
|
|
|
|
char *link_filepath;
|
|
|
|
const char *filepath;
|
|
|
|
|
|
|
|
link_filepath = strdup(src_file_path);
|
|
|
|
strcpy(link_filepath + strlen(link_filepath) - 3, "isl");
|
|
|
|
|
|
|
|
read_link_file(src_file_path, link_filepath);
|
|
|
|
|
|
|
|
filepath = tablespace_filepath(src_file_path);
|
|
|
|
|
|
|
|
if (filepath != NULL) {
|
|
|
|
dirname_part(filedir, filepath, &filedir_len);
|
|
|
|
|
|
|
|
dst_file_path = filepath + filedir_len;
|
|
|
|
dst_dir = filedir;
|
|
|
|
|
|
|
|
if (!directory_exists(dst_dir, true)) {
|
|
|
|
ret = false;
|
2018-11-29 15:28:03 +01:00
|
|
|
free(link_filepath);
|
2017-04-18 20:43:20 +02:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
|
|
|
|
datasink = ds_create(dst_dir, DS_TYPE_LOCAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(link_filepath);
|
|
|
|
}
|
|
|
|
|
2018-06-07 16:13:54 +02:00
|
|
|
ret = (copy ?
|
2023-04-12 09:40:46 +02:00
|
|
|
datasink->copy_file(src_file_path, dst_file_path, thread_n) :
|
|
|
|
datasink->move_file(src_file_path, dst_file_path,
|
2017-04-18 20:43:20 +02:00
|
|
|
dst_dir, thread_n));
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
|
2023-04-12 09:40:46 +02:00
|
|
|
if (datasink != datasink0) {
|
2017-04-18 20:43:20 +02:00
|
|
|
ds_destroy(datasink);
|
|
|
|
}
|
|
|
|
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
2023-12-03 13:09:43 +01:00
|
|
|
backup_files(ds_ctxt *ds_data, const char *from)
|
2017-04-18 20:43:20 +02:00
|
|
|
{
|
|
|
|
datadir_iter_t *it;
|
|
|
|
datadir_node_t node;
|
|
|
|
bool ret = true;
|
2023-12-03 13:09:43 +01:00
|
|
|
msg("Starting to backup non-InnoDB tables and files");
|
2017-04-18 20:43:20 +02:00
|
|
|
datadir_node_init(&node);
|
|
|
|
it = datadir_iter_new(from);
|
|
|
|
while (datadir_iter_next(it, &node)) {
|
|
|
|
if (!node.is_empty_dir) {
|
2023-12-03 13:09:43 +01:00
|
|
|
ret = datafile_copy_backup(ds_data, node.filepath, 1);
|
2017-04-18 20:43:20 +02:00
|
|
|
if (!ret) {
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Failed to copy file %s", node.filepath);
|
2017-04-18 20:43:20 +02:00
|
|
|
goto out;
|
|
|
|
}
|
2023-12-03 13:09:43 +01:00
|
|
|
} else {
|
2017-04-18 20:43:20 +02:00
|
|
|
/* backup fake file into empty directory */
|
|
|
|
char path[FN_REFLEN];
|
2023-12-03 13:09:43 +01:00
|
|
|
snprintf(path, sizeof(path), "%s/db.opt", node.filepath);
|
|
|
|
if (!(ret = ds_data->backup_file_printf(trim_dotslash(path), "%s", ""))) {
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Failed to create file %s", path);
|
2017-04-18 20:43:20 +02:00
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-12-03 13:09:43 +01:00
|
|
|
msg("Finished backing up non-InnoDB tables and files");
|
2017-04-18 20:43:20 +02:00
|
|
|
out:
|
|
|
|
datadir_iter_free(it);
|
|
|
|
datadir_node_free(&node);
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
2024-04-22 15:27:14 +02:00
|
|
|
/** Release resources after backup_files() */
|
2017-08-18 13:42:18 +02:00
|
|
|
void backup_release()
|
2017-04-18 20:43:20 +02:00
|
|
|
{
|
2018-03-30 00:13:01 +02:00
|
|
|
if (opt_lock_ddl_per_table) {
|
|
|
|
mdl_unlock_all();
|
|
|
|
}
|
|
|
|
|
2017-04-18 20:43:20 +02:00
|
|
|
if (opt_safe_slave_backup && sql_thread_started) {
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Starting slave SQL thread");
|
2017-04-18 20:43:20 +02:00
|
|
|
xb_mysql_query(mysql_connection,
|
|
|
|
"START SLAVE SQL_THREAD", false);
|
|
|
|
}
|
2017-08-18 13:42:18 +02:00
|
|
|
}
|
2017-04-18 20:43:20 +02:00
|
|
|
|
MDEV-27524: Incorrect binlogs after Galera SST using rsync and mariabackup
This commit adds correct handling of binlogs for SST using rsync
or mariabackup. Before this fix, binlogs were handled incorrectly -
- only one (last) binary log file was transferred during SST, which
then led to various failures (for example, when trying to list all
events from the binary log). These bugs were long masked by flaws
in the primitive binlogs handling code in the SST scripts, which
causing binary logs files to be erased after transfer or not added
to the binlog index on the joiner node. Now the correct transfer
of all binary logs (not just the last of the binary log files) has
been implemented both for the rsync (at the script level) and for
the mariabackup (at the level of the main utility code).
This commit also adds a new sst_max_binlogs=<n> parameter, which
can be located in the [sst] section or in the [xtrabackup] section
(historically, supported for mariabackup only, not for rsync), or
in one of the server sections. This parameter specifies the number
of binary log files to be sent to the joiner node during SST. This
option is added for compatibility with old SST scripting behavior,
which can be emulated by setting the sst_max_binlogs=1 (although
in general this can cause problems for the reasons described above).
In addition, setting the sst_max_binlogs=0 can be used to suppress
the transmission of binary logs to the joiner nodes during SST
(although sometimes a single file with the current binary log can
still be transmitted to the joiner, even with sst_max_binlogs=0,
because this sometimes necessary in modes that involve the use of
GTIDs with Galera).
Also, this commit ensures correct handling of paths to various
innodb files and directories in the SST scripts, and fixes some
problems with this that existed in mariabackup utility (which
were associated with incorrect handling of the innodb_data_dir
parameter in some scenarios).
In addition, this commit contains the following enhancements:
1) Added tests for mtr, which check the correct work with binlogs
after SST (using rsync and mariabackup);
2) Added correct handling of slashes at the end of all paths that
the SST script receives as parameters;
3) Improved parsing code for --mysqld-args parameters. Now it
correctly processes the sequence "--" after the name of the
one-letter option;
4) Checking the secret signature during joiner authentication
is made independent of presence of bash (as a unix shell)
in the system and diff utility no longer needed to check
certificates compliance;
5) All directories that are necessary for the correct placement
of various logs are automatically created by SST scripts in
advance (before running mariabackup on the joiner node);
6) Removal of old binary logs on joiner is done using the binlog
index (if it exists) (not only by fixed pattern that based
on the current binlog name, as before);
7) Paths for placing binary logs are correctly processed if they
are set as relative paths (to the datadir);
8) SST scripts are made even more resistant to spaces in filenames
(now for binlogs);
9) In case of failure, SST scripts now always end with an exit
code other than zero;
10) SST script for rsync now correctly create a tar file with
the binlogs, even if the paths to them (in the binlog index
file) are specified as a mix of absolute and relative paths,
and even if they do not match with the datadir path specified
in the current configuration settings.
2022-02-22 10:45:06 +01:00
|
|
|
static const char *default_buffer_pool_file = "ib_buffer_pool";
|
|
|
|
|
2024-04-22 15:27:14 +02:00
|
|
|
/** Finish after backup_files() and backup_release() */
|
2023-04-12 09:40:46 +02:00
|
|
|
bool backup_finish(ds_ctxt *ds_data)
|
2017-08-18 13:42:18 +02:00
|
|
|
{
|
2017-04-18 20:43:20 +02:00
|
|
|
/* Copy buffer pool dump or LRU dump */
|
2023-12-03 13:09:43 +01:00
|
|
|
if (opt_galera_info) {
|
2017-04-18 20:43:20 +02:00
|
|
|
if (buffer_pool_filename && file_exists(buffer_pool_filename)) {
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_data->copy_file(buffer_pool_filename, default_buffer_pool_file, 0);
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
if (file_exists("ib_lru_dump")) {
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_data->copy_file("ib_lru_dump", "ib_lru_dump", 0);
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-07 16:13:54 +02:00
|
|
|
if (has_rocksdb_plugin()) {
|
2023-04-12 09:40:46 +02:00
|
|
|
rocksdb_backup_checkpoint(ds_data);
|
2018-06-07 16:13:54 +02:00
|
|
|
}
|
|
|
|
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Backup created in directory '%s'", xtrabackup_target_dir);
|
2017-04-18 20:43:20 +02:00
|
|
|
if (mysql_binlog_position != NULL) {
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("MySQL binlog position: %s", mysql_binlog_position);
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
if (mysql_slave_position && opt_slave_info) {
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("MySQL slave binlog position: %s",
|
2017-04-18 20:43:20 +02:00
|
|
|
mysql_slave_position);
|
|
|
|
}
|
|
|
|
|
2023-04-12 09:40:46 +02:00
|
|
|
if (!write_backup_config_file(ds_data)) {
|
2017-04-18 20:43:20 +02:00
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
2023-06-05 20:13:06 +02:00
|
|
|
if (!write_xtrabackup_info(ds_data, mysql_connection, MB_INFO,
|
2019-05-27 13:52:27 +02:00
|
|
|
opt_history != 0, true)) {
|
2017-04-18 20:43:20 +02:00
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
2022-11-09 13:41:19 +01:00
|
|
|
|
|
|
|
/*
|
|
|
|
Drop all empty database directories in the base backup
|
|
|
|
that do not exists in the icremental backup.
|
|
|
|
|
|
|
|
This effectively re-plays all DROP DATABASE statements happened
|
|
|
|
in between base backup and incremental backup creation time.
|
|
|
|
|
|
|
|
Note, only checking if base_dir/db/ is empty is not enough,
|
|
|
|
because inc_dir/db/db.opt might have been dropped for some reasons,
|
|
|
|
which may also result into empty base_dir/db/.
|
|
|
|
|
|
|
|
Only the fact that at the same time:
|
|
|
|
- base_dir/db/ exists
|
|
|
|
- inc_dir/db/ does not exist
|
|
|
|
means that DROP DATABASE happened.
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
ibx_incremental_drop_databases(const char *base_dir,
|
|
|
|
const char *inc_dir)
|
|
|
|
{
|
|
|
|
datadir_node_t node;
|
|
|
|
datadir_node_init(&node);
|
|
|
|
datadir_iter_t *it = datadir_iter_new(base_dir);
|
|
|
|
|
|
|
|
while (datadir_iter_next(it, &node)) {
|
|
|
|
if (node.is_empty_dir) {
|
|
|
|
char path[FN_REFLEN];
|
|
|
|
snprintf(path, sizeof(path), "%s/%s",
|
|
|
|
inc_dir, node.filepath_rel);
|
|
|
|
if (!directory_exists(path, false)) {
|
|
|
|
msg("Removing %s", node.filepath);
|
|
|
|
rmdir(node.filepath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
datadir_iter_free(it);
|
|
|
|
datadir_node_free(&node);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool
|
2017-04-18 20:43:20 +02:00
|
|
|
ibx_copy_incremental_over_full()
|
|
|
|
{
|
|
|
|
const char *ext_list[] = {"frm", "isl", "MYD", "MYI", "MAD", "MAI",
|
|
|
|
"MRG", "TRG", "TRN", "ARM", "ARZ", "CSM", "CSV", "opt", "par",
|
|
|
|
NULL};
|
2023-02-03 04:42:59 +01:00
|
|
|
const char *sup_files[] = {MB_BINLOG_INFO,
|
|
|
|
MB_GALERA_INFO,
|
2024-01-05 12:05:30 +01:00
|
|
|
XTRABACKUP_DONOR_GALERA_INFO,
|
2023-02-03 04:42:59 +01:00
|
|
|
MB_SLAVE_INFO,
|
|
|
|
MB_INFO,
|
|
|
|
XTRABACKUP_BINLOG_INFO,
|
|
|
|
XTRABACKUP_GALERA_INFO,
|
|
|
|
XTRABACKUP_SLAVE_INFO,
|
|
|
|
XTRABACKUP_INFO,
|
2017-04-18 20:43:20 +02:00
|
|
|
"ib_lru_dump",
|
|
|
|
NULL};
|
|
|
|
datadir_iter_t *it = NULL;
|
|
|
|
datadir_node_t node;
|
|
|
|
bool ret = true;
|
|
|
|
char path[FN_REFLEN];
|
|
|
|
int i;
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_ctxt *ds_data= NULL;
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2022-06-28 09:42:45 +02:00
|
|
|
DBUG_ASSERT(!opt_galera_info);
|
2017-04-18 20:43:20 +02:00
|
|
|
datadir_node_init(&node);
|
|
|
|
|
|
|
|
/* If we were applying an incremental change set, we need to make
|
|
|
|
sure non-InnoDB files and xtrabackup_* metainfo files are copied
|
|
|
|
to the full backup directory. */
|
|
|
|
|
|
|
|
if (xtrabackup_incremental) {
|
|
|
|
|
|
|
|
ds_data = ds_create(xtrabackup_target_dir, DS_TYPE_LOCAL);
|
|
|
|
|
|
|
|
it = datadir_iter_new(xtrabackup_incremental_dir);
|
|
|
|
|
|
|
|
while (datadir_iter_next(it, &node)) {
|
|
|
|
|
|
|
|
/* copy only non-innodb files */
|
|
|
|
|
|
|
|
if (node.is_empty_dir
|
|
|
|
|| !filename_matches(node.filepath, ext_list)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (file_exists(node.filepath_rel)) {
|
|
|
|
unlink(node.filepath_rel);
|
|
|
|
}
|
|
|
|
|
2023-04-12 09:40:46 +02:00
|
|
|
if (!(ret = ds_data->copy_file(node.filepath,
|
|
|
|
node.filepath_rel, 1))) {
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Failed to copy file %s",
|
2017-04-18 20:43:20 +02:00
|
|
|
node.filepath);
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-13 13:42:53 +02:00
|
|
|
if (!(ret = backup_files_from_datadir(ds_data,
|
|
|
|
xtrabackup_incremental_dir,
|
|
|
|
"aws-kms-key")) ||
|
|
|
|
!(ret = backup_files_from_datadir(ds_data,
|
|
|
|
xtrabackup_incremental_dir,
|
|
|
|
"aria_log")))
|
2019-11-20 19:27:30 +01:00
|
|
|
goto cleanup;
|
|
|
|
|
2017-04-18 20:43:20 +02:00
|
|
|
/* copy supplementary files */
|
|
|
|
|
|
|
|
for (i = 0; sup_files[i]; i++) {
|
|
|
|
snprintf(path, sizeof(path), "%s/%s",
|
|
|
|
xtrabackup_incremental_dir,
|
|
|
|
sup_files[i]);
|
|
|
|
|
|
|
|
if (file_exists(path))
|
|
|
|
{
|
|
|
|
if (file_exists(sup_files[i])) {
|
|
|
|
unlink(sup_files[i]);
|
|
|
|
}
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_data->copy_file(path, sup_files[i], 0);
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-19 07:31:25 +01:00
|
|
|
if (directory_exists(ROCKSDB_BACKUP_DIR, false)) {
|
|
|
|
if (my_rmtree(ROCKSDB_BACKUP_DIR, MYF(0))) {
|
|
|
|
die("Can't remove " ROCKSDB_BACKUP_DIR);
|
|
|
|
}
|
2019-02-18 18:56:32 +01:00
|
|
|
}
|
2019-02-19 07:31:25 +01:00
|
|
|
snprintf(path, sizeof(path), "%s/" ROCKSDB_BACKUP_DIR, xtrabackup_incremental_dir);
|
|
|
|
if (directory_exists(path, false)) {
|
|
|
|
if (my_mkdir(ROCKSDB_BACKUP_DIR, 0777, MYF(0))) {
|
|
|
|
die("my_mkdir failed for " ROCKSDB_BACKUP_DIR);
|
|
|
|
}
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_data->copy_or_move_dir(path, ROCKSDB_BACKUP_DIR, true, true);
|
2019-02-18 18:56:32 +01:00
|
|
|
}
|
2022-11-09 13:41:19 +01:00
|
|
|
ibx_incremental_drop_databases(xtrabackup_target_dir,
|
|
|
|
xtrabackup_incremental_dir);
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
2019-02-19 07:31:25 +01:00
|
|
|
|
2017-04-18 20:43:20 +02:00
|
|
|
cleanup:
|
|
|
|
if (it != NULL) {
|
|
|
|
datadir_iter_free(it);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ds_data != NULL) {
|
|
|
|
ds_destroy(ds_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
datadir_node_free(&node);
|
|
|
|
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ibx_cleanup_full_backup()
|
|
|
|
{
|
|
|
|
const char *ext_list[] = {"delta", "meta", "ibd", NULL};
|
|
|
|
datadir_iter_t *it = NULL;
|
|
|
|
datadir_node_t node;
|
|
|
|
bool ret = true;
|
|
|
|
|
|
|
|
datadir_node_init(&node);
|
|
|
|
|
|
|
|
/* If we are applying an incremental change set, we need to make
|
|
|
|
sure non-InnoDB files are cleaned up from full backup dir before
|
|
|
|
we copy files from incremental dir. */
|
|
|
|
|
|
|
|
it = datadir_iter_new(xtrabackup_target_dir);
|
|
|
|
|
|
|
|
while (datadir_iter_next(it, &node)) {
|
|
|
|
|
|
|
|
if (node.is_empty_dir) {
|
2017-04-18 21:05:57 +02:00
|
|
|
#ifdef _WIN32
|
|
|
|
DeleteFile(node.filepath);
|
|
|
|
#else
|
2017-04-18 20:43:20 +02:00
|
|
|
rmdir(node.filepath);
|
2017-04-18 21:05:57 +02:00
|
|
|
#endif
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (xtrabackup_incremental && !node.is_empty_dir
|
|
|
|
&& !filename_matches(node.filepath, ext_list)) {
|
|
|
|
unlink(node.filepath);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
datadir_iter_free(it);
|
|
|
|
|
|
|
|
datadir_node_free(&node);
|
|
|
|
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
apply_log_finish()
|
|
|
|
{
|
|
|
|
if (!ibx_cleanup_full_backup()
|
|
|
|
|| !ibx_copy_incremental_over_full()) {
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
2023-03-17 16:51:33 +01:00
|
|
|
class Copy_back_dst_dir
|
|
|
|
{
|
|
|
|
std::string buf;
|
|
|
|
|
|
|
|
public:
|
|
|
|
const char *make(const char *path)
|
|
|
|
{
|
|
|
|
if (!path || !path[0])
|
|
|
|
return mysql_data_home;
|
|
|
|
if (is_absolute_path(path))
|
|
|
|
return path;
|
|
|
|
return buf.assign(mysql_data_home).append(path).c_str();
|
|
|
|
}
|
|
|
|
};
|
2020-04-28 01:06:11 +02:00
|
|
|
|
2023-04-13 13:42:53 +02:00
|
|
|
|
|
|
|
static inline bool
|
|
|
|
is_aria_log_dir_file(const datadir_node_t &node)
|
|
|
|
{
|
|
|
|
return starts_with(node.filepath_rel, "aria_log");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool
|
2023-04-24 08:27:55 +02:00
|
|
|
copy_back_aria_logs(const char *dstdir)
|
2023-04-13 13:42:53 +02:00
|
|
|
{
|
2024-10-03 07:15:48 +02:00
|
|
|
std::unique_ptr<ds_ctxt_t, std::function<void(ds_ctxt_t*)>>
|
2023-04-13 13:42:53 +02:00
|
|
|
ds_ctxt_aria_log_dir_path(ds_create(dstdir, DS_TYPE_LOCAL), ds_destroy);
|
|
|
|
|
|
|
|
datadir_node_t node;
|
|
|
|
datadir_node_init(&node);
|
|
|
|
datadir_iter_t *it = datadir_iter_new(".", false);
|
|
|
|
|
|
|
|
while (datadir_iter_next(it, &node))
|
|
|
|
{
|
|
|
|
if (!is_aria_log_dir_file(node))
|
|
|
|
continue;
|
|
|
|
if (!copy_or_move_file(ds_ctxt_aria_log_dir_path.get(),
|
|
|
|
node.filepath, node.filepath_rel,
|
|
|
|
dstdir, 1))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
datadir_node_free(&node);
|
|
|
|
datadir_iter_free(it);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2020-04-28 01:06:11 +02:00
|
|
|
|
2017-04-18 20:43:20 +02:00
|
|
|
bool
|
|
|
|
copy_back()
|
|
|
|
{
|
2020-08-11 14:48:58 +02:00
|
|
|
bool ret = false;
|
2017-04-18 20:43:20 +02:00
|
|
|
datadir_iter_t *it = NULL;
|
|
|
|
datadir_node_t node;
|
2023-03-17 16:51:33 +01:00
|
|
|
const char *dst_dir;
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
memset(&node, 0, sizeof(node));
|
|
|
|
|
|
|
|
if (!opt_force_non_empty_dirs) {
|
|
|
|
if (!directory_exists_and_empty(mysql_data_home,
|
|
|
|
"Original data")) {
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!directory_exists(mysql_data_home, true)) {
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
}
|
2020-04-28 01:06:11 +02:00
|
|
|
|
|
|
|
#ifdef _WIN32
|
2020-05-11 22:01:40 +02:00
|
|
|
/* Initialize security descriptor for the new directories
|
|
|
|
to be the same as for datadir */
|
2020-04-28 01:06:11 +02:00
|
|
|
DWORD res = GetNamedSecurityInfoA(mysql_data_home,
|
|
|
|
SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
|
|
|
|
NULL, NULL, NULL, NULL,
|
2020-05-11 22:01:40 +02:00
|
|
|
&my_dir_security_attributes.lpSecurityDescriptor);
|
2020-04-28 01:06:11 +02:00
|
|
|
if (res != ERROR_SUCCESS) {
|
|
|
|
msg("Unable to read security descriptor of %s",mysql_data_home);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2017-04-18 20:43:20 +02:00
|
|
|
if (srv_undo_dir && *srv_undo_dir
|
|
|
|
&& !directory_exists(srv_undo_dir, true)) {
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
if (innobase_data_home_dir && *innobase_data_home_dir
|
|
|
|
&& !directory_exists(innobase_data_home_dir, true)) {
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
if (srv_log_group_home_dir && *srv_log_group_home_dir
|
|
|
|
&& !directory_exists(srv_log_group_home_dir, true)) {
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
2023-04-24 08:27:55 +02:00
|
|
|
Copy_back_dst_dir aria_log_dir_path_dst;
|
|
|
|
const char *aria_log_dir_path_abs= aria_log_dir_path_dst.make(aria_log_dir_path);
|
2023-04-13 13:42:53 +02:00
|
|
|
if (aria_log_dir_path && *aria_log_dir_path
|
2023-04-24 08:27:55 +02:00
|
|
|
&& !directory_exists(aria_log_dir_path_abs, true)) {
|
2023-04-13 13:42:53 +02:00
|
|
|
return false;
|
|
|
|
}
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
/* cd to backup directory */
|
|
|
|
if (my_setwd(xtrabackup_target_dir, MYF(MY_WME)))
|
|
|
|
{
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Can't my_setwd %s", xtrabackup_target_dir);
|
2017-04-18 20:43:20 +02:00
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
2023-04-24 08:27:55 +02:00
|
|
|
if (!copy_back_aria_logs(aria_log_dir_path_abs))
|
2023-04-13 13:42:53 +02:00
|
|
|
return false;
|
|
|
|
|
2017-04-18 20:43:20 +02:00
|
|
|
/* parse data file path */
|
|
|
|
|
|
|
|
if (!innobase_data_file_path) {
|
|
|
|
innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
|
|
|
|
}
|
|
|
|
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
srv_sys_space.set_path(".");
|
|
|
|
|
|
|
|
if (!srv_sys_space.parse_params(innobase_data_file_path, true)) {
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("syntax error in innodb_data_file_path");
|
2017-04-18 20:43:20 +02:00
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* copy undo tablespaces */
|
|
|
|
|
2023-03-17 16:51:33 +01:00
|
|
|
Copy_back_dst_dir dst_dir_buf;
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2023-03-17 16:51:33 +01:00
|
|
|
dst_dir = dst_dir_buf.make(srv_undo_dir);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_ctxt *ds_tmp = ds_create(dst_dir, DS_TYPE_LOCAL);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2017-11-07 22:02:39 +01:00
|
|
|
for (uint i = 1; i <= TRX_SYS_MAX_UNDO_SPACES; i++) {
|
2017-11-03 17:02:19 +01:00
|
|
|
char filename[20];
|
2017-11-07 22:02:39 +01:00
|
|
|
sprintf(filename, "undo%03u", i);
|
2017-11-03 17:02:19 +01:00
|
|
|
if (!file_exists(filename)) {
|
|
|
|
break;
|
|
|
|
}
|
2023-04-12 09:40:46 +02:00
|
|
|
if (!(ret = copy_or_move_file(ds_tmp, filename, filename,
|
2017-11-07 22:02:39 +01:00
|
|
|
dst_dir, 1))) {
|
2017-11-03 17:02:19 +01:00
|
|
|
goto cleanup;
|
|
|
|
}
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_destroy(ds_tmp);
|
|
|
|
ds_tmp = NULL;
|
2017-11-03 17:02:19 +01:00
|
|
|
|
2017-04-18 20:43:20 +02:00
|
|
|
/* copy redo logs */
|
|
|
|
|
2023-03-17 16:51:33 +01:00
|
|
|
dst_dir = dst_dir_buf.make(srv_log_group_home_dir);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2023-12-03 13:09:43 +01:00
|
|
|
/* --backup generates a single LOG_FILE_NAME, which we must copy
|
|
|
|
if it exists. */
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_tmp = ds_create(dst_dir, DS_TYPE_LOCAL);
|
2023-04-26 12:58:40 +02:00
|
|
|
if (!(ret = copy_or_move_file(ds_tmp, LOG_FILE_NAME, LOG_FILE_NAME,
|
MDEV-14425 Improve the redo log for concurrency
The InnoDB redo log used to be formatted in blocks of 512 bytes.
The log blocks were encrypted and the checksum was calculated while
holding log_sys.mutex, creating a serious scalability bottleneck.
We remove the fixed-size redo log block structure altogether and
essentially turn every mini-transaction into a log block of its own.
This allows encryption and checksum calculations to be performed
on local mtr_t::m_log buffers, before acquiring log_sys.mutex.
The mutex only protects a memcpy() of the data to the shared
log_sys.buf, as well as the padding of the log, in case the
to-be-written part of the log would not end in a block boundary of
the underlying storage. For now, the "padding" consists of writing
a single NUL byte, to allow recovery and mariadb-backup to detect
the end of the circular log faster.
Like the previous implementation, we will overwrite the last log block
over and over again, until it has been completely filled. It would be
possible to write only up to the last completed block (if no more
recent write was requested), or to write dummy FILE_CHECKPOINT records
to fill the incomplete block, by invoking the currently disabled
function log_pad(). This would require adjustments to some logic around
log checkpoints, page flushing, and shutdown.
An upgrade after a crash of any previous version is not supported.
Logically empty log files from a previous version will be upgraded.
An attempt to start up InnoDB without a valid ib_logfile0 will be
refused. Previously, the redo log used to be created automatically
if it was missing. Only with with innodb_force_recovery=6, it is
possible to start InnoDB in read-only mode even if the log file
does not exist. This allows the contents of a possibly corrupted
database to be dumped.
Because a prepared backup from an earlier version of mariadb-backup
will create a 0-sized log file, we will allow an upgrade from such
log files, provided that the FIL_PAGE_FILE_FLUSH_LSN in the system
tablespace looks valid.
The 512-byte log checkpoint blocks at 0x200 and 0x600 will be replaced
with 64-byte log checkpoint blocks at 0x1000 and 0x2000.
The start of log records will move from 0x800 to 0x3000. This allows us
to use 4096-byte aligned blocks for all I/O in a future revision.
We extend the MDEV-12353 redo log record format as follows.
(1) Empty mini-transactions or extra NUL bytes will not be allowed.
(2) The end-of-minitransaction marker (a NUL byte) will be replaced
with a 1-bit sequence number, which will be toggled each time when the
circular log file wraps back to the beginning.
(3) After the sequence bit, a CRC-32C checksum of all data
(excluding the sequence bit) will written.
(4) If the log is encrypted, 8 bytes will be written before
the checksum and included in it. This is part of the
initialization vector (IV) of encrypted log data.
(5) File names, page numbers, and checkpoint information will not be
encrypted. Only the payload bytes of page-level log will be encrypted.
The tablespace ID and page number will form part of the IV.
(6) For padding, arbitrary-length FILE_CHECKPOINT records may be written,
with all-zero payload, and with the normal end marker and checksum.
The minimum size is 7 bytes, or 7+8 with innodb_encrypt_log=ON.
In mariadb-backup and in Galera snapshot transfer (SST) scripts, we will
no longer remove ib_logfile0 or create an empty ib_logfile0. Server startup
will require a valid log file. When resizing the log, we will create
a logically empty ib_logfile101 at the current LSN and use an atomic rename
to replace ib_logfile0 with it. See the test innodb.log_file_size.
Because there is no mandatory padding in the log file, we are able
to create a dummy log file as of an arbitrary log sequence number.
See the test mariabackup.huge_lsn.
The parameter innodb_log_write_ahead_size and the
INFORMATION_SCHEMA.INNODB_METRICS counter log_padded will be removed.
The minimum value of innodb_log_buffer_size will be increased to 2MiB
(because log_sys.buf will replace recv_sys.buf) and the increment
adjusted to 4096 bytes (the maximum log block size).
The following INFORMATION_SCHEMA.INNODB_METRICS counters will be removed:
os_log_fsyncs
os_log_pending_fsyncs
log_pending_log_flushes
log_pending_checkpoint_writes
The following status variables will be removed:
Innodb_os_log_fsyncs (this is included in Innodb_data_fsyncs)
Innodb_os_log_pending_fsyncs (this was limited to at most 1 by design)
log_sys.get_block_size(): Return the physical block size of the log file.
This is only implemented on Linux and Microsoft Windows for now, and for
the power-of-2 block sizes between 64 and 4096 bytes (the minimum and
maximum size of a checkpoint block). If the block size is anything else,
the traditional 512-byte size will be used via normal file system
buffering.
If the file system buffers can be bypassed, a message like the following
will be issued:
InnoDB: File system buffers for log disabled (block size=512 bytes)
InnoDB: File system buffers for log disabled (block size=4096 bytes)
This has been tested on Linux and Microsoft Windows with both sizes.
On Linux, only enable O_DIRECT on the log for innodb_flush_method=O_DSYNC.
Tests in 3 different environments where the log is stored in a device
with a physical block size of 512 bytes are yielding better throughput
without O_DIRECT. This could be due to the fact that in the event the
last log block is being overwritten (if multiple transactions would
become durable at the same time, and each of will write a small
number of bytes to the last log block), it should be faster to re-copy
data from log_sys.buf or log_sys.flush_buf to the kernel buffer,
to be finally written at fdatasync() time.
The parameter innodb_flush_method=O_DSYNC will imply O_DIRECT for
data files. This option will enable O_DIRECT on the log file on Linux.
It may be unsafe to use when the storage device does not support
FUA (Force Unit Access) mode.
When the server is compiled WITH_PMEM=ON, we will use memory-mapped
I/O for the log file if the log resides on a "mount -o dax" device.
We will identify PMEM in a start-up message:
InnoDB: log sequence number 0 (memory-mapped); transaction id 3
On Linux, we will also invoke mmap() on any ib_logfile0 that resides
in /dev/shm, effectively treating the log file as persistent memory.
This should speed up "./mtr --mem" and increase the test coverage of
PMEM on non-PMEM hardware. It also allows users to estimate how much
the performance would be improved by installing persistent memory.
On other tmpfs file systems such as /run, we will not use mmap().
mariadb-backup: Eliminated several variables. We will refer
directly to recv_sys and log_sys.
backup_wait_for_lsn(): Detect non-progress of
xtrabackup_copy_logfile(). In this new log format with
arbitrary-sized blocks, we can only detect log file overrun
indirectly, by observing that the scanned log sequence number
is not advancing.
xtrabackup_copy_logfile(): On PMEM, do not modify the sequence bit,
because we are not allowed to modify the server's log file, and our
memory mapping is read-only.
trx_flush_log_if_needed_low(): Do not use the callback on pmem.
Using neither flush_lock nor write_lock around PMEM writes seems
to yield the best performance. The pmem_persist() calls may
still be somewhat slower than the pwrite() and fdatasync() based
interface (PMEM mounted without -o dax).
recv_sys_t::buf: Remove. We will use log_sys.buf for parsing.
recv_sys_t::MTR_SIZE_MAX: Replaces RECV_SCAN_SIZE.
recv_sys_t::file_checkpoint: Renamed from mlog_checkpoint_lsn.
recv_sys_t, log_sys_t: Removed many data members.
recv_sys.lsn: Renamed from recv_sys.recovered_lsn.
recv_sys.offset: Renamed from recv_sys.recovered_offset.
log_sys.buf_size: Replaces srv_log_buffer_size.
recv_buf: A smart pointer that wraps log_sys.buf[recv_sys.offset]
when the buffer is being allocated from the memory heap.
recv_ring: A smart pointer that wraps a circular log_sys.buf[] that is
backed by ib_logfile0. The pointer will wrap from recv_sys.len
(log_sys.file_size) to log_sys.START_OFFSET. For the record that
wraps around, we may copy file name or record payload data to
the auxiliary buffer decrypt_buf in order to have a contiguous
block of memory. The maximum size of a record is less than
innodb_page_size bytes.
recv_sys_t::parse(): Take the smart pointer as a template parameter.
Do not temporarily add a trailing NUL byte to FILE_ records, because
we are not supposed to modify the memory-mapped log file. (It is
attached in read-write mode already during recovery.)
recv_sys_t::parse_mtr(): Wrapper for recv_sys_t::parse().
recv_sys_t::parse_pmem(): Like parse_mtr(), but if PREMATURE_EOF would be
returned on PMEM, use recv_ring to wrap around the buffer to the start.
mtr_t::finish_write(), log_close(): Do not enforce log_sys.max_buf_free
on PMEM, because it has no meaning on the mmap-based log.
log_sys.write_to_buf: Count writes to log_sys.buf. Replaces
srv_stats.log_write_requests and export_vars.innodb_log_write_requests.
Protected by log_sys.mutex. Updated consistently in log_close().
Previously, mtr_t::commit() conditionally updated the count,
which was inconsistent.
log_sys.write_to_log: Count swaps of log_sys.buf and log_sys.flush_buf,
for writing to log_sys.log (the ib_logfile0). Replaces
srv_stats.log_writes and export_vars.innodb_log_writes.
Protected by log_sys.mutex.
log_sys.waits: Count waits in append_prepare(). Replaces
srv_stats.log_waits and export_vars.innodb_log_waits.
recv_recover_page(): Do not unnecessarily acquire
log_sys.flush_order_mutex. We are inserting the blocks in arbitary
order anyway, to be adjusted in recv_sys.apply(true).
We will change the definition of flush_lock and write_lock to
avoid potential false sharing. Depending on sizeof(log_sys) and
CPU_LEVEL1_DCACHE_LINESIZE, the flush_lock and write_lock could
share a cache line with each other or with the last data members
of log_sys.
Thanks to Matthias Leich for providing https://rr-project.org traces
for various failures during the development, and to
Thirunarayanan Balathandayuthapani for his help in debugging
some of the recovery code. And thanks to the developers of the
rr debugger for a tool without which extensive changes to InnoDB
would be very challenging to get right.
Thanks to Vladislav Vaintroub for useful feedback and
to him, Axel Schwenke and Krunal Bauskar for testing the performance.
2022-01-21 15:03:47 +01:00
|
|
|
dst_dir, 1))) {
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
goto cleanup;
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_destroy(ds_tmp);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
/* copy innodb system tablespace(s) */
|
|
|
|
|
2023-03-17 16:51:33 +01:00
|
|
|
dst_dir = dst_dir_buf.make(innobase_data_home_dir);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_tmp = ds_create(dst_dir, DS_TYPE_LOCAL);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
for (Tablespace::const_iterator iter(srv_sys_space.begin()),
|
|
|
|
end(srv_sys_space.end());
|
|
|
|
iter != end;
|
|
|
|
++iter) {
|
MDEV-25312 Replace fil_space_t::name with fil_space_t::name()
A consistency check for fil_space_t::name is causing recovery failures
in MDEV-25180 (Atomic ALTER TABLE). So, we'd better remove that field
altogether.
fil_space_t::name was more or less a copy of dict_table_t::name
(except for some special cases), and it was not being used for
anything useful.
There used to be a name_hash, but it had been removed already in
commit a75dbfd7183cc96680f3e3e684fd36500dac8158 (MDEV-12266).
We will also remove os_normalize_path(), OS_PATH_SEPARATOR,
OS_PATH_SEPATOR_ALT. On Microsoft Windows, we will treat \ and /
roughly in the same way. The intention is that for per-table
tablespaces, the filenames will always follow the pattern
prefix/databasename/tablename.ibd. (Any \ in the prefix must not
be converted.)
ut_basename_noext(): Remove (unused function).
read_link_file(): Replaces RemoteDatafile::read_link_file().
We will ensure that the last two path component separators are
forward slashes (converting up to 2 trailing backslashes on
Microsoft Windows), so that everywhere else we can
assume that data file names end in "/databasename/tablename.ibd".
Note: On Microsoft Windows, path names that start with \\?\ must
not contain / as path component separators. Previously, such paths
did work in the DATA DIRECTORY argument of InnoDB tables.
Reviewed by: Vladislav Vaintroub
2021-04-07 17:01:13 +02:00
|
|
|
const char *filepath = iter->filepath();
|
2023-04-25 12:10:33 +02:00
|
|
|
if (!(ret = copy_or_move_file(ds_tmp, base_name(filepath),
|
|
|
|
filepath, dst_dir, 1))) {
|
2017-04-18 20:43:20 +02:00
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_destroy(ds_tmp);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
/* copy the rest of tablespaces */
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_tmp = ds_create(mysql_data_home, DS_TYPE_LOCAL);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
it = datadir_iter_new(".", false);
|
|
|
|
|
|
|
|
datadir_node_init(&node);
|
|
|
|
|
|
|
|
while (datadir_iter_next(it, &node)) {
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
const char *ext_list[] = {"backup-my.cnf",
|
2023-02-03 04:42:59 +01:00
|
|
|
"xtrabackup_binary",
|
|
|
|
MB_BINLOG_INFO,
|
|
|
|
MB_METADATA_FILENAME,
|
|
|
|
XTRABACKUP_BINLOG_INFO,
|
|
|
|
XTRABACKUP_METADATA_FILENAME,
|
|
|
|
".qp", ".pmap", ".tmp",
|
2017-05-26 11:13:48 +02:00
|
|
|
NULL};
|
2017-04-18 20:43:20 +02:00
|
|
|
const char *filename;
|
|
|
|
char c_tmp;
|
|
|
|
int i_tmp;
|
|
|
|
|
2023-04-13 13:42:53 +02:00
|
|
|
/* Skip aria log files */
|
|
|
|
if (is_aria_log_dir_file(node))
|
|
|
|
continue;
|
|
|
|
|
2018-06-07 16:13:54 +02:00
|
|
|
if (strstr(node.filepath,"/" ROCKSDB_BACKUP_DIR "/")
|
|
|
|
#ifdef _WIN32
|
|
|
|
|| strstr(node.filepath,"\\" ROCKSDB_BACKUP_DIR "\\")
|
|
|
|
#endif
|
|
|
|
)
|
|
|
|
{
|
|
|
|
// copied at later step
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-04-18 20:43:20 +02:00
|
|
|
/* create empty directories */
|
|
|
|
if (node.is_empty_dir) {
|
|
|
|
char path[FN_REFLEN];
|
|
|
|
|
|
|
|
snprintf(path, sizeof(path), "%s/%s",
|
|
|
|
mysql_data_home, node.filepath_rel);
|
|
|
|
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Creating directory %s", path);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
if (mkdirp(path, 0777, MYF(0)) < 0) {
|
|
|
|
char errbuf[MYSYS_STRERROR_SIZE];
|
2017-04-18 21:05:57 +02:00
|
|
|
my_strerror(errbuf, sizeof(errbuf), my_errno);
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Can not create directory %s: %s",
|
2017-04-18 21:05:57 +02:00
|
|
|
path, errbuf);
|
2017-04-18 20:43:20 +02:00
|
|
|
ret = false;
|
|
|
|
|
|
|
|
goto cleanup;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-01-14 22:28:23 +01:00
|
|
|
msg(" ...done.");
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
filename = base_name(node.filepath);
|
|
|
|
|
2017-05-26 11:13:48 +02:00
|
|
|
/* skip .qp files */
|
2017-04-18 20:43:20 +02:00
|
|
|
if (filename_matches(filename, ext_list)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* skip undo tablespaces */
|
|
|
|
if (sscanf(filename, "undo%d%c", &i_tmp, &c_tmp) == 1) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
/* skip the redo log (it was already copied) */
|
2020-01-11 20:05:28 +01:00
|
|
|
if (!strcmp(filename, LOG_FILE_NAME)) {
|
2017-04-18 20:43:20 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2022-06-28 09:42:45 +02:00
|
|
|
/* skip buffer pool dump */
|
|
|
|
if (!strcmp(filename, default_buffer_pool_file)) {
|
|
|
|
continue;
|
|
|
|
}
|
MDEV-27524: Incorrect binlogs after Galera SST using rsync and mariabackup
This commit adds correct handling of binlogs for SST using rsync
or mariabackup. Before this fix, binlogs were handled incorrectly -
- only one (last) binary log file was transferred during SST, which
then led to various failures (for example, when trying to list all
events from the binary log). These bugs were long masked by flaws
in the primitive binlogs handling code in the SST scripts, which
causing binary logs files to be erased after transfer or not added
to the binlog index on the joiner node. Now the correct transfer
of all binary logs (not just the last of the binary log files) has
been implemented both for the rsync (at the script level) and for
the mariabackup (at the level of the main utility code).
This commit also adds a new sst_max_binlogs=<n> parameter, which
can be located in the [sst] section or in the [xtrabackup] section
(historically, supported for mariabackup only, not for rsync), or
in one of the server sections. This parameter specifies the number
of binary log files to be sent to the joiner node during SST. This
option is added for compatibility with old SST scripting behavior,
which can be emulated by setting the sst_max_binlogs=1 (although
in general this can cause problems for the reasons described above).
In addition, setting the sst_max_binlogs=0 can be used to suppress
the transmission of binary logs to the joiner nodes during SST
(although sometimes a single file with the current binary log can
still be transmitted to the joiner, even with sst_max_binlogs=0,
because this sometimes necessary in modes that involve the use of
GTIDs with Galera).
Also, this commit ensures correct handling of paths to various
innodb files and directories in the SST scripts, and fixes some
problems with this that existed in mariabackup utility (which
were associated with incorrect handling of the innodb_data_dir
parameter in some scenarios).
In addition, this commit contains the following enhancements:
1) Added tests for mtr, which check the correct work with binlogs
after SST (using rsync and mariabackup);
2) Added correct handling of slashes at the end of all paths that
the SST script receives as parameters;
3) Improved parsing code for --mysqld-args parameters. Now it
correctly processes the sequence "--" after the name of the
one-letter option;
4) Checking the secret signature during joiner authentication
is made independent of presence of bash (as a unix shell)
in the system and diff utility no longer needed to check
certificates compliance;
5) All directories that are necessary for the correct placement
of various logs are automatically created by SST scripts in
advance (before running mariabackup on the joiner node);
6) Removal of old binary logs on joiner is done using the binlog
index (if it exists) (not only by fixed pattern that based
on the current binlog name, as before);
7) Paths for placing binary logs are correctly processed if they
are set as relative paths (to the datadir);
8) SST scripts are made even more resistant to spaces in filenames
(now for binlogs);
9) In case of failure, SST scripts now always end with an exit
code other than zero;
10) SST script for rsync now correctly create a tar file with
the binlogs, even if the paths to them (in the binlog index
file) are specified as a mix of absolute and relative paths,
and even if they do not match with the datadir path specified
in the current configuration settings.
2022-02-22 10:45:06 +01:00
|
|
|
|
2017-04-18 20:43:20 +02:00
|
|
|
/* skip innodb data files */
|
MDEV-12548 Initial implementation of Mariabackup for MariaDB 10.2
InnoDB I/O and buffer pool interfaces and the redo log format
have been changed between MariaDB 10.1 and 10.2, and the backup
code has to be adjusted accordingly.
The code has been simplified, and many memory leaks have been fixed.
Instead of the file name xtrabackup_logfile, the file name ib_logfile0
is being used for the copy of the redo log. Unnecessary InnoDB startup and
shutdown and some unnecessary threads have been removed.
Some help was provided by Vladislav Vaintroub.
Parameters have been cleaned up and aligned with those of MariaDB 10.2.
The --dbug option has been added, so that in debug builds,
--dbug=d,ib_log can be specified to enable diagnostic messages
for processing redo log entries.
By default, innodb_doublewrite=OFF, so that --prepare works faster.
If more crash-safety for --prepare is needed, double buffering
can be enabled.
The parameter innodb_log_checksums=OFF can be used to ignore redo log
checksums in --backup.
Some messages have been cleaned up.
Unless --export is specified, Mariabackup will not deal with undo log.
The InnoDB mini-transaction redo log is not only about user-level
transactions; it is actually about mini-transactions. To avoid confusion,
call it the redo log, not transaction log.
We disable any undo log processing in --prepare.
Because MariaDB 10.2 supports indexed virtual columns, the
undo log processing would need to be able to evaluate virtual column
expressions. To reduce the amount of code dependencies, we will not
process any undo log in prepare.
This means that the --export option must be disabled for now.
This also means that the following options are redundant
and have been removed:
xtrabackup --apply-log-only
innobackupex --redo-only
In addition to disabling any undo log processing, we will disable any
further changes to data pages during --prepare, including the change
buffer merge. This means that restoring incremental backups should
reliably work even when change buffering is being used on the server.
Because of this, preparing a backup will not generate any further
redo log, and the redo log file can be safely deleted. (If the
--export option is enabled in the future, it must generate redo log
when processing undo logs and buffered changes.)
In --prepare, we cannot easily know if a partial backup was used,
especially when restoring a series of incremental backups. So, we
simply warn about any missing files, and ignore the redo log for them.
FIXME: Enable the --export option.
FIXME: Improve the handling of the MLOG_INDEX_LOAD record, and write
a test that initiates a backup while an ALGORITHM=INPLACE operation
is creating indexes or rebuilding a table. An error should be detected
when preparing the backup.
FIXME: In --incremental --prepare, xtrabackup_apply_delta() should
ensure that if FSP_SIZE is modified, the file size will be adjusted
accordingly.
2017-06-30 09:49:37 +02:00
|
|
|
for (Tablespace::const_iterator iter(srv_sys_space.begin()),
|
|
|
|
end(srv_sys_space.end()); iter != end; ++iter) {
|
MDEV-25312 Replace fil_space_t::name with fil_space_t::name()
A consistency check for fil_space_t::name is causing recovery failures
in MDEV-25180 (Atomic ALTER TABLE). So, we'd better remove that field
altogether.
fil_space_t::name was more or less a copy of dict_table_t::name
(except for some special cases), and it was not being used for
anything useful.
There used to be a name_hash, but it had been removed already in
commit a75dbfd7183cc96680f3e3e684fd36500dac8158 (MDEV-12266).
We will also remove os_normalize_path(), OS_PATH_SEPARATOR,
OS_PATH_SEPATOR_ALT. On Microsoft Windows, we will treat \ and /
roughly in the same way. The intention is that for per-table
tablespaces, the filenames will always follow the pattern
prefix/databasename/tablename.ibd. (Any \ in the prefix must not
be converted.)
ut_basename_noext(): Remove (unused function).
read_link_file(): Replaces RemoteDatafile::read_link_file().
We will ensure that the last two path component separators are
forward slashes (converting up to 2 trailing backslashes on
Microsoft Windows), so that everywhere else we can
assume that data file names end in "/databasename/tablename.ibd".
Note: On Microsoft Windows, path names that start with \\?\ must
not contain / as path component separators. Previously, such paths
did work in the DATA DIRECTORY argument of InnoDB tables.
Reviewed by: Vladislav Vaintroub
2021-04-07 17:01:13 +02:00
|
|
|
if (!strcmp(base_name(iter->filepath()), filename)) {
|
|
|
|
goto next_file;
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-12 09:40:46 +02:00
|
|
|
if (!(ret = copy_or_move_file(ds_tmp, node.filepath, node.filepath_rel,
|
2017-04-18 20:43:20 +02:00
|
|
|
mysql_data_home, 1))) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
MDEV-25312 Replace fil_space_t::name with fil_space_t::name()
A consistency check for fil_space_t::name is causing recovery failures
in MDEV-25180 (Atomic ALTER TABLE). So, we'd better remove that field
altogether.
fil_space_t::name was more or less a copy of dict_table_t::name
(except for some special cases), and it was not being used for
anything useful.
There used to be a name_hash, but it had been removed already in
commit a75dbfd7183cc96680f3e3e684fd36500dac8158 (MDEV-12266).
We will also remove os_normalize_path(), OS_PATH_SEPARATOR,
OS_PATH_SEPATOR_ALT. On Microsoft Windows, we will treat \ and /
roughly in the same way. The intention is that for per-table
tablespaces, the filenames will always follow the pattern
prefix/databasename/tablename.ibd. (Any \ in the prefix must not
be converted.)
ut_basename_noext(): Remove (unused function).
read_link_file(): Replaces RemoteDatafile::read_link_file().
We will ensure that the last two path component separators are
forward slashes (converting up to 2 trailing backslashes on
Microsoft Windows), so that everywhere else we can
assume that data file names end in "/databasename/tablename.ibd".
Note: On Microsoft Windows, path names that start with \\?\ must
not contain / as path component separators. Previously, such paths
did work in the DATA DIRECTORY argument of InnoDB tables.
Reviewed by: Vladislav Vaintroub
2021-04-07 17:01:13 +02:00
|
|
|
next_file:
|
|
|
|
continue;
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
2017-11-03 17:02:19 +01:00
|
|
|
/* copy buffer pool dump */
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2022-06-28 09:42:45 +02:00
|
|
|
if (file_exists(default_buffer_pool_file) &&
|
|
|
|
innobase_buffer_pool_filename) {
|
2023-04-12 09:40:46 +02:00
|
|
|
copy_or_move_file(ds_tmp, default_buffer_pool_file,
|
2022-06-28 09:42:45 +02:00
|
|
|
innobase_buffer_pool_filename,
|
|
|
|
mysql_data_home, 0);
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
2023-04-12 09:40:46 +02:00
|
|
|
rocksdb_copy_back(ds_tmp);
|
2018-06-07 16:13:54 +02:00
|
|
|
|
2017-04-18 20:43:20 +02:00
|
|
|
cleanup:
|
|
|
|
if (it != NULL) {
|
|
|
|
datadir_iter_free(it);
|
|
|
|
}
|
|
|
|
|
|
|
|
datadir_node_free(&node);
|
|
|
|
|
2023-04-12 09:40:46 +02:00
|
|
|
if (ds_tmp != NULL) {
|
|
|
|
ds_destroy(ds_tmp);
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_tmp = NULL;
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
decrypt_decompress_file(const char *filepath, uint thread_n)
|
|
|
|
{
|
|
|
|
std::stringstream cmd, message;
|
|
|
|
char *dest_filepath = strdup(filepath);
|
|
|
|
bool needs_action = false;
|
|
|
|
|
2017-04-18 21:05:57 +02:00
|
|
|
cmd << IF_WIN("type ","cat ") << filepath;
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
if (opt_decompress
|
2017-05-26 11:13:48 +02:00
|
|
|
&& ends_with(filepath, ".qp")) {
|
2017-04-18 20:43:20 +02:00
|
|
|
cmd << " | qpress -dio ";
|
|
|
|
dest_filepath[strlen(dest_filepath) - 3] = 0;
|
|
|
|
if (needs_action) {
|
|
|
|
message << " and ";
|
|
|
|
}
|
|
|
|
message << "decompressing";
|
|
|
|
needs_action = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
cmd << " > " << dest_filepath;
|
|
|
|
message << " " << filepath;
|
|
|
|
|
|
|
|
free(dest_filepath);
|
|
|
|
|
|
|
|
if (needs_action) {
|
|
|
|
|
2019-01-14 22:28:23 +01:00
|
|
|
msg(thread_n,"%s\n", message.str().c_str());
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
if (system(cmd.str().c_str()) != 0) {
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
2017-10-25 16:17:21 +02:00
|
|
|
if (opt_remove_original) {
|
2019-01-14 22:28:23 +01:00
|
|
|
msg(thread_n, "Removing %s", filepath);
|
2017-10-25 16:17:21 +02:00
|
|
|
if (my_delete(filepath, MYF(MY_WME)) != 0) {
|
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
}
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return(true);
|
|
|
|
}
|
|
|
|
|
2021-03-17 08:03:06 +01:00
|
|
|
static void decrypt_decompress_thread_func(datadir_thread_ctxt_t *ctxt)
|
2017-04-18 20:43:20 +02:00
|
|
|
{
|
|
|
|
bool ret = true;
|
|
|
|
datadir_node_t node;
|
|
|
|
|
|
|
|
datadir_node_init(&node);
|
|
|
|
|
|
|
|
while (datadir_iter_next(ctxt->it, &node)) {
|
|
|
|
|
|
|
|
/* skip empty directories in backup */
|
|
|
|
if (node.is_empty_dir) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-05-26 11:13:48 +02:00
|
|
|
if (!ends_with(node.filepath, ".qp")) {
|
2017-04-18 20:43:20 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(ret = decrypt_decompress_file(node.filepath,
|
|
|
|
ctxt->n_thread))) {
|
|
|
|
goto cleanup;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cleanup:
|
|
|
|
|
|
|
|
datadir_node_free(&node);
|
|
|
|
|
2018-09-20 20:27:59 +02:00
|
|
|
pthread_mutex_lock(ctxt->count_mutex);
|
2017-04-18 20:43:20 +02:00
|
|
|
--(*ctxt->count);
|
2018-09-20 20:27:59 +02:00
|
|
|
pthread_mutex_unlock(ctxt->count_mutex);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
ctxt->ret = ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
decrypt_decompress()
|
|
|
|
{
|
|
|
|
bool ret;
|
|
|
|
datadir_iter_t *it = NULL;
|
|
|
|
|
|
|
|
/* cd to backup directory */
|
|
|
|
if (my_setwd(xtrabackup_target_dir, MYF(MY_WME)))
|
|
|
|
{
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Can't my_setwd %s", xtrabackup_target_dir);
|
2017-04-18 20:43:20 +02:00
|
|
|
return(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* copy the rest of tablespaces */
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_ctxt *ds_tmp = ds_create(".", DS_TYPE_LOCAL);
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
it = datadir_iter_new(".", false);
|
|
|
|
|
|
|
|
ret = run_data_threads(it, decrypt_decompress_thread_func,
|
|
|
|
xtrabackup_parallel ? xtrabackup_parallel : 1);
|
|
|
|
|
|
|
|
if (it != NULL) {
|
|
|
|
datadir_iter_free(it);
|
|
|
|
}
|
|
|
|
|
2023-04-12 09:40:46 +02:00
|
|
|
if (ds_tmp != NULL) {
|
|
|
|
ds_destroy(ds_tmp);
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
|
|
|
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_tmp = NULL;
|
2017-04-18 20:43:20 +02:00
|
|
|
|
|
|
|
return(ret);
|
|
|
|
}
|
|
|
|
|
2017-04-18 21:05:57 +02:00
|
|
|
/*
|
|
|
|
Copy some files from top level datadir.
|
|
|
|
Do not copy the Innodb files (ibdata1, redo log files),
|
|
|
|
as this is done in a separate step.
|
|
|
|
*/
|
2023-12-03 13:09:43 +01:00
|
|
|
bool backup_files_from_datadir(ds_ctxt_t *ds_data,
|
|
|
|
const char *dir_path,
|
|
|
|
const char *prefix)
|
2017-04-18 20:43:20 +02:00
|
|
|
{
|
2021-05-18 11:13:18 +02:00
|
|
|
os_file_dir_t dir = os_file_opendir(dir_path);
|
|
|
|
if (dir == IF_WIN(INVALID_HANDLE_VALUE, nullptr)) return false;
|
|
|
|
|
2017-04-18 21:05:57 +02:00
|
|
|
os_file_stat_t info;
|
|
|
|
bool ret = true;
|
|
|
|
while (os_file_readdir_next_file(dir_path, dir, &info) == 0) {
|
2017-04-18 20:43:20 +02:00
|
|
|
|
2017-04-18 21:05:57 +02:00
|
|
|
if (info.type != OS_FILE_TYPE_FILE)
|
|
|
|
continue;
|
2017-04-18 20:43:20 +02:00
|
|
|
|
MDEV-25312 Replace fil_space_t::name with fil_space_t::name()
A consistency check for fil_space_t::name is causing recovery failures
in MDEV-25180 (Atomic ALTER TABLE). So, we'd better remove that field
altogether.
fil_space_t::name was more or less a copy of dict_table_t::name
(except for some special cases), and it was not being used for
anything useful.
There used to be a name_hash, but it had been removed already in
commit a75dbfd7183cc96680f3e3e684fd36500dac8158 (MDEV-12266).
We will also remove os_normalize_path(), OS_PATH_SEPARATOR,
OS_PATH_SEPATOR_ALT. On Microsoft Windows, we will treat \ and /
roughly in the same way. The intention is that for per-table
tablespaces, the filenames will always follow the pattern
prefix/databasename/tablename.ibd. (Any \ in the prefix must not
be converted.)
ut_basename_noext(): Remove (unused function).
read_link_file(): Replaces RemoteDatafile::read_link_file().
We will ensure that the last two path component separators are
forward slashes (converting up to 2 trailing backslashes on
Microsoft Windows), so that everywhere else we can
assume that data file names end in "/databasename/tablename.ibd".
Note: On Microsoft Windows, path names that start with \\?\ must
not contain / as path component separators. Previously, such paths
did work in the DATA DIRECTORY argument of InnoDB tables.
Reviewed by: Vladislav Vaintroub
2021-04-07 17:01:13 +02:00
|
|
|
const char *pname = strrchr(info.name, '/');
|
|
|
|
#ifdef _WIN32
|
|
|
|
if (const char *last = strrchr(info.name, '\\')) {
|
|
|
|
if (!pname || last >pname) {
|
|
|
|
pname = last;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2017-04-18 21:05:57 +02:00
|
|
|
if (!pname)
|
|
|
|
pname = info.name;
|
|
|
|
|
2023-04-13 13:42:53 +02:00
|
|
|
if (!starts_with(pname, prefix))
|
2019-11-20 19:27:30 +01:00
|
|
|
continue;
|
|
|
|
|
|
|
|
if (xtrabackup_prepare && xtrabackup_incremental_dir &&
|
|
|
|
file_exists(info.name))
|
|
|
|
unlink(info.name);
|
|
|
|
|
|
|
|
std::string full_path(dir_path);
|
MDEV-25312 Replace fil_space_t::name with fil_space_t::name()
A consistency check for fil_space_t::name is causing recovery failures
in MDEV-25180 (Atomic ALTER TABLE). So, we'd better remove that field
altogether.
fil_space_t::name was more or less a copy of dict_table_t::name
(except for some special cases), and it was not being used for
anything useful.
There used to be a name_hash, but it had been removed already in
commit a75dbfd7183cc96680f3e3e684fd36500dac8158 (MDEV-12266).
We will also remove os_normalize_path(), OS_PATH_SEPARATOR,
OS_PATH_SEPATOR_ALT. On Microsoft Windows, we will treat \ and /
roughly in the same way. The intention is that for per-table
tablespaces, the filenames will always follow the pattern
prefix/databasename/tablename.ibd. (Any \ in the prefix must not
be converted.)
ut_basename_noext(): Remove (unused function).
read_link_file(): Replaces RemoteDatafile::read_link_file().
We will ensure that the last two path component separators are
forward slashes (converting up to 2 trailing backslashes on
Microsoft Windows), so that everywhere else we can
assume that data file names end in "/databasename/tablename.ibd".
Note: On Microsoft Windows, path names that start with \\?\ must
not contain / as path component separators. Previously, such paths
did work in the DATA DIRECTORY argument of InnoDB tables.
Reviewed by: Vladislav Vaintroub
2021-04-07 17:01:13 +02:00
|
|
|
full_path.append(1, '/').append(info.name);
|
2023-04-12 09:40:46 +02:00
|
|
|
if (!(ret = ds_data->copy_file(full_path.c_str() , info.name, 1)))
|
2019-11-20 19:27:30 +01:00
|
|
|
break;
|
2017-04-18 21:05:57 +02:00
|
|
|
}
|
|
|
|
os_file_closedir(dir);
|
|
|
|
return ret;
|
2017-04-18 20:43:20 +02:00
|
|
|
}
|
2018-06-07 16:13:54 +02:00
|
|
|
|
|
|
|
|
|
|
|
static int rocksdb_remove_checkpoint_directory()
|
|
|
|
{
|
|
|
|
xb_mysql_query(mysql_connection, "set global rocksdb_remove_mariabackup_checkpoint=ON", false);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2023-12-03 13:09:43 +01:00
|
|
|
bool has_rocksdb_plugin()
|
2018-06-07 16:13:54 +02:00
|
|
|
{
|
|
|
|
static bool first_time = true;
|
|
|
|
static bool has_plugin= false;
|
|
|
|
if (!first_time || !xb_backup_rocksdb)
|
|
|
|
return has_plugin;
|
|
|
|
|
|
|
|
const char *query = "SELECT COUNT(*) FROM information_schema.plugins WHERE plugin_name='rocksdb'";
|
|
|
|
MYSQL_RES* result = xb_mysql_query(mysql_connection, query, true);
|
|
|
|
MYSQL_ROW row = mysql_fetch_row(result);
|
|
|
|
if (row)
|
|
|
|
has_plugin = !strcmp(row[0], "1");
|
|
|
|
mysql_free_result(result);
|
|
|
|
first_time = false;
|
|
|
|
return has_plugin;
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *trim_trailing_dir_sep(char *path)
|
|
|
|
{
|
|
|
|
size_t path_len = strlen(path);
|
|
|
|
while (path_len)
|
|
|
|
{
|
|
|
|
char c = path[path_len - 1];
|
|
|
|
if (c == '/' IF_WIN(|| c == '\\', ))
|
|
|
|
path_len--;
|
|
|
|
else
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
path[path_len] = 0;
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Create a file hardlink.
|
|
|
|
@return true on success, false on error.
|
|
|
|
*/
|
2023-04-12 09:40:46 +02:00
|
|
|
bool
|
|
|
|
ds_ctxt_t::make_hardlink(const char *from_path, const char *to_path)
|
2018-06-07 16:13:54 +02:00
|
|
|
{
|
|
|
|
DBUG_EXECUTE_IF("no_hardlinks", return false;);
|
|
|
|
char to_path_full[FN_REFLEN];
|
|
|
|
if (!is_abs_path(to_path))
|
|
|
|
{
|
2023-04-12 09:40:46 +02:00
|
|
|
fn_format(to_path_full, to_path, root, "", MYF(MY_RELATIVE_PATH));
|
2018-06-07 16:13:54 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2023-09-18 16:16:32 +02:00
|
|
|
strmake(to_path_full, to_path, sizeof(to_path_full)-1);
|
2018-06-07 16:13:54 +02:00
|
|
|
}
|
|
|
|
#ifdef _WIN32
|
|
|
|
return CreateHardLink(to_path_full, from_path, NULL);
|
|
|
|
#else
|
|
|
|
return !link(from_path, to_path_full);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Copies or moves a directory (non-recursively so far).
|
|
|
|
Helper function used to backup rocksdb checkpoint, or copy-back the
|
|
|
|
rocksdb files.
|
|
|
|
|
|
|
|
Has optimization that allows to use hardlinks when possible
|
|
|
|
(source and destination are directories on the same device)
|
|
|
|
*/
|
2023-04-12 09:40:46 +02:00
|
|
|
void
|
|
|
|
ds_ctxt_t::copy_or_move_dir(const char *from, const char *to,
|
|
|
|
bool do_copy, bool allow_hardlinks)
|
2018-06-07 16:13:54 +02:00
|
|
|
{
|
|
|
|
datadir_node_t node;
|
|
|
|
datadir_node_init(&node);
|
|
|
|
datadir_iter_t *it = datadir_iter_new(from, false);
|
|
|
|
|
|
|
|
while (datadir_iter_next(it, &node))
|
|
|
|
{
|
|
|
|
char to_path[FN_REFLEN];
|
|
|
|
const char *from_path = node.filepath;
|
|
|
|
snprintf(to_path, sizeof(to_path), "%s/%s", to, base_name(from_path));
|
|
|
|
bool rc = false;
|
|
|
|
if (do_copy && allow_hardlinks)
|
|
|
|
{
|
|
|
|
rc = make_hardlink(from_path, to_path);
|
|
|
|
if (rc)
|
|
|
|
{
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Creating hardlink from %s to %s",from_path, to_path);
|
2018-06-07 16:13:54 +02:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
allow_hardlinks = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!rc)
|
|
|
|
{
|
|
|
|
rc = (do_copy ?
|
2023-04-12 09:40:46 +02:00
|
|
|
copy_file(from_path, to_path, 1) :
|
|
|
|
move_file(from_path, node.filepath_rel,
|
2018-06-07 16:13:54 +02:00
|
|
|
to, 1));
|
|
|
|
}
|
|
|
|
if (!rc)
|
2019-01-15 22:47:54 +01:00
|
|
|
die("copy or move file failed");
|
2018-06-07 16:13:54 +02:00
|
|
|
}
|
|
|
|
datadir_iter_free(it);
|
|
|
|
datadir_node_free(&node);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Obtain user level lock , to protect the checkpoint directory of the server
|
|
|
|
from being user/overwritten by different backup processes, if backups are
|
|
|
|
running in parallel.
|
|
|
|
|
|
|
|
This lock will be acquired before rocksdb checkpoint is created, held
|
|
|
|
while all files from it are being copied to their final backup destination,
|
|
|
|
and finally released after the checkpoint is removed.
|
|
|
|
*/
|
|
|
|
static void rocksdb_lock_checkpoint()
|
|
|
|
{
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Obtaining rocksdb checkpoint lock.");
|
2018-06-07 16:13:54 +02:00
|
|
|
MYSQL_RES *res =
|
|
|
|
xb_mysql_query(mysql_connection, "SELECT GET_LOCK('mariabackup_rocksdb_checkpoint',3600)", true, true);
|
|
|
|
|
|
|
|
MYSQL_ROW r = mysql_fetch_row(res);
|
|
|
|
if (r && r[0] && strcmp(r[0], "1"))
|
|
|
|
{
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Could not obtain rocksdb checkpont lock.");
|
2018-06-07 16:13:54 +02:00
|
|
|
exit(EXIT_FAILURE);
|
|
|
|
}
|
2018-08-09 16:06:52 +02:00
|
|
|
mysql_free_result(res);
|
2018-06-07 16:13:54 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void rocksdb_unlock_checkpoint()
|
|
|
|
{
|
|
|
|
xb_mysql_query(mysql_connection,
|
|
|
|
"SELECT RELEASE_LOCK('mariabackup_rocksdb_checkpoint')", false, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
Create temporary checkpoint in $rocksdb_datadir/mariabackup-checkpoint
|
|
|
|
directory.
|
|
|
|
A (user-level) lock named 'mariabackup_rocksdb_checkpoint' will also be
|
|
|
|
acquired be this function.
|
|
|
|
*/
|
|
|
|
#define MARIADB_CHECKPOINT_DIR "mariabackup-checkpoint"
|
|
|
|
static char rocksdb_checkpoint_dir[FN_REFLEN];
|
|
|
|
|
2023-12-03 13:09:43 +01:00
|
|
|
void rocksdb_create_checkpoint()
|
2018-06-07 16:13:54 +02:00
|
|
|
{
|
|
|
|
MYSQL_RES *result = xb_mysql_query(mysql_connection, "SELECT @@rocksdb_datadir,@@datadir", true, true);
|
|
|
|
MYSQL_ROW row = mysql_fetch_row(result);
|
|
|
|
|
|
|
|
DBUG_ASSERT(row && row[0] && row[1]);
|
|
|
|
|
|
|
|
char *rocksdbdir = row[0];
|
|
|
|
char *datadir = row[1];
|
|
|
|
|
|
|
|
if (is_abs_path(rocksdbdir))
|
|
|
|
{
|
|
|
|
snprintf(rocksdb_checkpoint_dir, sizeof(rocksdb_checkpoint_dir),
|
|
|
|
"%s/" MARIADB_CHECKPOINT_DIR, trim_trailing_dir_sep(rocksdbdir));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
snprintf(rocksdb_checkpoint_dir, sizeof(rocksdb_checkpoint_dir),
|
|
|
|
"%s/%s/" MARIADB_CHECKPOINT_DIR, trim_trailing_dir_sep(datadir),
|
|
|
|
trim_dotslash(rocksdbdir));
|
|
|
|
}
|
|
|
|
mysql_free_result(result);
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
for (char *p = rocksdb_checkpoint_dir; *p; p++)
|
|
|
|
if (*p == '\\') *p = '/';
|
|
|
|
#endif
|
|
|
|
|
|
|
|
rocksdb_lock_checkpoint();
|
|
|
|
|
|
|
|
if (!access(rocksdb_checkpoint_dir, 0))
|
|
|
|
{
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Removing rocksdb checkpoint from previous backup attempt.");
|
2018-06-07 16:13:54 +02:00
|
|
|
rocksdb_remove_checkpoint_directory();
|
|
|
|
}
|
|
|
|
|
|
|
|
char query[FN_REFLEN + 32];
|
|
|
|
snprintf(query, sizeof(query), "SET GLOBAL rocksdb_create_checkpoint='%s'", rocksdb_checkpoint_dir);
|
|
|
|
xb_mysql_query(mysql_connection, query, false, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Copy files from rocksdb temporary checkpoint to final destination.
|
|
|
|
remove temp.checkpoint directory (in server's datadir)
|
|
|
|
and release user level lock acquired inside rocksdb_create_checkpoint().
|
|
|
|
*/
|
2023-04-12 09:40:46 +02:00
|
|
|
static void rocksdb_backup_checkpoint(ds_ctxt *ds_data)
|
2018-06-07 16:13:54 +02:00
|
|
|
{
|
2019-01-14 22:28:23 +01:00
|
|
|
msg("Backing up rocksdb files.");
|
2018-06-07 16:13:54 +02:00
|
|
|
char rocksdb_backup_dir[FN_REFLEN];
|
|
|
|
snprintf(rocksdb_backup_dir, sizeof(rocksdb_backup_dir), "%s/" ROCKSDB_BACKUP_DIR , xtrabackup_target_dir);
|
|
|
|
bool backup_to_directory = xtrabackup_backup && xtrabackup_stream_fmt == XB_STREAM_FMT_NONE;
|
|
|
|
if (backup_to_directory)
|
|
|
|
{
|
|
|
|
if (my_mkdir(rocksdb_backup_dir, 0777, MYF(0))){
|
2019-01-15 22:47:54 +01:00
|
|
|
die("Can't create rocksdb backup directory %s", rocksdb_backup_dir);
|
2018-06-07 16:13:54 +02:00
|
|
|
}
|
|
|
|
}
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_data->copy_or_move_dir(rocksdb_checkpoint_dir, ROCKSDB_BACKUP_DIR, true, backup_to_directory);
|
2018-06-07 16:13:54 +02:00
|
|
|
rocksdb_remove_checkpoint_directory();
|
|
|
|
rocksdb_unlock_checkpoint();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
Copies #rocksdb directory to the $rockdb_data_dir, on copy-back
|
|
|
|
*/
|
2023-04-12 09:40:46 +02:00
|
|
|
static void rocksdb_copy_back(ds_ctxt *ds_data) {
|
2018-06-07 16:13:54 +02:00
|
|
|
if (access(ROCKSDB_BACKUP_DIR, 0))
|
|
|
|
return;
|
|
|
|
char rocksdb_home_dir[FN_REFLEN];
|
|
|
|
if (xb_rocksdb_datadir && is_abs_path(xb_rocksdb_datadir)) {
|
2019-03-21 07:54:35 +01:00
|
|
|
strncpy(rocksdb_home_dir, xb_rocksdb_datadir, sizeof rocksdb_home_dir - 1);
|
|
|
|
rocksdb_home_dir[sizeof rocksdb_home_dir - 1] = '\0';
|
2018-06-07 16:13:54 +02:00
|
|
|
} else {
|
|
|
|
snprintf(rocksdb_home_dir, sizeof(rocksdb_home_dir), "%s/%s", mysql_data_home,
|
|
|
|
xb_rocksdb_datadir?trim_dotslash(xb_rocksdb_datadir): ROCKSDB_BACKUP_DIR);
|
|
|
|
}
|
|
|
|
mkdirp(rocksdb_home_dir, 0777, MYF(0));
|
2023-04-12 09:40:46 +02:00
|
|
|
ds_data->copy_or_move_dir(ROCKSDB_BACKUP_DIR, rocksdb_home_dir, xtrabackup_copy_back, xtrabackup_copy_back);
|
2018-06-07 16:13:54 +02:00
|
|
|
}
|
2023-12-03 13:09:43 +01:00
|
|
|
|
|
|
|
void foreach_file_in_db_dirs(
|
|
|
|
const char *dir_path, std::function<bool(const char *)> func) {
|
|
|
|
DBUG_ASSERT(dir_path);
|
|
|
|
|
|
|
|
datadir_iter_t *it;
|
|
|
|
datadir_node_t node;
|
|
|
|
|
|
|
|
datadir_node_init(&node);
|
|
|
|
it = datadir_iter_new(dir_path);
|
|
|
|
|
|
|
|
while (datadir_iter_next(it, &node))
|
|
|
|
if (!node.is_empty_dir && !func(node.filepath))
|
|
|
|
break;
|
|
|
|
|
|
|
|
datadir_iter_free(it);
|
|
|
|
datadir_node_free(&node);
|
|
|
|
}
|
|
|
|
|
|
|
|
void foreach_file_in_datadir(
|
|
|
|
const char *dir_path, std::function<bool(const char *)> func)
|
|
|
|
{
|
|
|
|
DBUG_ASSERT(dir_path);
|
|
|
|
os_file_dir_t dir = os_file_opendir(dir_path);
|
|
|
|
os_file_stat_t info;
|
|
|
|
while (os_file_readdir_next_file(dir_path, dir, &info) == 0) {
|
|
|
|
if (info.type != OS_FILE_TYPE_FILE)
|
|
|
|
continue;
|
|
|
|
const char *pname = strrchr(info.name, IF_WIN('\\', '/'));
|
|
|
|
if (!pname)
|
|
|
|
pname = info.name;
|
|
|
|
if (!func(pname))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
os_file_closedir(dir);
|
|
|
|
}
|