Skip to content

Commit 4d3573e

Browse files
Sunny Bainsdahlerlend
authored andcommitted
Bug#27265874 - TABLESPACE ID DISCOVERY ON STARTUP IS BROKEN
The compare with the previous value is broken. The fix is to read the the value into an array and then do a compare separately. If there is any mismatch then we fallback to the slower tablespace ID lookup. RB#18258 Approved by Bin Su.
1 parent ed792fd commit 4d3573e

File tree

1 file changed

+23
-26
lines changed

1 file changed

+23
-26
lines changed

storage/innobase/fil/fil0fil.cc

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -11113,19 +11113,19 @@ Datafile::find_space_id().
1111311113
space_id_t
1111411114
Fil_system::get_tablespace_id(const std::string& filename)
1111511115
{
11116-
dberr_t err = DB_CORRUPTION;
1111711116
char buf[sizeof(space_id_t)];
11118-
space_id_t space_id = ULINT32_UNDEFINED;
11119-
space_id_t prev_space_id = ULINT32_UNDEFINED;
1112011117
std::ifstream ifs(filename, std::ios::binary);
1112111118

1112211119
if (!ifs) {
1112311120
ib::warn() << "Unable to open '" << filename << "'";
1112411121
return(ULINT32_UNDEFINED);
1112511122
}
1112611123

11124+
std::vector<space_id_t> space_ids;
1112711125
auto page_size = srv_page_size;
1112811126

11127+
space_ids.reserve(MAX_PAGES_TO_CHECK);
11128+
1112911129
for (page_no_t page_no = 0; page_no < MAX_PAGES_TO_CHECK; ++page_no) {
1113011130

1113111131
off_t off;
@@ -11169,50 +11169,47 @@ Fil_system::get_tablespace_id(const std::string& filename)
1116911169
|| (ifs.rdstate() & std::ifstream::badbit) != 0) {
1117011170

1117111171
/* Trucated files can be a single page */
11172-
return(page_no > 0 ? space_id : ULINT32_UNDEFINED);
11172+
break;
1117311173
}
1117411174

1117511175
ifs.read(buf, sizeof(buf));
1117611176

1117711177
if (!ifs.good() || (size_t) ifs.gcount() < sizeof(buf)) {
1117811178

1117911179
/* Trucated files can be a single page */
11180-
return(page_no > 0 ? space_id : ULINT32_UNDEFINED);
11180+
break;
1118111181
}
1118211182

11183-
space_id = mach_read_from_4(reinterpret_cast<byte*>(buf));
11183+
space_id_t space_id;
1118411184

11185-
if (space_id == 0 || space_id == ULINT32_UNDEFINED) {
11185+
space_id = mach_read_from_4(reinterpret_cast<byte*>(buf));
1118611186

11187-
/* We don't write the space ID to new pages. */
11188-
if (prev_space_id != ULINT32_UNDEFINED
11189-
&& prev_space_id != 0) {
11187+
space_ids.push_back(space_id);
11188+
}
1119011189

11191-
err = DB_SUCCESS;
11192-
space_id = prev_space_id;
11190+
ifs.close();
1119311191

11194-
break;
11195-
}
11192+
space_id_t space_id;
1119611193

11197-
continue;
11194+
if (!space_ids.empty()) {
1119811195

11199-
} else if (space_id > 0 && prev_space_id == space_id) {
11196+
space_id = space_ids.front();
1120011197

11201-
ut_a(prev_space_id != ULINT32_UNDEFINED);
11198+
for (auto id : space_ids) {
1120211199

11203-
err = DB_SUCCESS;
11204-
break;
11200+
if (space_id != id) {
1120511201

11206-
} else if (space_id > 0) {
11202+
space_id = ULINT32_UNDEFINED;
1120711203

11208-
prev_space_id = space_id;
11204+
break;
11205+
}
1120911206
}
11207+
} else {
11208+
space_id = ULINT32_UNDEFINED;
1121011209
}
1121111210

11212-
ifs.close();
11213-
1121411211
/* Try the more heavy duty method, as a last resort. */
11215-
if (err != DB_SUCCESS) {
11212+
if (space_id == ULINT32_UNDEFINED) {
1121611213

1121711214
/* The ifstream will work for all file formats compressed or
1121811215
otherwise because the header of the page is not compressed.
@@ -11224,7 +11221,7 @@ Fil_system::get_tablespace_id(const std::string& filename)
1122411221

1122511222
file.set_filepath(filename.c_str());
1122611223

11227-
err = file.open_read_only(false);
11224+
dberr_t err = file.open_read_only(false);
1122811225

1122911226
ut_a(file.is_open());
1123011227
ut_a(err == DB_SUCCESS);
@@ -11240,7 +11237,7 @@ Fil_system::get_tablespace_id(const std::string& filename)
1124011237
file.close();
1124111238
}
1124211239

11243-
return(err != DB_SUCCESS) ? ULINT32_UNDEFINED : space_id;
11240+
return(space_id);
1124411241
}
1124511242

1124611243
/** Check for duplicate tablespace IDs.

0 commit comments

Comments
 (0)