DROP TABLE IF EXISTS [TEMP_TABLE_NAME];
create temporary table [TEMP_TABLE_NAME] select col1,col2,... from [TABLE_NAME];
alter table [TEMP_TABLE_NAME] add unique idx_col1(col1);
经过以上操作中,多次出现该warning问题。通过查询和跟踪调试源码,有以下线索和处理方式:
mysql的"[Warning] Invalid (old?) table or database name"问题出现位置:
sql_table.cc:279
uint explain_filename (THD* thd, const char *from, char *to , uint to_length , enum_explain_filename_mode explain_mode )
跟踪代码发现,只有在ha_innodb.cc:1946的innobase_convert_identifier 中调用explain_filename函数。
复制代码 代码如下:
static char* innobase_convert_identifier (
char* buf,
ulint buflen,
const char * id,
ulint idlen,
void* thd,
ibool file_id)
顺着线索向上查找,发现在有两个位置调用了innobase_convert_identifier 函数,分两个线索继续查找。
线索一:
ha_innodb.cc:2034
调用innodb_convert_identifier函数
复制代码 代码如下:
extern "C" UNIV_INTERN char* innobase_convert_name (
char* buf,
ulint buflen,
const char * id,
ulint idlen,
void* thd,
ibool table_id)
从函数定义和函数功能来看,该函数是将mysql的表名或者索引名转换成utf8,与字符集相关。查看现有数据库字符集和生成的临时表字符集均为lanti1,推断是可能的原因之一。
处理方式:
修改数据库的字符集为utf8,观察数据库是否仍然出现该错误。
线索二:
复制代码 代码如下:
ha_innodb.cc:6269
调用innodb_convert_identifier函数
static create_table_def (
trx_t* trx,
TABLE* form,
const char * table_name,
const char * path_of_temp_table,
ulint flags)
在create_table_def 函数中,调用row_create_table_for_mysql函数后,当返回值为DB_DUPLICATE_KEY时,调用innodb_convert_identifier,从而触发该warning。
复制代码 代码如下:
row0mysql.c:1820
UNIV_INTERN int row_create_table_for_mysql(
dict_table_t* table,
trx_t* trx)
该函数中调用了更深层次的函数,但从调试代码来看,暂时没有发现导致该问题的点。
处理方式:
在线索一中的处理方式不能解决问题的情况下,再进行进一步的代码分析。
总结:
经过以上代码调试和分析,得出两条线索,但是一直未能重现该问题。因此,目前只能对现有服务器进行线索一的处理。如果按照线索一处理方式处理后,仍然出现该问题,将对第二步进行深入的分析。
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/2353/viewspace-2804450/ ,如需转载,请注明出处,否则将追究法律责任。