MDEV-13561 Mariabackup is incompatible with retroactively created innodb_undo_tablespaces

- Mariabackup supports starting undo tablespace id which is greater
than 1.
parent 4629db0d
......@@ -27,7 +27,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#include <stdarg.h>
# define fil_is_user_tablespace_id(i) ((i) > srv_undo_tablespaces_open)
/** Determine if (i) is a user tablespace id or not. */
# define fil_is_user_tablespace_id(i) (i != 0 \
&& !srv_is_undo_tablespace(i))
#ifdef _MSC_VER
#define stat _stati64
......
......@@ -3079,6 +3079,85 @@ xb_fil_io_init(void)
fsp_init();
}
/** Assign srv_undo_space_id_start variable if there are undo tablespace present.
Read the TRX_SYS page from ibdata1 file and get the minimum space id from
the first slot rollback segments of TRX_SYS_PAGE_NO.
@retval DB_ERROR if file open or page read failed.
@retval DB_SUCCESS if srv_undo_space_id assigned successfully. */
static dberr_t xb_assign_undo_space_start()
{
ulint dirnamelen;
char name[1000];
pfs_os_file_t file;
byte* buf;
byte* page;
ibool ret;
dberr_t error = DB_SUCCESS;
ulint space, page_no;
if (srv_undo_tablespaces == 0) {
return error;
}
srv_normalize_path_for_win(srv_data_home);
dirnamelen = strlen(srv_data_home);
memcpy(name, srv_data_home, dirnamelen);
if (dirnamelen && name[dirnamelen - 1] != SRV_PATH_SEPARATOR) {
name[dirnamelen++] = SRV_PATH_SEPARATOR;
}
ut_snprintf(name + dirnamelen, strlen(name) + strlen("ibdata1"),
"%s", "ibdata1");
file = os_file_create(innodb_file_data_key, name, OS_FILE_OPEN,
OS_FILE_NORMAL, OS_DATA_FILE, &ret, 0);
if (ret == FALSE) {
fprintf(stderr, "InnoDB: Error in opening %s\n", name);
return DB_ERROR;
}
buf = static_cast<byte*>(ut_malloc(2 * UNIV_PAGE_SIZE));
page = static_cast<byte*>(ut_align(buf, UNIV_PAGE_SIZE));
retry:
ret = os_file_read(file, page, TRX_SYS_PAGE_NO * UNIV_PAGE_SIZE,
UNIV_PAGE_SIZE);
if (!ret) {
fprintf(stderr, "InnoDB: Reading TRX_SYS page failed.");
error = DB_ERROR;
goto func_exit;
}
/* TRX_SYS page can't be compressed or encrypted. */
if (buf_page_is_corrupted(false, page, 0, NULL)) {
goto retry;
}
/* 0th slot always points to system tablespace.
1st slot should point to first undotablespace which is minimum. */
page_no = mach_read_ulint(TRX_SYS + TRX_SYS_RSEGS
+ TRX_SYS_RSEG_SLOT_SIZE
+ TRX_SYS_RSEG_PAGE_NO + page, MLOG_4BYTES);
ut_ad(page_no != FIL_NULL);
space = mach_read_ulint(TRX_SYS + TRX_SYS_RSEGS
+ TRX_SYS_RSEG_SLOT_SIZE
+ TRX_SYS_RSEG_SPACE + page, MLOG_4BYTES);
srv_undo_space_id_start = space;
func_exit:
ut_free(buf);
ret = os_file_close(file);
ut_a(ret);
return error;
}
/****************************************************************************
Populates the tablespace memory cache by scanning for and opening data files.
@returns DB_SUCCESS or error code.*/
......@@ -3132,6 +3211,12 @@ xb_load_tablespaces(void)
/* Add separate undo tablespaces to fil_system */
err = xb_assign_undo_space_start();
if (err != DB_SUCCESS) {
return err;
}
err = srv_undo_tablespaces_init(FALSE,
TRUE,
srv_undo_tablespaces,
......
--debug=d,innodb_undo_upgrade
--innodb_undo_tablespaces=2
# Create 2 UNDO TABLESPACE(UNDO003, UNDO004)
CREATE TABLE t1(a varchar(60)) ENGINE INNODB;
start transaction;
INSERT INTO t1 VALUES(1);
# xtrabackup backup
# Display undo log files from target directory
undo003
undo004
# xtrabackup prepare
# Display undo log files from targer directory
undo003
undo004
DROP TABLE t1;
--source include/have_innodb.inc
--source include/have_debug.inc
--echo # Create 2 UNDO TABLESPACE(UNDO003, UNDO004)
let $basedir=$MYSQLTEST_VARDIR/tmp/backup;
CREATE TABLE t1(a varchar(60)) ENGINE INNODB;
start transaction;
INSERT INTO t1 VALUES(1);
--echo # xtrabackup backup
--disable_result_log
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir;
--enable_result_log
--echo # Display undo log files from target directory
list_files $basedir undo*;
--echo # xtrabackup prepare
exec $XTRABACKUP --prepare --apply-log-only --target-dir=$basedir;
--echo # Display undo log files from targer directory
list_files $basedir undo*;
DROP TABLE t1;
rmdir $basedir;
......@@ -1505,14 +1505,12 @@ srv_undo_tablespaces_init(
if (backup_mode) {
ut_ad(!create_new_db);
/* MDEV-13561 FIXME: Determine srv_undo_space_id_start
from the undo001 file. */
srv_undo_space_id_start = 1;
for (i = 0; i < n_undo_tablespaces; i++) {
undo_tablespace_ids[i]
= i + srv_undo_space_id_start;
}
prev_space_id = srv_undo_space_id_start - 1;
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment