您的位置:首页 > 数据库 > MySQL

mysql的"[Warning] Invalid (old?) table or database name"问题

2012-07-27 16:04 447 查看
[align=left]        线上服务器出现[Warning] Invalid (old?) table or database name问题,通过分析binlog日志发现,在以下sql语句中出现问题,由于涉及敏感内容,用sql语法表示。[/align]
[align=left]        DROP TABLE IF EXISTS [TEMP_TABLE_NAME];[/align]
[align=left]        create temporary table [TEMP_TABLE_NAME] select col1,col2,... from [TABLE_NAME];[/align]
[align=left]        alter table [TEMP_TABLE_NAME] add unique idx_col1(col1);[/align]
[align=left]        经过以上操作中,多次出现该warning问题。通过查询和跟踪调试源码,有以下线索和处理方式:[/align]
[align=left] [/align]
[align=left]
[/align]
[align=left]        mysql的"[Warning] Invalid (old?) table or database name"问题出现位置:[/align]
[align=left]
[/align]

sql_table.cc:279

[align=left]uint explain_filename (THD* thd, const char *from, char *to , uint to_length , enum_explain_filename_mode explain_mode )[/align]

[align=left]
[/align]
[align=left]        跟踪代码发现,只有在ha_innodb.cc:1946的innobase_convert_identifier 中调用explain_filename函数。[/align]

[align=left]/*****************************************************************//**[/align]
[align=left]Convert an SQL identifier to the MySQL system_charset_info (UTF-8)[/align]
[align=left]and quote it if needed.[/align]
[align=left]@return       pointer to the end of buf */[/align]
[align=left]static char* innobase_convert_identifier ([/align]
[align=left]/*========================*/[/align]
           char*           buf,     /*!<
out: buffer for converted identifier */
           ulint             buflen,          /*!<
in: length of buf, in bytes */
           const char *  id,       /*!<
in: identifier to convert */
           ulint             idlen,   /*!<
in: length of id, in bytes */
           void*           thd,     /*!<
in: MySQL connection thread, or NULL */
           ibool            file_id) /*!<
in: TRUE=id is a table or database name;
[align=left]                                      FALSE=id is an UTF-8 string */[/align]

[align=left]
[/align]
[align=left]        顺着线索向上查找,发现在有两个位置调用了innobase_convert_identifier 函数,分两个线索继续查找。[/align]
[align=left][/align]
[align=left]线索一[/align]

ha_innodb.cc:2034
调用innodb_convert_identifier函数

[align=left]/*****************************************************************//**[/align]
Convert a table or index name
to the MySQL system_charset_info (UTF-8)
[align=left]and quote it if needed.[/align]
@return       pointer to the
end of buf */
[align=left]extern "C" UNIV_INTERN char* innobase_convert_name ([/align]
[align=left]/*==================*/[/align]
           char*           buf,     /*!<
out: buffer for converted identifier */
           ulint             buflen,          /*!<
in: length of buf, in bytes */
           const char *  id,       /*!<
in: identifier to convert */
           ulint             idlen,   /*!<
in: length of id, in bytes */
           void*           thd,     /*!<
in: MySQL connection thread, or NULL */
           ibool            table_id) /*!<
in: TRUE=id is a table or database name;
                                      FALSE=id
is an index name */

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

线索二:

ha_innodb.cc:6269
调用innodb_convert_identifier函数

[align=left]/*****************************************************************//**[/align]
[align=left]Creates a table definition to an InnoDB database. */[/align]
[align=left]static create_table_def ([/align]
[align=left]/*=============*/[/align]
           trx_t*          trx,               /*!<
in: InnoDB transaction handle */
           TABLE*                form,           /*!<
in: information on table
[align=left]                                                columns and indexes */[/align]
           const char *  table_name,  /*!<
in: table name */
           const char *  path_of_temp_table, /*!<
in: if this is a table explicitly
[align=left]                                                created by the user with the[/align]
[align=left]                                                TEMPORARY keyword, then this[/align]
[align=left]                                                parameter is the dir path where the[/align]
[align=left]                                                table should be placed if we create[/align]
[align=left]                                                an .ibd file for it (no .ibd extension[/align]
[align=left]                                                in the path, though); otherwise this[/align]
[align=left]                                                is NULL */[/align]
           ulint             flags)            /*!<
in: table flags */
[align=left]
[/align]
[align=left]        在create_table_def 函数中,调用row_create_table_for_mysql函数后,当返回值为DB_DUPLICATE_KEY时,调用innodb_convert_identifier,从而触发该warning。[/align]
[align=left]
[/align]
[align=left]row0mysql.c:1820[/align]
[align=left]UNIV_INTERN int row_create_table_for_mysql([/align]
[align=left]/*=======================*/[/align]
           dict_table_t*         table,   /*!<
in, own: table definition
[align=left]                                      (will be freed) */[/align]
           trx_t*          trx)     /*!<
in: transaction handle */
[align=left]
[/align]
[align=left]        该函数中调用了更深层次的函数,但从调试代码来看,暂时没有发现导致该问题的点。[/align]

处理方式:
        在线索一中的处理方式不能解决问题的情况下,再进行进一步的代码分析。

总结:
        经过以上代码调试和分析,得出两条线索,但是一直未能重现该问题。因此,目前只能对现有服务器进行线索一的处理。如果按照线索一处理方式处理后,仍然出现该问题,将对第二步进行深入的分析。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