Commit eb1f8b29 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-32027 Opening all .ibd files on InnoDB startup can be slow

dict_find_max_space_id(): Return SELECT MAX(SPACE) FROM SYS_TABLES.

dict_check_tablespaces_and_store_max_id(): In the normal case
(no encryption plugin has been loaded and the change buffer is empty),
invoke dict_find_max_space_id() and do not open any .ibd files.
If a std::set<uint32_t> has been specified, open the files whose
tablespace ID is mentioned. Else, open all data files that are identified
by SYS_TABLES records.

fil_ibd_open(): Remove a call to os_file_get_last_error() that can
report a misleading error, such as EINVAL inside my_realpath() that is
not an actual error. This could be invoked when a data file is found
but the FSP_SPACE_FLAGS are incorrect, such as is the case for
table test.td in
./mtr --mysqld=--innodb-buffer-pool-dump-at-shutdown=0 innodb.table_flags

buf_load(): If any tablespaces could not be found, invoke
dict_check_tablespaces_and_store_max_id() on the missing tablespaces.

dict_load_tablespace(): Try to load the tablespace unless it was found
to be futile. This fixes failures related to FTS_*.ibd files for
FULLTEXT INDEX.

btr_cur_t::search_leaf(): Prevent a crash when the tablespace
does not exist. This was caught by the test innodb_fts.fts_concurrent_insert
when the change to dict_load_tablespaces() was not present.

We modify a few tests to ensure that tables will not be loaded at startup.
For some fault injection tests this means that the corrupted tables
will not be loaded, because dict_load_tablespace() would perform stricter
checks than dict_check_tablespaces_and_store_max_id().

