Commit 316f0d8f authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

MDEV-14447 mariabackup incremental incorrectly extends system tablespace

for multi-file innodb_data_file_path.

Use fil_extend_space_to_desired_size() to correctly extend system
tablespace. Make sure to get tablespace size from the first tablespace
part.
parent 12840f97
...@@ -4955,10 +4955,29 @@ xtrabackup_apply_delta( ...@@ -4955,10 +4955,29 @@ xtrabackup_apply_delta(
const os_offset_t off = os_offset_t(offset_on_page)*page_size; const os_offset_t off = os_offset_t(offset_on_page)*page_size;
if (off == 0) { if (off == 0) {
/* Fix tablespace size. */ /* Read tablespace size from page 0,
os_offset_t n_pages = fsp_get_size_low(static_cast<ib_page_t *>(buf)); extend the tablespace to specified size. */
os_offset_t n_pages = mach_read_from_4(buf + FSP_HEADER_OFFSET + FSP_SIZE);
ulint space_id = mach_read_from_4(buf + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
if (space_id != TRX_SYS_SPACE) {
if (!os_file_set_size(dst_path, dst_file, n_pages*page_size)) if (!os_file_set_size(dst_path, dst_file, n_pages*page_size))
goto error; goto error;
} else {
/* System tablespace needs special handling , since
it can consist of multiple files. The first one has full
tablespace size in page 0, but only last file should be extended. */
mutex_enter(&fil_system->mutex);
fil_space_t* space = fil_space_get_by_id(space_id);
mutex_exit(&fil_system->mutex);
DBUG_ASSERT(space);
fil_node_t* n = UT_LIST_GET_FIRST(space->chain);
if(strcmp(n->name, dst_path) == 0) {
/* Got first tablespace file, with correct size */
ulint actual_size;
if (!fil_extend_space_to_desired_size(&actual_size, 0, (ulint)n_pages))
goto error;
}
}
} }
success = os_file_write(dst_path, dst_file, buf, off, page_size); success = os_file_write(dst_path, dst_file, buf, off, page_size);
......
...@@ -2817,7 +2817,7 @@ sub mysql_server_start($) { ...@@ -2817,7 +2817,7 @@ sub mysql_server_start($) {
# Some InnoDB options are incompatible with the default bootstrap. # Some InnoDB options are incompatible with the default bootstrap.
# If they are used, re-bootstrap # If they are used, re-bootstrap
if ( $extra_opts and if ( $extra_opts and
"@$extra_opts" =~ /--innodb[-_](?:page[-_]size|checksum[-_]algorithm|undo[-_]tablespaces|log[-_]group[-_]home[-_]dir|data[-_]home[-_]dir)/ ) "@$extra_opts" =~ /--innodb[-_](?:page[-_]size|checksum[-_]algorithm|undo[-_]tablespaces|log[-_]group[-_]home[-_]dir|data[-_]home[-_]dir)|data[-_]file[-_]path/ )
{ {
mysql_install_db($mysqld, undef, $extra_opts); mysql_install_db($mysqld, undef, $extra_opts);
} }
......
--sequence --innodb-data-file-path=ibdata_first:3M;ibdata_second:1M:autoextend
\ No newline at end of file
call mtr.add_suppression("InnoDB: New log files created");
CREATE TABLE t(a varchar(40) PRIMARY KEY, b varchar(40), c varchar(40), d varchar(40), index(b,c,d)) ENGINE INNODB;
# Create full backup , modify table, then create incremental/differential backup
BEGIN;
INSERT INTO t select uuid(), uuid(), uuid(), uuid() from seq_1_to_100000;
COMMIT;
SELECT count(*) FROM t;
count(*)
100000
# Prepare full backup, apply incremental one
# Restore and check results
# shutdown server
# remove datadir
# xtrabackup move back
# restart server
SELECT count(*) FROM t;
count(*)
100000
DROP TABLE t;
call mtr.add_suppression("InnoDB: New log files created");
let $basedir=$MYSQLTEST_VARDIR/tmp/backup;
let $incremental_dir=$MYSQLTEST_VARDIR/tmp/backup_inc1;
CREATE TABLE t(a varchar(40) PRIMARY KEY, b varchar(40), c varchar(40), d varchar(40), index(b,c,d)) ENGINE INNODB;
echo # Create full backup , modify table, then create incremental/differential backup;
--disable_result_log
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir;
--enable_result_log
BEGIN;
INSERT INTO t select uuid(), uuid(), uuid(), uuid() from seq_1_to_100000;
COMMIT;
SELECT count(*) FROM t;
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$incremental_dir --incremental-basedir=$basedir;
--disable_result_log
echo # Prepare full backup, apply incremental one;
exec $XTRABACKUP --prepare --apply-log-only --target-dir=$basedir;
exec $XTRABACKUP --prepare --apply-log-only --target-dir=$basedir --incremental-dir=$incremental_dir ;
echo # Restore and check results;
let $targetdir=$basedir;
#-- source include/restart_and_restore.inc
let $_datadir= `SELECT @@datadir`;
let $innodb_data_file_path=`SELECT @@innodb_data_file_path`;
echo # shutdown server;
--source include/shutdown_mysqld.inc
echo # remove datadir;
rmdir $_datadir;
echo # xtrabackup move back;
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --copy-back --datadir=$_datadir "--innodb_data_file_path=$innodb_data_file_path" --target-dir=$targetdir;
echo # restart server;
--source include/start_mysqld.inc
--enable_result_log
SELECT count(*) FROM t;
DROP TABLE t;
# Cleanup
rmdir $basedir;
rmdir $incremental_dir;
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