Commit 33f70c4d authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-13869 MariaDB slow start

When code from MySQL 5.7.9 was merged to MariaDB 10.2.2
in commit 2e814d47
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.
parent 7a106d19
......@@ -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;
......
......@@ -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'");
......
......@@ -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
......
/*****************************************************************************
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 @@ dict_load_table_one(
} 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;
......
......@@ -624,6 +624,7 @@ fil_node_open_file(
<< " 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 @@ fil_node_open_file(
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(
......
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