Skip to content

Commit 31e69d1

Browse files
Rahul Agarkardahlerlend
authored andcommitted
Bug#30108154 - SLOW STARTUP FOR MYSQL 8.0 WITH MANY TABLES DUE TO THE TABLESPACE FILES SCAN
Post-push fix: Fix test failures reported on ASAN and Windows The test failed because the server could not find the space id because of the corrupted header page. Modified the code to fall back to the heavier method of finding the space id by traversing all the pages in the tablespace. RB# 23455 Reviewed by: Mayank Prasad ([email protected])
1 parent d4ac4b3 commit 31e69d1

File tree

1 file changed

+33
-26
lines changed

1 file changed

+33
-26
lines changed

storage/innobase/fil/fil0fil.cc

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10671,37 +10671,46 @@ space_id_t Fil_system::get_tablespace_id(const std::string &filename) {
1067110671
return dict_sys_t::s_invalid_space_id;
1067210672
}
1067310673

10674-
auto bytes_read = fread(buf.get(), page_size, MAX_PAGES_TO_READ, fp);
10674+
auto pages_read = fread(buf.get(), page_size, MAX_PAGES_TO_READ, fp);
10675+
10676+
DBUG_EXECUTE_IF("invalid_header", pages_read = 0;);
10677+
10678+
/* Find the space id from the pages read if enough pages could be read.
10679+
Fall back to the more heavier method of finding the space id from
10680+
Datafile::find_space_id() if pages cannot be read properly. */
10681+
if (pages_read >= MAX_PAGES_TO_READ) {
10682+
auto bytes_read = pages_read * page_size;
1067510683

1067610684
#ifdef POSIX_FADV_DONTNEED
10677-
posix_fadvise(fileno(fp), 0, bytes_read, POSIX_FADV_DONTNEED);
10685+
posix_fadvise(fileno(fp), 0, bytes_read, POSIX_FADV_DONTNEED);
1067810686
#endif /* POSIX_FADV_DONTNEED */
1067910687

10680-
for (page_no_t i = 0; i < MAX_PAGES_TO_READ; ++i) {
10681-
const auto off = i * page_size + FIL_PAGE_SPACE_ID;
10688+
for (page_no_t i = 0; i < MAX_PAGES_TO_READ; ++i) {
10689+
const auto off = i * page_size + FIL_PAGE_SPACE_ID;
1068210690

10683-
if (off == FIL_PAGE_SPACE_ID) {
10684-
/* Find out the page size of the tablespace from the first page.
10685-
In case of compressed pages, the subsequent pages can be of different
10686-
sizes. If MAX_PAGES_TO_READ is changed to a different value, then the
10687-
page size of subsequent pages is needed to find out the offset for
10688-
space ID. */
10691+
if (off == FIL_PAGE_SPACE_ID) {
10692+
/* Find out the page size of the tablespace from the first page.
10693+
In case of compressed pages, the subsequent pages can be of different
10694+
sizes. If MAX_PAGES_TO_READ is changed to a different value, then the
10695+
page size of subsequent pages is needed to find out the offset for
10696+
space ID. */
1068910697

10690-
auto space_flags_offset = FSP_HEADER_OFFSET + FSP_SPACE_FLAGS;
10698+
auto space_flags_offset = FSP_HEADER_OFFSET + FSP_SPACE_FLAGS;
1069110699

10692-
ut_a(space_flags_offset + 4 < n_bytes);
10700+
ut_a(space_flags_offset + 4 < n_bytes);
1069310701

10694-
const auto flags = mach_read_from_4(buf.get() + space_flags_offset);
10702+
const auto flags = mach_read_from_4(buf.get() + space_flags_offset);
1069510703

10696-
page_size_t space_page_size(flags);
10704+
page_size_t space_page_size(flags);
1069710705

10698-
page_size = space_page_size.physical();
10699-
}
10706+
page_size = space_page_size.physical();
10707+
}
1070010708

10701-
space_ids.push_back(mach_read_from_4(buf.get() + off));
10709+
space_ids.push_back(mach_read_from_4(buf.get() + off));
1070210710

10703-
if ((i + 1) * page_size >= bytes_read) {
10704-
break;
10711+
if ((i + 1) * page_size >= bytes_read) {
10712+
break;
10713+
}
1070510714
}
1070610715
}
1070710716

@@ -10725,11 +10734,9 @@ space_id_t Fil_system::get_tablespace_id(const std::string &filename) {
1072510734

1072610735
/* Try the more heavy duty method, as a last resort. */
1072710736
if (space_id == UINT32_UNDEFINED) {
10728-
/* The ifstream will work for all file formats compressed or
10729-
otherwise because the header of the page is not compressed.
10730-
Where it will fail is if the first page is corrupt. Then for
10731-
compressed tablespaces we don't know where the page boundary
10732-
starts because we don't know the page size. */
10737+
/* If the first page cannot be read properly, then for compressed
10738+
tablespaces we don't know where the page boundary starts because
10739+
we don't know the page size. */
1073310740

1073410741
Datafile file;
1073510742

@@ -10740,8 +10747,8 @@ space_id_t Fil_system::get_tablespace_id(const std::string &filename) {
1074010747
ut_a(file.is_open());
1074110748
ut_a(err == DB_SUCCESS);
1074210749

10743-
/* Read and validate the first page of the tablespace.
10744-
Assign a tablespace name based on the tablespace type. */
10750+
/* Use the heavier Datafile::find_space_id() method to
10751+
find the space id. */
1074510752
err = file.find_space_id();
1074610753

1074710754
if (err == DB_SUCCESS) {

0 commit comments

Comments
 (0)