diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2018-02-12 13:35:07 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2018-02-12 14:06:04 +0200 |
commit | 33f70c4d9c42b6e4da062312e1e4a4fb370313df (patch) | |
tree | 470da84efdb0c461857cd3d0865c79e684074f30 | |
parent | 7a106d19614cb052ecf245e3825b9510e8029ba0 (diff) | |
download | mariadb-git-33f70c4d9c42b6e4da062312e1e4a4fb370313df.tar.gz |
MDEV-13869 MariaDB slow start
When code from MySQL 5.7.9 was merged to MariaDB 10.2.2
in commit 2e814d4702d71a04388386a9f591d14a35980bfe
an assignment validate=true was inadvertently added to the function
dict_check_sys_tables().
This causes InnoDB to open every single .ibd file on startup, even
when no crash recovery was needed.
Simply removing the assignment would make some tests fail. We do the
best to retain almost the same level of inconsistency detection.
In the test innodb.table_flags, access to one of the tables will not
be blocked despite inconsistent flags.
dict_check_sys_tables(): Remove the problematic assignment, and skip
validation in normal startup.
dict_load_table_one(): If the .ibd file cannot be opened, mark the
table as corrupted and unreadable.
fil_node_open_file(): Validate FSP_SPACE_FLAGS with the expected
flags. If reading the tablespace fails, invalidate node->handle
instead of letting it remain stale. This bug was caught by a
fil_validate() assertion failure.
fsp_flags_try_adjust(): If the tablespace file is invalid, do nothing.
-rw-r--r-- | mysql-test/suite/innodb/r/table_flags.result | 13 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/log_file_name.test | 1 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/table_flags.test | 5 | ||||
-rw-r--r-- | storage/innobase/dict/dict0load.cc | 10 | ||||
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 9 |
5 files changed, 28 insertions, 10 deletions
diff --git a/mysql-test/suite/innodb/r/table_flags.result b/mysql-test/suite/innodb/r/table_flags.result index 435fe8fc45e..3684242f765 100644 --- a/mysql-test/suite/innodb/r/table_flags.result +++ b/mysql-test/suite/innodb/r/table_flags.result @@ -116,14 +116,21 @@ SHOW CREATE TABLE tr; ERROR 42S02: Table 'test.tr' doesn't exist in engine SHOW CREATE TABLE tc; ERROR 42S02: Table 'test.tc' doesn't exist in engine +SELECT * FROM tc; +ERROR 42S02: Table 'test.tc' doesn't exist in engine SHOW CREATE TABLE td; -ERROR 42S02: Table 'test.td' doesn't exist in engine +Table Create Table +td CREATE TABLE `td` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=DYNAMIC +SELECT * FROM td; +a SHOW CREATE TABLE tz; ERROR 42S02: Table 'test.tz' doesn't exist in engine SHOW CREATE TABLE tp; ERROR 42S02: Table 'test.tp' doesn't exist in engine -FOUND 6 /InnoDB: Table `test`.`t[czp]` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=(129|289|3873|1232[13]) SYS_TABLES\.N_COLS=2147483649/ in mysqld.1.err -FOUND 2 /InnoDB: Refusing to load '\..test.td\.ibd' \(id=3, flags=0x1?[2ae]1\); dictionary contains id=3, flags=0x10[01][2ae]1\b/ in mysqld.1.err +FOUND 7 /InnoDB: Table `test`.`t[czp]` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=(129|289|3873|1232[13]) SYS_TABLES\.N_COLS=2147483649/ in mysqld.1.err FOUND 2 /InnoDB: Table `test`\.`tr` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=65 SYS_TABLES\.MIX_LEN=4294967295\b/ in mysqld.1.err Restoring SYS_TABLES clustered index root page (8) SHOW CREATE TABLE tr; diff --git a/mysql-test/suite/innodb/t/log_file_name.test b/mysql-test/suite/innodb/t/log_file_name.test index 2ee8c49aa7c..87c1681d443 100644 --- a/mysql-test/suite/innodb/t/log_file_name.test +++ b/mysql-test/suite/innodb/t/log_file_name.test @@ -163,6 +163,7 @@ call mtr.add_suppression("InnoDB: Cannot rename.*because the target file exists" call mtr.add_suppression("InnoDB: Log scan aborted at LSN"); # The following are for the --innodb-force-recovery=1 with broken u* tables: call mtr.add_suppression("InnoDB: Header page consists of zero bytes in datafile: .*u1.ibd"); +call mtr.add_suppression("InnoDB: The size of the file .*u1\\.ibd is only 16384 bytes, should be at least 65536"); call mtr.add_suppression("InnoDB: The error means the system cannot find the path specified"); call mtr.add_suppression("InnoDB: .*you must create directories"); call mtr.add_suppression("InnoDB: Cannot open datafile for read-only: '.*u[1-5]\.ibd'"); diff --git a/mysql-test/suite/innodb/t/table_flags.test b/mysql-test/suite/innodb/t/table_flags.test index b8ccc4ce4b6..02d5a744e2c 100644 --- a/mysql-test/suite/innodb/t/table_flags.test +++ b/mysql-test/suite/innodb/t/table_flags.test @@ -14,6 +14,7 @@ call mtr.add_suppression("InnoDB: Ignoring tablespace for `test`.`td` because it call mtr.add_suppression("InnoDB: Operating system error number .* in a file operation"); call mtr.add_suppression("InnoDB: The error means the system cannot find the path specified"); call mtr.add_suppression("InnoDB: If you are installing InnoDB, remember that you must create directories yourself"); +call mtr.add_suppression("InnoDB: adjusting FSP_SPACE_FLAGS of tablespace"); FLUSH TABLES; --enable_query_log @@ -133,7 +134,9 @@ SHOW CREATE TABLE tr; --error ER_NO_SUCH_TABLE_IN_ENGINE SHOW CREATE TABLE tc; --error ER_NO_SUCH_TABLE_IN_ENGINE +SELECT * FROM tc; SHOW CREATE TABLE td; +SELECT * FROM td; --error ER_NO_SUCH_TABLE_IN_ENGINE SHOW CREATE TABLE tz; --error ER_NO_SUCH_TABLE_IN_ENGINE @@ -144,8 +147,6 @@ SHOW CREATE TABLE tp; let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err; --let SEARCH_PATTERN= InnoDB: Table `test`.`t[czp]` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=(129|289|3873|1232[13]) SYS_TABLES\.N_COLS=2147483649 --source include/search_pattern_in_file.inc ---let SEARCH_PATTERN= InnoDB: Refusing to load '\..test.td\.ibd' \(id=3, flags=0x1?[2ae]1\); dictionary contains id=3, flags=0x10[01][2ae]1\b ---source include/search_pattern_in_file.inc --let SEARCH_PATTERN= InnoDB: Table `test`\.`tr` in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=65 SYS_TABLES\.MIX_LEN=4294967295\b --source include/search_pattern_in_file.inc diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index 15e14b9d9f7..3606b902510 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2017, MariaDB Corporation. +Copyright (c) 2016, 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 @@ -1471,8 +1471,6 @@ dict_check_sys_tables( char* filepath = dict_get_first_path(space_id); /* Check that the .ibd file exists. */ - validate = true; /* Encryption */ - dberr_t err = fil_ibd_open( validate, !srv_read_only_mode && srv_log_file_size != 0, @@ -3078,6 +3076,12 @@ err_exit: } else { dict_mem_table_fill_foreign_vcol_set(table); table->fk_max_recusive_level = 0; + + if (table->space + && !fil_space_get_size(table->space)) { + table->corrupted = true; + table->file_unreadable = true; + } } } else { dict_index_t* index; diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 0598b687d91..f3bb127020a 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -624,6 +624,7 @@ retry: << " is only " << size_bytes << " bytes, should be at least " << min_size; os_file_close(node->handle); + node->handle = OS_FILE_CLOSED; return(false); } @@ -661,10 +662,12 @@ retry: ut_free(buf2); os_file_close(node->handle); + node->handle = OS_FILE_CLOSED; if (!fsp_flags_is_valid(flags, space->id)) { ulint cflags = fsp_flags_convert_from_101(flags); - if (cflags == ULINT_UNDEFINED) { + if (cflags == ULINT_UNDEFINED + || (cflags ^ space->flags) & ~FSP_FLAGS_MEM_MASK) { ib::error() << "Expected tablespace flags " << ib::hex(space->flags) @@ -4626,7 +4629,9 @@ fsp_flags_try_adjust(ulint space_id, ulint flags) { ut_ad(!srv_read_only_mode); ut_ad(fsp_flags_is_valid(flags, space_id)); - + if (!fil_space_get_size(space_id)) { + return; + } mtr_t mtr; mtr.start(); if (buf_block_t* b = buf_page_get( |