Tested by: Matthias Leich
Reviewed by: Thirunarayanan Balathandayuthapani
parent 44b9e416
...@@ -68,9 +68,8 @@ DROP TABLE t1; ...@@ -68,9 +68,8 @@ DROP TABLE t1;
Warnings: Warnings:
Warning 1932 Table 'test.t1' doesn't exist in engine Warning 1932 Table 'test.t1' doesn't exist in engine
DROP TABLE t2,t3; DROP TABLE t2,t3;
FOUND 6 /\[ERROR\] InnoDB: Table test/t1 in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=1 SYS_TABLES\.MIX_LEN=511\b/ in mysqld.1.err FOUND 5 /\[ERROR\] InnoDB: Table test/t1 in InnoDB data dictionary contains invalid flags\. SYS_TABLES\.TYPE=1 SYS_TABLES\.MIX_LEN=511\b/ in mysqld.1.err
# restart # restart
ib_buffer_pool
ib_logfile0 ib_logfile0
ibdata1 ibdata1
db.opt db.opt
...@@ -101,13 +101,9 @@ ERROR 42S02: Table 'test.tc' doesn't exist in engine ...@@ -101,13 +101,9 @@ ERROR 42S02: Table 'test.tc' doesn't exist in engine
SELECT * FROM tc; SELECT * FROM tc;
ERROR 42S02: Table 'test.tc' doesn't exist in engine ERROR 42S02: Table 'test.tc' doesn't exist in engine
SHOW CREATE TABLE td; SHOW CREATE TABLE td;
Table Create Table ERROR HY000: Got error 194 "Tablespace is missing for a table" from storage engine InnoDB
td CREATE TABLE `td` (
`a` int(11) NOT NULL,
PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC
SELECT * FROM td; SELECT * FROM td;
a ERROR HY000: Got error 194 "Tablespace is missing for a table" from storage engine InnoDB
SHOW CREATE TABLE tz; SHOW CREATE TABLE tz;
Table Create Table Table Create Table
tz CREATE TABLE `tz` ( tz CREATE TABLE `tz` (
...@@ -122,8 +118,8 @@ a ...@@ -122,8 +118,8 @@ a
42 42
SHOW CREATE TABLE tp; SHOW CREATE TABLE tp;
ERROR 42S02: Table 'test.tp' doesn't exist in engine ERROR 42S02: Table 'test.tp' doesn't exist in engine
FOUND 5 /InnoDB: Table test/t[cp] 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 3 /InnoDB: Table test/t[cp] 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 FOUND 1 /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) Restoring SYS_TABLES clustered index root page (8)
# restart: with restart_parameters # restart: with restart_parameters
SHOW CREATE TABLE tr; SHOW CREATE TABLE tr;
......
--innodb-checksum-algorithm=crc32 --innodb-checksum-algorithm=crc32
--skip-innodb-fast-shutdown
--skip-innodb-buffer-pool-dump-at-shutdown
--innodb-checksum-algorithm=crc32 --innodb-checksum-algorithm=crc32
--skip-innodb-read-only-compressed --skip-innodb-read-only-compressed
--skip-innodb-buffer-pool-dump-at-shutdown
...@@ -157,7 +157,9 @@ SHOW CREATE TABLE tr; ...@@ -157,7 +157,9 @@ SHOW CREATE TABLE tr;
SHOW CREATE TABLE tc; SHOW CREATE TABLE tc;
--error ER_NO_SUCH_TABLE_IN_ENGINE --error ER_NO_SUCH_TABLE_IN_ENGINE
SELECT * FROM tc; SELECT * FROM tc;
--error ER_GET_ERRNO
SHOW CREATE TABLE td; SHOW CREATE TABLE td;
--error ER_GET_ERRNO
SELECT * FROM td; SELECT * FROM td;
# This table was converted to NO_ROLLBACK due to the SYS_TABLES.TYPE change. # This table was converted to NO_ROLLBACK due to the SYS_TABLES.TYPE change.
SHOW CREATE TABLE tz; SHOW CREATE TABLE tz;
......
...@@ -527,15 +527,6 @@ Variable_name Value ...@@ -527,15 +527,6 @@ Variable_name Value
innodb_file_per_table ON innodb_file_per_table ON
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles === === information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Page_Size Zip_Size Path Space_Name Page_Size Zip_Size Path
test/t4_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t4_restart.ibd
test/t6_restart#p#p0 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p0.ibd
test/t6_restart#p#p1 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p1.ibd
test/t7_restart#p#p0#sp#s0 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s0.ibd
test/t7_restart#p#p0#sp#s1 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p0#sp#s1.ibd
test/t5_restart DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t5_restart.ibd
test/t6_restart#p#p2 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t6_restart#p#p2.ibd
test/t7_restart#p#p1#sp#s2 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s2.ibd
test/t7_restart#p#p1#sp#s3 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t7_restart#p#p1#sp#s3.ibd
innodb_temporary DEFAULT DEFAULT MYSQLD_DATADIR/ibtmp1 innodb_temporary DEFAULT DEFAULT MYSQLD_DATADIR/ibtmp1
SELECT count(*) FROM t5_restart; SELECT count(*) FROM t5_restart;
count(*) count(*)
...@@ -629,7 +620,6 @@ RENAME TABLE t6_restart TO t66_restart; ...@@ -629,7 +620,6 @@ RENAME TABLE t6_restart TO t66_restart;
RENAME TABLE t7_restart TO t77_restart; RENAME TABLE t7_restart TO t77_restart;
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles === === information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Page_Size Zip_Size Path Space_Name Page_Size Zip_Size Path
test/t4_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t4_restart.ibd
test/t66_restart#p#p0 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p0.ibd test/t66_restart#p#p0 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p0.ibd
test/t66_restart#p#p1 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p1.ibd test/t66_restart#p#p1 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p1.ibd
test/t77_restart#p#p0#sp#s0 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s0.ibd test/t77_restart#p#p0#sp#s0 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s0.ibd
...@@ -728,15 +718,6 @@ Variable_name Value ...@@ -728,15 +718,6 @@ Variable_name Value
innodb_file_per_table ON innodb_file_per_table ON
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles === === information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Page_Size Zip_Size Path Space_Name Page_Size Zip_Size Path
test/t4_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t4_restart.ibd
test/t66_restart#p#p0 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p0.ibd
test/t66_restart#p#p1 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p1.ibd
test/t77_restart#p#p0#sp#s0 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s0.ibd
test/t77_restart#p#p0#sp#s1 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p0#sp#s1.ibd
test/t55_restart DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t55_restart.ibd
test/t66_restart#p#p2 DEFAULT 2048 MYSQL_TMP_DIR/alt_dir/test/t66_restart#p#p2.ibd
test/t77_restart#p#p1#sp#s2 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s2.ibd
test/t77_restart#p#p1#sp#s3 DEFAULT DEFAULT MYSQL_TMP_DIR/alt_dir/test/t77_restart#p#p1#sp#s3.ibd
innodb_temporary DEFAULT DEFAULT MYSQLD_DATADIR/ibtmp1 innodb_temporary DEFAULT DEFAULT MYSQLD_DATADIR/ibtmp1
INSERT INTO t55_restart (SELECT 0, c2, c3, c4, c5 FROM t55_restart); INSERT INTO t55_restart (SELECT 0, c2, c3, c4, c5 FROM t55_restart);
SELECT count(*) FROM t55_restart; SELECT count(*) FROM t55_restart;
...@@ -863,15 +844,6 @@ t77_restart#p#p1#sp#s3.ibd ...@@ -863,15 +844,6 @@ t77_restart#p#p1#sp#s3.ibd
# restart # restart
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles === === information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Page_Size Zip_Size Path Space_Name Page_Size Zip_Size Path
test/t4_restart DEFAULT DEFAULT MYSQL_TMP_DIR/new_dir/test/t4_restart.ibd
test/t66_restart#p#p0 DEFAULT 2048 MYSQL_TMP_DIR/new_dir/test/t66_restart#p#p0.ibd
test/t66_restart#p#p1 DEFAULT 2048 MYSQL_TMP_DIR/new_dir/test/t66_restart#p#p1.ibd
test/t77_restart#p#p0#sp#s0 DEFAULT DEFAULT MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p0#sp#s0.ibd
test/t77_restart#p#p0#sp#s1 DEFAULT DEFAULT MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p0#sp#s1.ibd
test/t55_restart DEFAULT DEFAULT MYSQL_TMP_DIR/new_dir/test/t55_restart.ibd
test/t66_restart#p#p2 DEFAULT 2048 MYSQL_TMP_DIR/new_dir/test/t66_restart#p#p2.ibd
test/t77_restart#p#p1#sp#s2 DEFAULT DEFAULT MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p1#sp#s2.ibd
test/t77_restart#p#p1#sp#s3 DEFAULT DEFAULT MYSQL_TMP_DIR/new_dir/test/t77_restart#p#p1#sp#s3.ibd
innodb_temporary DEFAULT DEFAULT MYSQLD_DATADIR/ibtmp1 innodb_temporary DEFAULT DEFAULT MYSQLD_DATADIR/ibtmp1
INSERT INTO t4_restart (SELECT 0, c2, c3, c4, c5 FROM t4_restart); INSERT INTO t4_restart (SELECT 0, c2, c3, c4, c5 FROM t4_restart);
SELECT count(*) FROM t4_restart; SELECT count(*) FROM t4_restart;
...@@ -1002,15 +974,6 @@ t77_restart.par ...@@ -1002,15 +974,6 @@ t77_restart.par
# restart # restart
=== information_schema.innodb_sys_tablespaces and innodb_sys_datafiles === === information_schema.innodb_sys_tablespaces and innodb_sys_datafiles ===
Space_Name Page_Size Zip_Size Path Space_Name Page_Size Zip_Size Path
test/t4_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t4_restart.ibd
test/t66_restart#p#p0 DEFAULT 2048 MYSQLD_DATADIR/test/t66_restart#p#p0.ibd
test/t66_restart#p#p1 DEFAULT 2048 MYSQLD_DATADIR/test/t66_restart#p#p1.ibd
test/t77_restart#p#p0#sp#s0 DEFAULT DEFAULT MYSQLD_DATADIR/test/t77_restart#p#p0#sp#s0.ibd
test/t77_restart#p#p0#sp#s1 DEFAULT DEFAULT MYSQLD_DATADIR/test/t77_restart#p#p0#sp#s1.ibd
test/t55_restart DEFAULT DEFAULT MYSQLD_DATADIR/test/t55_restart.ibd
test/t66_restart#p#p2 DEFAULT 2048 MYSQLD_DATADIR/test/t66_restart#p#p2.ibd
test/t77_restart#p#p1#sp#s2 DEFAULT DEFAULT MYSQLD_DATADIR/test/t77_restart#p#p1#sp#s2.ibd
test/t77_restart#p#p1#sp#s3 DEFAULT DEFAULT MYSQLD_DATADIR/test/t77_restart#p#p1#sp#s3.ibd
innodb_temporary DEFAULT DEFAULT MYSQLD_DATADIR/ibtmp1 innodb_temporary DEFAULT DEFAULT MYSQLD_DATADIR/ibtmp1
INSERT INTO t4_restart (SELECT 0, c2, c3, c4, c5 FROM t4_restart); INSERT INTO t4_restart (SELECT 0, c2, c3, c4, c5 FROM t4_restart);
SELECT count(*) FROM t4_restart; SELECT count(*) FROM t4_restart;
......
--loose-innodb-sys-tables --innodb-sys-tables
--loose-innodb-sys-tablespaces --innodb-sys-tablespaces
--skip-innodb-stats-persistent
--skip-innodb-buffer-pool-dump-at-shutdown
--skip-innodb-fast-shutdown
...@@ -1155,6 +1155,19 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode, ...@@ -1155,6 +1155,19 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode,
mtr_s_lock_index(index(), mtr); mtr_s_lock_index(index(), mtr);
} }
dberr_t err;
if (!index()->table->space)
{
corrupted:
ut_ad("corrupted" == 0); // FIXME: remove this
err= DB_CORRUPTION;
func_exit:
if (UNIV_LIKELY_NULL(heap))
mem_heap_free(heap);
return err;
}
const ulint zip_size= index()->table->space->zip_size(); const ulint zip_size= index()->table->space->zip_size();
/* Start with the root page. */ /* Start with the root page. */
...@@ -1168,7 +1181,6 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode, ...@@ -1168,7 +1181,6 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode,
low_bytes= 0; low_bytes= 0;
ulint buf_mode= BUF_GET; ulint buf_mode= BUF_GET;
search_loop: search_loop:
dberr_t err;
auto block_savepoint= mtr->get_savepoint(); auto block_savepoint= mtr->get_savepoint();
buf_block_t *block= buf_block_t *block=
buf_page_get_gen(page_id, zip_size, rw_latch, guess, buf_mode, mtr, buf_page_get_gen(page_id, zip_size, rw_latch, guess, buf_mode, mtr,
...@@ -1180,10 +1192,7 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode, ...@@ -1180,10 +1192,7 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode,
btr_decryption_failed(*index()); btr_decryption_failed(*index());
/* fall through */ /* fall through */
default: default:
func_exit: goto func_exit;
if (UNIV_LIKELY_NULL(heap))
mem_heap_free(heap);
return err;
case DB_SUCCESS: case DB_SUCCESS:
/* This must be a search to perform an insert, delete mark, or delete; /* This must be a search to perform an insert, delete mark, or delete;
try using the change buffer */ try using the change buffer */
...@@ -1250,12 +1259,7 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode, ...@@ -1250,12 +1259,7 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode,
btr_page_get_index_id(block->page.frame) != index()->id || btr_page_get_index_id(block->page.frame) != index()->id ||
fil_page_get_type(block->page.frame) == FIL_PAGE_RTREE || fil_page_get_type(block->page.frame) == FIL_PAGE_RTREE ||
!fil_page_index_page_check(block->page.frame)) !fil_page_index_page_check(block->page.frame))
{ goto corrupted;
corrupted:
ut_ad("corrupted" == 0); // FIXME: remove this
err= DB_CORRUPTION;
goto func_exit;
}
page_cur.block= block; page_cur.block= block;
ut_ad(block == mtr->at_savepoint(block_savepoint)); ut_ad(block == mtr->at_savepoint(block_savepoint));
......
...@@ -33,7 +33,7 @@ Created April 08, 2011 Vasil Dimov ...@@ -33,7 +33,7 @@ Created April 08, 2011 Vasil Dimov
#include "buf0rea.h" #include "buf0rea.h"
#include "buf0dump.h" #include "buf0dump.h"
#include "dict0dict.h" #include "dict0load.h"
#include "os0file.h" #include "os0file.h"
#include "srv0srv.h" #include "srv0srv.h"
#include "srv0start.h" #include "srv0start.h"
...@@ -557,6 +557,22 @@ buf_load() ...@@ -557,6 +557,22 @@ buf_load()
if (!SHUTTING_DOWN()) { if (!SHUTTING_DOWN()) {
std::sort(dump, dump + dump_n); std::sort(dump, dump + dump_n);
std::set<uint32_t> missing;
for (const page_id_t id : st_::span<const page_id_t>
(dump, dump_n)) {
missing.emplace(id.space());
}
for (std::set<uint32_t>::iterator i = missing.begin();
i != missing.end(); ) {
auto j = i++;
if (fil_space_t* space = fil_space_t::get(*j)) {
space->release();
missing.erase(j);
}
}
if (!missing.empty()) {
dict_check_tablespaces_and_store_max_id(&missing);
}
} }
/* Avoid calling the expensive fil_space_t::get() for each /* Avoid calling the expensive fil_space_t::get() for each
......
...@@ -33,8 +33,8 @@ Created 4/24/1996 Heikki Tuuri ...@@ -33,8 +33,8 @@ Created 4/24/1996 Heikki Tuuri
#include "dict0boot.h" #include "dict0boot.h"
#include "dict0crea.h" #include "dict0crea.h"
#include "dict0dict.h" #include "dict0dict.h"
#include "dict0mem.h"
#include "dict0stats.h" #include "dict0stats.h"
#include "ibuf0ibuf.h"
#include "fsp0file.h" #include "fsp0file.h"
#include "fts0priv.h" #include "fts0priv.h"
#include "mach0data.h" #include "mach0data.h"
...@@ -867,18 +867,30 @@ dict_sys_tables_rec_read( ...@@ -867,18 +867,30 @@ dict_sys_tables_rec_read(
return READ_OK; return READ_OK;
} }
/** Check each tablespace found in the data dictionary. /** @return SELECT MAX(space) FROM sys_tables */
Then look at each table defined in SYS_TABLES that has a space_id > 0 static uint32_t dict_find_max_space_id(btr_pcur_t *pcur, mtr_t *mtr)
to find all the file-per-table tablespaces. {
uint32_t max_space_id= 0;
In a crash recovery we already have some tablespace objects created from for (const rec_t *rec= dict_startscan_system(pcur, mtr, dict_sys.sys_tables);
processing the REDO log. We will compare the rec; rec= dict_getnext_system_low(pcur, mtr))
space_id information in the data dictionary to what we find in the if (!dict_sys_tables_rec_check(rec))
tablespace file. In addition, more validation will be done if recovery {
was needed and force_recovery is not set. ulint len;
const byte *field=
rec_get_nth_field_old(rec, DICT_FLD__SYS_TABLES__SPACE, &len);
ut_ad(len == 4);
max_space_id= std::max(max_space_id, mach_read_from_4(field));
}
return max_space_id;
}
We also scan the biggest space id, and store it to fil_system. */ /** Check MAX(SPACE) FROM SYS_TABLES and store it in fil_system.
void dict_check_tablespaces_and_store_max_id() Open each data file if an encryption plugin has been loaded.
@param spaces set of tablespace files to open */
void dict_check_tablespaces_and_store_max_id(const std::set<uint32_t> *spaces)
{ {
ulint max_space_id = 0; ulint max_space_id = 0;
btr_pcur_t pcur; btr_pcur_t pcur;
...@@ -890,6 +902,12 @@ void dict_check_tablespaces_and_store_max_id() ...@@ -890,6 +902,12 @@ void dict_check_tablespaces_and_store_max_id()
dict_sys.lock(SRW_LOCK_CALL); dict_sys.lock(SRW_LOCK_CALL);
if (!spaces && ibuf.empty
&& !encryption_key_id_exists(FIL_DEFAULT_ENCRYPTION_KEY)) {
max_space_id = dict_find_max_space_id(&pcur, &mtr);
goto done;
}
for (const rec_t *rec = dict_startscan_system(&pcur, &mtr, for (const rec_t *rec = dict_startscan_system(&pcur, &mtr,
dict_sys.sys_tables); dict_sys.sys_tables);
rec; rec = dict_getnext_system_low(&pcur, &mtr)) { rec; rec = dict_getnext_system_low(&pcur, &mtr)) {
...@@ -921,14 +939,6 @@ void dict_check_tablespaces_and_store_max_id() ...@@ -921,14 +939,6 @@ void dict_check_tablespaces_and_store_max_id()
continue; continue;
} }
if (flags2 & DICT_TF2_DISCARDED) {
sql_print_information("InnoDB: Ignoring tablespace"
" for %.*s because "
"the DISCARD flag is set",
static_cast<int>(len), field);
continue;
}
/* For tables or partitions using .ibd files, the flag /* For tables or partitions using .ibd files, the flag
DICT_TF2_USE_FILE_PER_TABLE was not set in MIX_LEN DICT_TF2_USE_FILE_PER_TABLE was not set in MIX_LEN
before MySQL 5.6.5. The flag should not have been before MySQL 5.6.5. The flag should not have been
...@@ -941,6 +951,19 @@ void dict_check_tablespaces_and_store_max_id() ...@@ -941,6 +951,19 @@ void dict_check_tablespaces_and_store_max_id()
continue; continue;
} }
if (spaces && spaces->find(uint32_t(space_id))
== spaces->end()) {
continue;
}
if (flags2 & DICT_TF2_DISCARDED) {
sql_print_information("InnoDB: Ignoring tablespace"
" for %.*s because "
"the DISCARD flag is set",
static_cast<int>(len), field);
continue;
}
const span<const char> name{field, len}; const span<const char> name{field, len};
char* filepath = fil_make_filepath(nullptr, name, char* filepath = fil_make_filepath(nullptr, name,
...@@ -973,6 +996,7 @@ void dict_check_tablespaces_and_store_max_id() ...@@ -973,6 +996,7 @@ void dict_check_tablespaces_and_store_max_id()
ut_free(filepath); ut_free(filepath);
} }
done:
mtr.commit(); mtr.commit();
fil_set_max_space_id_if_bigger(max_space_id); fil_set_max_space_id_if_bigger(max_space_id);
...@@ -2248,22 +2272,10 @@ dict_load_tablespace( ...@@ -2248,22 +2272,10 @@ dict_load_tablespace(
/* The tablespace may already be open. */ /* The tablespace may already be open. */
table->space = fil_space_for_table_exists_in_mem(table->space_id, table->space = fil_space_for_table_exists_in_mem(table->space_id,
table->flags); table->flags);
if (table->space) { if (table->space || table->file_unreadable) {
return; return;
} }
if (ignore_err >= DICT_ERR_IGNORE_TABLESPACE) {
table->file_unreadable = true;
return;
}
if (!(ignore_err & DICT_ERR_IGNORE_RECOVER_LOCK)) {
ib::error() << "Failed to find tablespace for table "
<< table->name << " in the cache. Attempting"
" to load the tablespace with space id "
<< table->space_id;
}
/* Use the remote filepath if needed. This parameter is optional /* Use the remote filepath if needed. This parameter is optional
in the call to fil_ibd_open(). If not supplied, it will be built in the call to fil_ibd_open(). If not supplied, it will be built
from the table->name. */ from the table->name. */
...@@ -2286,6 +2298,12 @@ dict_load_tablespace( ...@@ -2286,6 +2298,12 @@ dict_load_tablespace(
if (!table->space) { if (!table->space) {
/* We failed to find a sensible tablespace file */ /* We failed to find a sensible tablespace file */
table->file_unreadable = true; table->file_unreadable = true;
if (!(ignore_err & DICT_ERR_IGNORE_RECOVER_LOCK)) {
sql_print_error("InnoDB: Failed to load tablespace "
ULINTPF " for table %s",
table->space_id, table->name);
}
} }
ut_free(filepath); ut_free(filepath);
......
...@@ -2221,8 +2221,6 @@ fil_ibd_open( ...@@ -2221,8 +2221,6 @@ fil_ibd_open(
goto corrupted; goto corrupted;
} }
os_file_get_last_error(operation_not_for_export,
!operation_not_for_export);
if (!operation_not_for_export) { if (!operation_not_for_export) {
goto corrupted; goto corrupted;
} }
......
...@@ -35,22 +35,16 @@ Created 4/24/1996 Heikki Tuuri ...@@ -35,22 +35,16 @@ Created 4/24/1996 Heikki Tuuri
#include "btr0types.h" #include "btr0types.h"
#include <deque> #include <deque>
#include <set>
/** A stack of table names related through foreign key constraints */ /** A stack of table names related through foreign key constraints */
typedef std::deque<const char*, ut_allocator<const char*> > dict_names_t; typedef std::deque<const char*, ut_allocator<const char*> > dict_names_t;
/** Check each tablespace found in the data dictionary. /** Check MAX(SPACE) FROM SYS_TABLES and store it in fil_system.
Then look at each table defined in SYS_TABLES that has a space_id > 0 Open each data file if an encryption plugin has been loaded.
to find all the file-per-table tablespaces.
In a crash recovery we already have some tablespace objects created from @param spaces set of tablespace files to open */
processing the REDO log. We will compare the void dict_check_tablespaces_and_store_max_id(const std::set<uint32_t> *spaces);
space_id information in the data dictionary to what we find in the
tablespace file. In addition, more validation will be done if recovery
was needed and force_recovery is not set.
We also scan the biggest space id, and store it to fil_system. */
void dict_check_tablespaces_and_store_max_id();
/** Make sure the data_file_name is saved in dict_table_t if needed. /** Make sure the data_file_name is saved in dict_table_t if needed.
@param[in,out] table Table object */ @param[in,out] table Table object */
......
...@@ -1819,21 +1819,13 @@ dberr_t srv_start(bool create_new_db) ...@@ -1819,21 +1819,13 @@ dberr_t srv_start(bool create_new_db)
} }
if (srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN) { if (srv_force_recovery < SRV_FORCE_NO_UNDO_LOG_SCAN) {
/* The following call is necessary for the insert /* The following call is necessary for the change
buffer to work with multiple tablespaces. We must buffer to work with multiple tablespaces. We must
know the mapping between space id's and .ibd file know the mapping between space id's and .ibd file
names. names.
In a crash recovery, we check that the info in data
dictionary is consistent with what we already know
about space id's from the calls to fil_ibd_load().
In a normal startup, we create the space objects for
every table in the InnoDB data dictionary that has
an .ibd file.
We also determine the maximum tablespace id used. */ We also determine the maximum tablespace id used. */
dict_check_tablespaces_and_store_max_id(); dict_check_tablespaces_and_store_max_id(nullptr);
} }
if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO if (srv_force_recovery < SRV_FORCE_NO_TRX_UNDO
......
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