diff options
author | Vladislav Vaintroub <wlad@mariadb.com> | 2017-11-23 21:01:00 +0000 |
---|---|---|
committer | Vladislav Vaintroub <wlad@mariadb.com> | 2017-11-24 00:01:29 +0000 |
commit | 316f0d8fe3f3eda61bfe1025ef59a93dde3c753b (patch) | |
tree | a2bf5a19a26dfa91a84f32aac53f274ed9574eb9 | |
parent | 12840f97cd3f768b64b6ddfc863b3ebfce6b2740 (diff) | |
download | mariadb-git-316f0d8fe3f3eda61bfe1025ef59a93dde3c753b.tar.gz |
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.
-rw-r--r-- | extra/mariabackup/xtrabackup.cc | 27 | ||||
-rwxr-xr-x | mysql-test/mysql-test-run.pl | 2 | ||||
-rw-r--r-- | mysql-test/suite/mariabackup/mdev-14447.opt | 1 | ||||
-rw-r--r-- | mysql-test/suite/mariabackup/mdev-14447.result | 19 | ||||
-rw-r--r-- | mysql-test/suite/mariabackup/mdev-14447.test | 46 |
5 files changed, 90 insertions, 5 deletions
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 2f9761eb0ec..a50504be274 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -4955,10 +4955,29 @@ xtrabackup_apply_delta( const os_offset_t off = os_offset_t(offset_on_page)*page_size; if (off == 0) { - /* Fix tablespace size. */ - os_offset_t n_pages = fsp_get_size_low(static_cast<ib_page_t *>(buf)); - if (!os_file_set_size(dst_path, dst_file, n_pages*page_size)) - goto error; + /* Read tablespace size from page 0, + 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)) + 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); diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index ac9f493dc84..3b1bb0b5cb0 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -2817,7 +2817,7 @@ sub mysql_server_start($) { # Some InnoDB options are incompatible with the default bootstrap. # If they are used, re-bootstrap 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); } diff --git a/mysql-test/suite/mariabackup/mdev-14447.opt b/mysql-test/suite/mariabackup/mdev-14447.opt new file mode 100644 index 00000000000..5ac67e950c4 --- /dev/null +++ b/mysql-test/suite/mariabackup/mdev-14447.opt @@ -0,0 +1 @@ +--sequence --innodb-data-file-path=ibdata_first:3M;ibdata_second:1M:autoextend
\ No newline at end of file diff --git a/mysql-test/suite/mariabackup/mdev-14447.result b/mysql-test/suite/mariabackup/mdev-14447.result new file mode 100644 index 00000000000..3bca7eb5701 --- /dev/null +++ b/mysql-test/suite/mariabackup/mdev-14447.result @@ -0,0 +1,19 @@ +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; diff --git a/mysql-test/suite/mariabackup/mdev-14447.test b/mysql-test/suite/mariabackup/mdev-14447.test new file mode 100644 index 00000000000..48f37646231 --- /dev/null +++ b/mysql-test/suite/mariabackup/mdev-14447.test @@ -0,0 +1,46 @@ +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; |