diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2018-01-25 14:20:18 +0200 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2018-01-25 14:20:18 +0200 |
commit | 0ecb2d7223788acc8efe07250d36b1706eed4b16 (patch) | |
tree | e6cf8f698da50c5fffa2e87c841aa6080b63ec4d | |
parent | 524221e7a34d42214e82dd868348b453f2ef1591 (diff) | |
download | mariadb-git-0ecb2d7223788acc8efe07250d36b1706eed4b16.tar.gz |
MDEV-13284: mariadb-server: fil_load_single_table_tablespace(): mysqld killed by SIGABRTbb-10.1-MDEV-13284
MDEV-13499: Backing up table that "doesn't exist in engine" cause crash in mariabackup when using encryption
In both cases if .ibd file was missing we called abort() in
fil_load_single_table_tablespace().
fil_load_single_table_tablespace
Mofify function to return true when loading is successful
and false at failure. Rmove abort() call.
fil_load_single_tablespaces
If loading of single table tablespace failed set error.
-rw-r--r-- | mysql-test/suite/innodb/r/innodb-missing-file.result | 12 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/innodb-missing-file.test | 26 | ||||
-rw-r--r-- | mysql-test/suite/mariabackup/missing_ibd.result | 6 | ||||
-rw-r--r-- | mysql-test/suite/mariabackup/missing_ibd.test | 26 | ||||
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 37 | ||||
-rw-r--r-- | storage/xtradb/fil/fil0fil.cc | 42 |
6 files changed, 117 insertions, 32 deletions
diff --git a/mysql-test/suite/innodb/r/innodb-missing-file.result b/mysql-test/suite/innodb/r/innodb-missing-file.result new file mode 100644 index 00000000000..5c10d98e541 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-missing-file.result @@ -0,0 +1,12 @@ +call mtr.add_suppression("A link file was found named './test/t1.isl' but the linked tablespace .* could not be opened."); +call mtr.add_suppression("InnoDB: Error: could not open single-table tablespace file ./test/t1.ibd"); +call mtr.add_suppression("InnoDB: Table test/t1 in the InnoDB data dictionary has tablespace id [0-9]+, but tablespace with that id or name does not exist. Have you deleted or moved .ibd files\\? This may also be a table created with CREATE TEMPORARY TABLE whose .ibd and .frm files MySQL automatically removed, but the table still exists in the InnoDB internal data dictionary."); +Warnings: +Warning 1265 Data truncated for column 'pattern' at row 1 +set global innodb_file_format='Barracuda'; +CREATE TABLE t1(c1 INT) ENGINE=InnoDB DATA DIRECTORY='MYSQL_TMP_DIR'; +INSERT INTO t1 VALUES(1); +# Kill the server +select * from t1; +ERROR 42S02: Table 'test.t1' doesn't exist in engine +drop table t1; diff --git a/mysql-test/suite/innodb/t/innodb-missing-file.test b/mysql-test/suite/innodb/t/innodb-missing-file.test new file mode 100644 index 00000000000..451e29796ac --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-missing-file.test @@ -0,0 +1,26 @@ +-- source include/have_innodb.inc + +call mtr.add_suppression("A link file was found named './test/t1.isl' but the linked tablespace .* could not be opened."); +call mtr.add_suppression("InnoDB: Error: could not open single-table tablespace file ./test/t1.ibd"); +call mtr.add_suppression("InnoDB: Table test/t1 in the InnoDB data dictionary has tablespace id [0-9]+, but tablespace with that id or name does not exist. Have you deleted or moved .ibd files\\? This may also be a table created with CREATE TEMPORARY TABLE whose .ibd and .frm files MySQL automatically removed, but the table still exists in the InnoDB internal data dictionary."); + +--disable_warnings +set global innodb_file_format='Barracuda'; +--enable_warnings + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +EVAL CREATE TABLE t1(c1 INT) ENGINE=InnoDB DATA DIRECTORY='$MYSQL_TMP_DIR'; +INSERT INTO t1 VALUES(1); +let $MYSQLD_DATADIR = `SELECT @@datadir`; + +--source include/kill_mysqld.inc + +--copy_file $MYSQL_TMP_DIR/test/t1.ibd $MYSQL_TMP_DIR/test/t1_1.ibd +--remove_file $MYSQL_TMP_DIR/test/t1.ibd + +--source include/start_mysqld.inc +--error ER_NO_SUCH_TABLE_IN_ENGINE +select * from t1; +drop table t1; + +--remove_file $MYSQL_TMP_DIR/test/t1_1.ibd diff --git a/mysql-test/suite/mariabackup/missing_ibd.result b/mysql-test/suite/mariabackup/missing_ibd.result new file mode 100644 index 00000000000..53989be7c14 --- /dev/null +++ b/mysql-test/suite/mariabackup/missing_ibd.result @@ -0,0 +1,6 @@ +create table t1(c1 int) engine=InnoDB; +INSERT INTO t1 VALUES(1); +# xtrabackup backup +select * from t1; +ERROR 42S02: Table 'test.t1' doesn't exist in engine +drop table t1; diff --git a/mysql-test/suite/mariabackup/missing_ibd.test b/mysql-test/suite/mariabackup/missing_ibd.test new file mode 100644 index 00000000000..689d237aa8f --- /dev/null +++ b/mysql-test/suite/mariabackup/missing_ibd.test @@ -0,0 +1,26 @@ +--source include/have_innodb.inc + +create table t1(c1 int) engine=InnoDB; +INSERT INTO t1 VALUES(1); +let MYSQLD_DATADIR=`select @@datadir`; + +--source include/shutdown_mysqld.inc + +--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQL_TMP_DIR/t1.ibd +--remove_file $MYSQLD_DATADIR/test/t1.ibd + +--source include/start_mysqld.inc + +echo # xtrabackup backup; +let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +--enable_result_log + +rmdir $targetdir; + +--error ER_NO_SUCH_TABLE_IN_ENGINE +select * from t1; +drop table t1; + +--remove_file $MYSQL_TMP_DIR/t1.ibd diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index c9ecf3dab0b..11be527a2f3 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2017, MariaDB Corporation. +Copyright (c) 2014, 2018, MariaDB Corporation. 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 @@ -4585,16 +4585,17 @@ check_first_page: } -/********************************************************************//** -Opens an .ibd file and adds the associated single-table tablespace to the -InnoDB fil0fil.cc data structures. */ +/** Opens an .ibd file and adds the associated single-table tablespace to the +InnoDB fil0fil.cc data structures. +@param[in] dbname database name +@param[in] filename file name (not a path), including the + .ibd or .isl extension +@return true when success, false at failure. */ static -void +bool fil_load_single_table_tablespace( -/*=============================*/ - const char* dbname, /*!< in: database name */ - const char* filename) /*!< in: file name (not a path), - including the .ibd or .isl extension */ + const char* dbname, + const char* filename) { char* tablename; ulint tablename_len; @@ -4640,7 +4641,7 @@ fil_load_single_table_tablespace( if (space) { mem_free(tablename); mutex_exit(&fil_system->mutex); - return; + return true; } mutex_exit(&fil_system->mutex); @@ -4693,7 +4694,7 @@ fil_load_single_table_tablespace( fprintf(stderr, "InnoDB: Error: could not open single-table" " tablespace file %s. Encryption error!\n", def.filepath); - return; + return false; } /* The following call prints an error message */ @@ -4712,7 +4713,7 @@ fil_load_single_table_tablespace( if (def.filepath) { mem_free(def.filepath); } - return; + return true; } no_good_file: fprintf(stderr, @@ -4751,10 +4752,10 @@ will_not_choose: "Continuing crash recovery even though we " "cannot access the .ibd file of this table.", srv_force_recovery); - return; + return true; } - abort(); + return false; } if (def.success && remote.success) { @@ -4928,6 +4929,8 @@ func_exit_after_close: mem_free(remote.filepath); } mem_free(def.filepath); + + return true; } /***********************************************************************//** @@ -5058,8 +5061,12 @@ fil_load_single_table_tablespaces(void) ".isl"))) { /* The name ends in .ibd or .isl; try opening the file */ - fil_load_single_table_tablespace( + bool success = fil_load_single_table_tablespace( dbinfo.name, fileinfo.name); + + if (!success) { + err = DB_ERROR; + } } next_file_item: ret = fil_file_readdir_next_file(&err, diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index 9023b4446b5..0f12282c573 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2014, 2017, MariaDB Corporation. +Copyright (c) 2014, 2018, MariaDB Corporation. 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 @@ -4777,16 +4777,17 @@ check_first_page: } -/********************************************************************//** -Opens an .ibd file and adds the associated single-table tablespace to the -InnoDB fil0fil.cc data structures. */ +/** Opens an .ibd file and adds the associated single-table tablespace to the +InnoDB fil0fil.cc data structures. +@param[in] dbname database name +@param[in] filename file name (not a path), including the + .ibd or .isl extension +@return true when success, false at failure. */ static -void +bool fil_load_single_table_tablespace( -/*=============================*/ - const char* dbname, /*!< in: database name */ - const char* filename) /*!< in: file name (not a path), - including the .ibd or .isl extension */ + const char* dbname, + const char* filename) { char* tablename; ulint tablename_len; @@ -4836,7 +4837,7 @@ fil_load_single_table_tablespace( if (space) { mem_free(tablename); mutex_exit(&fil_system->mutex); - return; + return true; } mutex_exit(&fil_system->mutex); @@ -4925,7 +4926,7 @@ fil_load_single_table_tablespace( if (def.filepath) { mem_free(def.filepath); } - return; + return true; } no_good_file: fprintf(stderr, @@ -4964,10 +4965,10 @@ will_not_choose: "Continuing crash recovery even though we " "cannot access the .ibd file of this table.", srv_force_recovery); - return; + return true; } - abort(); + return false; } if (def.success && remote.success) { @@ -5180,6 +5181,8 @@ func_exit_after_close: mem_free(remote.filepath); } mem_free(def.filepath); + + return true; } /***********************************************************************//** @@ -5327,7 +5330,7 @@ fil_load_single_table_tablespaces(ibool (*pred)(const char*, const char*)) && (0 == strcmp(fileinfo.name + strlen(fileinfo.name) - 4, ".ibd") - || ((!IS_XTRABACKUP() || srv_backup_mode) + || ((!IS_XTRABACKUP() || srv_backup_mode) && 0 == strcmp(fileinfo.name + strlen(fileinfo.name) - 4, ".isl"))) @@ -5335,17 +5338,22 @@ fil_load_single_table_tablespaces(ibool (*pred)(const char*, const char*)) pred(dbinfo.name, fileinfo.name))) { /* The name ends in .ibd or .isl; try opening the file */ - fil_load_single_table_tablespace( + bool success = fil_load_single_table_tablespace( dbinfo.name, fileinfo.name); + + if (!success) { + err = DB_ERROR; + } + files_read++; if (files_read - files_read_at_last_check > CHECK_TIME_EVERY_N_FILES) { ib_time_t cur_time= ut_time(); files_read_at_last_check= files_read; - double time_elapsed= ut_difftime(cur_time, + double time_elapsed= ut_difftime(cur_time, prev_report_time); if (time_elapsed > 15) { - ib_logf(IB_LOG_LEVEL_INFO, + ib_logf(IB_LOG_LEVEL_INFO, "Processed %ld .ibd/.isl files", files_read); prev_report_time= cur_time; |