diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2016-02-03 11:32:51 +0200 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2016-02-03 12:22:31 +0200 |
commit | f66d01610f713a76f38de650464bfaea476b9f32 (patch) | |
tree | 81cea0f2531ad287365421dba75b0d93ce92c298 /storage/innobase | |
parent | 603c0960ba7e27dfa25c1b0297deb1c4c5ed6746 (diff) | |
download | mariadb-git-f66d01610f713a76f38de650464bfaea476b9f32.tar.gz |
MDEV-9471: Server crashes or returns an error while trying to alter partitioning on a table moved from Windows to Linux
At alter table when server renames the table to temporal name,
old name uses normal partioned table naming rules. However,
if tables are created on Windows and then transfered to Linux
and lower-case-table-names=1 we should modify the old name
on rename to lower case to be able to find it from the
InnoDB dictionary.
Diffstat (limited to 'storage/innobase')
-rw-r--r-- | storage/innobase/row/row0mysql.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 181ca966451..1a11e398959 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -3838,6 +3838,7 @@ row_rename_table_for_mysql( ibool old_is_tmp, new_is_tmp; pars_info_t* info = NULL; int retry; + char* is_part = NULL; ut_a(old_name != NULL); ut_a(new_name != NULL); @@ -3872,6 +3873,54 @@ row_rename_table_for_mysql( table = dict_table_get_low(old_name, DICT_ERR_IGNORE_NONE); + /* We look for pattern #P# to see if the table is partitioned + MySQL table. */ +#ifdef __WIN__ + is_part = strstr(old_name, "#p#"); +#else + is_part = strstr(old_name, "#P#"); +#endif /* __WIN__ */ + + /* MySQL partition engine hard codes the file name + separator as "#P#". The text case is fixed even if + lower_case_table_names is set to 1 or 2. This is true + for sub-partition names as well. InnoDB always + normalises file names to lower case on Windows, this + can potentially cause problems when copying/moving + tables between platforms. + + 1) If boot against an installation from Windows + platform, then its partition table name could + be all be in lower case in system tables. So we + will need to check lower case name when load table. + + 2) If we boot an installation from other case + sensitive platform in Windows, we might need to + check the existence of table name without lowering + case them in the system table. */ + if (!table && + is_part && + innobase_get_lower_case_table_names() == 1) { + char par_case_name[MAX_FULL_NAME_LEN + 1]; +#ifndef __WIN__ + /* Check for the table using lower + case name, including the partition + separator "P" */ + memcpy(par_case_name, old_name, + strlen(old_name)); + par_case_name[strlen(old_name)] = 0; + innobase_casedn_str(par_case_name); +#else + /* On Windows platfrom, check + whether there exists table name in + system table whose name is + not being normalized to lower case */ + normalize_table_name_low( + par_case_name, old_name, FALSE); +#endif + table = dict_table_get_low(par_case_name, DICT_ERR_IGNORE_NONE); + } + if (!table) { err = DB_TABLE_NOT_FOUND; ut_print_timestamp(stderr); |