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]
处理方式:
在线索一中的处理方式不能解决问题的情况下,再进行进一步的代码分析。
总结:
经过以上代码调试和分析,得出两条线索,但是一直未能重现该问题。因此,目前只能对现有服务器进行线索一的处理。如果按照线索一处理方式处理后,仍然出现该问题,将对第二步进行深入的分析。
[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]
处理方式:
在线索一中的处理方式不能解决问题的情况下,再进行进一步的代码分析。
总结:
经过以上代码调试和分析,得出两条线索,但是一直未能重现该问题。因此,目前只能对现有服务器进行线索一的处理。如果按照线索一处理方式处理后,仍然出现该问题,将对第二步进行深入的分析。
相关文章推荐
- mysql提示[Warning] Invalid (old?) table or database name问题的解决方法
- mysql提示[Warning] Invalid (old?) table or database name问题的解决方法
- Problem of " Invalid (old?) table or database name"
- "Invalid username/password or database/scan listener not up"
- "Invalid username/password or database/scan listener not up"
- 解决mysql出现"the table is full"的问题
- 解决SQL Server数据库的"User, group, or role already exists in the current database"问题
- 解决mysql出现"the table is full"的问题
- mysql的"Incorrect key file for table '/tmp/#sql_1194_12.MYI'; try to repair it"问题
- mysql出现"the table is full"的问题
- Pycharm上python unittest不执行"if __name__ == '__main__' "问题or选择非unittest run
- mysql: "tablename" is marked as crashed and should be repaired修复 问题分析: 当mysql出现这类提示时,大部分的现象为查询不到正常的
- "WARNING: Increasing RAM size to 1GB" and "Cannot set up guest memory 'xxx.ram': Invalid argument".
- python unittest不执行"if __name__ == '__main__' "问题(Pycharm)
- 解决在MySQL中插入中文出现"Incorrect string value"的问题
- MySQL 5.6 解决InnoDB: Error: Table "mysql"."innodb_table_stats" not found.问题
- MySQL 1042, "Can't get hostname for your address"问题解决方案
- jquery下removeClass(“oldClassName”).addClass("newClassName")的问题
- 关于STM32头文件包含出现No such file or directory和 invalid redeclaration of type name...的问题
- mysqli使用localhost问题 Warning: mysqli::mysqli(): (HY000/2002): No such file or directory in /...