mysql提示[Warning] Invalid table or database name
文章介绍了关于mysql提示[Warning] Invalid table or database name,有需的朋友可参考一下.
- 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?) table or database name"问题出现位置:
- 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*/--phpfensi.com
- 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*/
该函数中调用了更深层次的函数,但从调试代码来看,暂时没有发现导致该问题的点.
处理方式:在线索一中的处理方式不能解决问题的情况下,再进行进一步的代码分析.
国外网站参考:
There is the presence of a bug in this case for two reasons:
- 11111610:48:29[Warning]Invalid(old?)tableordatabasename'#sql-3z8g_122a#P#p1'11111610:48:29[Warning]Invalid(old?)tableordatabasename'#sql-3z8g_122a#P#p2'11111610:48:29[Warning]Invalid(old?)tableordatabasename'#sql-3z8g_122a#P#p3'11111610:48:29[Warning]Invalid(old?)tableordatabasename'#sql-3z8g_122a#P#p4'11111610:48:29[Warning]Invalid(old?)tableordatabasename'#sql-3z8g_122a#P#p5'11111610:48:29[Warning]Invalid(old?)tableordatabasename'#sql-3z8g_122a#P#p6'11111610:48:29[Warning]Invalid(old?)tableordatabasename'#sql-3z8g_122a#P#p7'11111610:48:29[Warning]Invalid(old?)tableordatabasename'#sql-3z8g_122a#P#p8'11111610:48:29[Warning]Invalid(old?)tableordatabasename'#sql-3z8g_122a#P#p9'11111610:48:29[Warning]Invalid(old?)tableordatabasename'#sql-3z8g_122a#P#p10'REASON#1:Anytablestartingwith#sqlisatemptable.Ifthesetablesarestillpresentinanydatabasefolderandthedatetimestamp,simplydeletethem.
- REASON#2:Lookcarefullyatthesuffixofeachtable.#P#p?resemblesapartitiontag.Thiswouldindicateanattempttocreateatemptableusingpartitiions.That'ssoundsinsane.TherewasbugreportonthisbackinFeb16,2006forMySQL5.1.7-beta(closedMar15,2006).Thebugreportisbasedontryingtodothismanually.Ismysqlattemptingtodothisinternally?
- IMHOIwouldupgrademysqlawayfromMySQL5.1uptoMySQL5.5
chinanx参考:
环境说明:
1. 错误记录在Percona MySQL 5.5.20版本中
2. 5.5版本的mysql为5.0的从库
错误日志如下:
- 1204162:50:19[Warning]Invalid(old?)tableordatabasename'#sql1f58_a_340'
- 1204162:50:19[Warning]Invalid(old?)tableordatabasename'#sql1f58_a_341'
级别为警告,没有发现其他异常,查看Percona 5.5.20的源代码sql/sql_table.cc:275-283行:
- if(res)
- {
- /*Bettertogivesomethingbackifwefailparsing,thannothingatall*/
- DBUG_PRINT("info",("Errorinexplain_filename:%u",res));
- sql_print_warning("Invalid(old?)tableordatabasename'%s'",from);
- DBUG_RETURN(my_snprintf(to,to_length,
- "<result%uwhenexplainingfilename'%s'>",
- res,from));--phpfensi.com
- }
可以详细说明一下你计算临时表命名的公式吗?
以前推过,没有搞明白,下面是thread_id=297的手动创建的临时表的名字.
-rw-rw---- 1 mysql mysql 98304 Mar 24 18:28 #sqld0b_7_2.ibd
lz的这种临时很大可能是由于alter table的大表的生成的.
一般的alter都会导致表重建,如果表大,一般都会创建中间,就有点像你的那种临时文件,一直没有应用过对临时表进行alter,刚才测试了一下,也没有错误,不知道具体原因.
但是直接用create temporary table会有表结构的临时文件(*.frm等,名字不一样),也是放在/tmp下面的.出现问题之前有crash过吗?可以看一下mysql打开的临时文件中有没有这些warning中提示的:lsof -p mysql pid | grep /tmp
Warning] Invalid (old?) table or database name '#sql56c4_4f_48dc'
这个问题,又大规模出现了.在同一时间有:ALTER TABLE t1 ADD UNIQUE idx_id(id)
总结:经过以上代码调试和分析,得出两条线索,但是一直未能重现该问题,因此,目前只能对现有服务器进行线索一的处理。,如果按照线索一处理方式处理后,仍然出现该问题,将对第二步进行深入的分析.
热门评论