summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2017-11-23 21:01:00 +0000
committerVladislav Vaintroub <wlad@mariadb.com>2017-11-24 00:01:29 +0000
commit316f0d8fe3f3eda61bfe1025ef59a93dde3c753b (patch)
treea2bf5a19a26dfa91a84f32aac53f274ed9574eb9
parent12840f97cd3f768b64b6ddfc863b3ebfce6b2740 (diff)
downloadmariadb-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.cc27
-rwxr-xr-xmysql-test/mysql-test-run.pl2
-rw-r--r--mysql-test/suite/mariabackup/mdev-14447.opt1
-rw-r--r--mysql-test/suite/mariabackup/mdev-14447.result19
-rw-r--r--mysql-test/suite/mariabackup/mdev-14447.test46
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;