Skip to content

Commit 5ced1b7

Browse files
Nisha Gopalakrishnandahlerlend
authored andcommitted
BUG#32288105: MYSQL CRASHES IMMEDIATELY AFTER SELECTING FROM
INFORMATION_SCHEMA ISSUE Queries on tables executed after querying the INFORMATION_SCHEMA tables INNODB_TABLES, INNODB_COLUMNS, INNODB_INDEXES, INNODB_TABLESTATS and INNODB_VIRTUAL can trigger an assert on case insensitive file system where the lower-case-table-names is set to 2. ROOT CAUSE When querying the I_S tables, the function dd_table_open_on_dd_obj() is called to load the table definition from the DD object. However, if the table was created with a mixed-case schema or table name, dd_table_open_on_dd_obj() does not convert the name to lowercase before adding it to dictionary cache. Subsequent queries look up the cache using the lowercase name, but since the entry was stored with mixed casing, it is not found. Hence it tries to add to cache using dict_table_add_to_cache(). During error checks before adding an entry, the cache is searched using the table id and finds an entry in the cache triggering an assert. FIX The function dd_table_open_on_dd_obj() is modified to convert the name to lower case before loading the table definition and adding to the dictionary cache on case insensitive file sytem. Change-Id: Id902acfc3622b6af869f5b9dc830d0be58cc09c8
1 parent 09a3a38 commit 5ced1b7

File tree

1 file changed

+23
-16
lines changed

1 file changed

+23
-16
lines changed

storage/innobase/dict/dict0dd.cc

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -435,39 +435,46 @@ int dd_table_open_on_dd_obj(THD *thd, dd::cache::Dictionary_client *client,
435435

436436
TABLE_SHARE ts;
437437
TABLE table_def;
438-
dd::Schema *schema;
439438

440439
error =
441440
acquire_uncached_table(thd, client, &dd_table, tbl_name, &ts, &table_def);
442441
if (error != 0) {
443442
return (error);
444443
}
445444

446-
char tmp_name[MAX_FULL_NAME_LEN + 1];
447-
const char *tab_namep;
448-
if (tbl_name) {
449-
tab_namep = tbl_name;
450-
} else {
451-
char tmp_schema[MAX_DATABASE_NAME_LEN + 1];
452-
char tmp_tablename[MAX_TABLE_NAME_LEN + 1];
445+
const char *table_name = tbl_name;
446+
if (!tbl_name) {
447+
dd::Schema *schema;
453448
error = client->acquire_uncached<dd::Schema>(dd_table.schema_id(), &schema);
454449
if (error != 0) {
455450
return error;
456451
}
457-
tablename_to_filename(schema->name().c_str(), tmp_schema,
458-
MAX_DATABASE_NAME_LEN + 1);
459-
tablename_to_filename(dd_table.name().c_str(), tmp_tablename,
460-
MAX_TABLE_NAME_LEN + 1);
461-
snprintf(tmp_name, sizeof tmp_name, "%s/%s", tmp_schema, tmp_tablename);
462-
tab_namep = tmp_name;
452+
453+
bool truncated;
454+
char tmp_name[FN_REFLEN + 1];
455+
build_table_filename(tmp_name, sizeof(tmp_name) - 1, schema->name().c_str(),
456+
dd_table.name().c_str(), nullptr, 0, &truncated);
457+
458+
if (truncated) {
459+
ut_d(ut_error);
460+
ut_o(return DB_TOO_LONG_PATH);
461+
}
462+
table_name = tmp_name;
463+
}
464+
465+
char norm_name[FN_REFLEN];
466+
if (!normalize_table_name(norm_name, table_name)) {
467+
ut_d(ut_error);
468+
ut_o(return DB_TOO_LONG_PATH);
463469
}
470+
464471
if (dd_part == nullptr) {
465-
table = dd_open_table(client, &table_def, tab_namep, &dd_table, thd);
472+
table = dd_open_table(client, &table_def, norm_name, &dd_table, thd);
466473
if (table == nullptr) {
467474
error = HA_ERR_GENERIC;
468475
}
469476
} else {
470-
table = dd_open_table(client, &table_def, tab_namep, dd_part, thd);
477+
table = dd_open_table(client, &table_def, norm_name, dd_part, thd);
471478
}
472479
release_uncached_table(&ts, &table_def);
473480
return error;

0 commit comments

Comments
 (0)