zl程序教程

您现在的位置是:首页 >  数据库

当前栏目

mysql提示[Warning]Invalid(old?)tableordatabasename问题的解决方法

mysqlinvalid方法 问题 解决 提示 WARNING old
2023-06-13 09:14:34 时间
DROPTABLEIFEXISTS[TEMP_TABLE_NAME];
createtemporarytable[TEMP_TABLE_NAME]selectcol1,col2,...from[TABLE_NAME];
altertable[TEMP_TABLE_NAME]adduniqueidx_col1(col1);
经过以上操作中,多次出现该warning问题。通过查询和跟踪调试源码,有以下线索和处理方式:
mysql的"[Warning]Invalid(old?)tableordatabasename"问题出现位置:

sql_table.cc:279
uintexplain_filename(THD*thd,constchar*from,char*to,uintto_length,enum_explain_filename_modeexplain_mode)

跟踪代码发现,只有在ha_innodb.cc:1946的innobase_convert_identifier中调用explain_filename函数。
复制代码代码如下:

/*****************************************************************//**
ConvertanSQLidentifiertotheMySQLsystem_charset_info(UTF-8)
andquoteitifneeded.
@returnpointertotheendofbuf*/
staticchar*innobase_convert_identifier(
/*========================*/
char*buf,/*!<out:bufferforconvertedidentifier*/
ulintbuflen,/*!<in:lengthofbuf,inbytes*/
constchar*id,/*!<in:identifiertoconvert*/
ulintidlen,/*!<in:lengthofid,inbytes*/
void*thd,/*!<in:MySQLconnectionthread,orNULL*/
iboolfile_id)/*!<in:TRUE=idisatableordatabasename;
FALSE=idisanUTF-8string*/

顺着线索向上查找,发现在有两个位置调用了innobase_convert_identifier函数,分两个线索继续查找。

线索一:
ha_innodb.cc:2034
调用innodb_convert_identifier函数
复制代码代码如下:

/*****************************************************************//**
ConvertatableorindexnametotheMySQLsystem_charset_info(UTF-8)
andquoteitifneeded.
@returnpointertotheendofbuf*/
extern"C"UNIV_INTERNchar*innobase_convert_name(
/*==================*/
char*buf,/*!<out:bufferforconvertedidentifier*/
ulintbuflen,/*!<in:lengthofbuf,inbytes*/
constchar*id,/*!<in:identifiertoconvert*/
ulintidlen,/*!<in:lengthofid,inbytes*/
void*thd,/*!<in:MySQLconnectionthread,orNULL*/
ibooltable_id)/*!<in:TRUE=idisatableordatabasename;
FALSE=idisanindexname*/

从函数定义和函数功能来看,该函数是将mysql的表名或者索引名转换成utf8,与字符集相关。查看现有数据库字符集和生成的临时表字符集均为lanti1,推断是可能的原因之一。
处理方式:
修改数据库的字符集为utf8,观察数据库是否仍然出现该错误。

线索二:
复制代码代码如下:
ha_innodb.cc:6269
调用innodb_convert_identifier函数
/*****************************************************************//**
CreatesatabledefinitiontoanInnoDBdatabase.*/
staticcreate_table_def(
/*=============*/
trx_t*trx,/*!<in:InnoDBtransactionhandle*/
TABLE*form,/*!<in:informationontable
columnsandindexes*/
constchar*table_name,/*!<in:tablename*/
constchar*path_of_temp_table,/*!<in:ifthisisatableexplicitly
createdbytheuserwiththe
TEMPORARYkeyword,thenthis
parameteristhedirpathwherethe
tableshouldbeplacedifwecreate
an.ibdfileforit(no.ibdextension
inthepath,though);otherwisethis
isNULL*/
ulintflags)/*!<in:tableflags*/

在create_table_def函数中,调用row_create_table_for_mysql函数后,当返回值为DB_DUPLICATE_KEY时,调用innodb_convert_identifier,从而触发该warning。
复制代码代码如下:
row0mysql.c:1820
UNIV_INTERNintrow_create_table_for_mysql(
/*=======================*/
dict_table_t*table,/*!<in,own:tabledefinition
(willbefreed)*/
trx_t*trx)/*!<in:transactionhandle*/

该函数中调用了更深层次的函数,但从调试代码来看,暂时没有发现导致该问题的点。
处理方式:
在线索一中的处理方式不能解决问题的情况下,再进行进一步的代码分析。
总结:
经过以上代码调试和分析,得出两条线索,但是一直未能重现该问题。因此,目前只能对现有服务器进行线索一的处理。如果按照线索一处理方式处理后,仍然出现该问题,将对第二步进行深入的分析。

作者king_wangheng