萬盛學電腦網

 萬盛學電腦網 >> 數據庫 >> mysql教程 >> mysql提示[Warning] Invalid table or database name

mysql提示[Warning] Invalid table or database name

文章介紹了關於mysql提示[Warning] Invalid table or database name,有需的朋友可參考一下。

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函數。

/*****************************************************************//**
Convert an SQL identifier to the MySQL system_charset_info (UTF-8)
and quote it if needed.
@return pointer to the end of buf */
static char* innobase_convert_identifier (
/*========================*/
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;
FALSE=id is an UTF-8 string */

順著線索向上查找,發現在有兩個位置調用了innobase_convert_identifier 函數,分兩個線索繼續查找。

線索一:
ha_innodb.cc:2034
調用innodb_convert_identifier函數

/*****************************************************************//**
Convert a table or index name to the MySQL system_charset_info (UTF-8)
and quote it if needed.
@return pointer to the end of buf */
extern "C" UNIV_INTERN char* innobase_convert_name (
/*==================*/
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函數
/*****************************************************************//**
Creates a table definition to an InnoDB database. */
static create_table_def (
/*=============*/
trx_t* trx, /*!< in: InnoDB transaction handle */
TABLE* form, /*!< in: information on table
columns and indexes */
const char * table_name, /*!< in: table name */
const char * path_of_temp_table, /*!< in: if this is a table explicitly
created by the user with the
TEMPORARY keyword, then this
parameter is the dir path where the
table should be placed if we create
an .ibd file for it (no .ibd extension
in the path, though); otherwise this
is NULL */
ulint flags) /*!< in: table 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, /*!< in, own: table definition
(will be freed) */
trx_t* trx) /*!< in: transaction handle */

該函數中調用了更深層次的函數,但從調試代碼來看,暫時沒有發現導致該問題的點。
處理方式:
在線索一中的處理方式不能解決問題的情況下,再進行進一步的代碼分析。

國外網站參考


There is the presence of a bug in this case for two reasons:

111116 10:48:29 [Warning] Invalid (old?) table or database name '#sql-3z8g_122a#P#p1'  111116 10:48:29 [Warning] Invalid (old?) table or database name '#sql-3z8g_122a#P#p2'  111116 10:48:29 [Warning] Invalid (old?) table or database name '#sql-3z8g_122a#P#p3'  111116 10:48:29 [Warning] Invalid (old?) table or database name '#sql-3z8g_122a#P#p4'  111116 10:48:29 [Warning] Invalid (old?) table or database name '#sql-3z8g_122a#P#p5'  111116 10:48:29 [Warning] Invalid (old?) table or database name '#sql-3z8g_122a#P#p6'  111116 10:48:29 [Warning] Invalid (old?) table or database name '#sql-3z8g_122a#P#p7'  111116 10:48:29 [Warning] Invalid (old?) table or database name '#sql-3z8g_122a#P#p8'  111116 10:48:29 [Warning] Invalid (old?) table or database name '#sql-3z8g_122a#P#p9'  111116 10:48:29 [Warning] Invalid (old?) table or database name '#sql-3z8g_122a#P#p10'  REASON #1 : Any table starting with #sql is a temp table. If these tables are still present in any database folder and the datetime stamp, simply delete them.

REASON #2 : Look carefully at the suffix of each table. #P#p? resembles a partition tag. This would indicate an attempt to create a temp table using partitiions. That's sounds insane. There was bug report on this back in Feb 16, 2006 for MySQL 5.1.7-beta (closed Mar 15, 2006). The bug report is based on trying to do this manually. Is mysql attempting to do this internally ?

IMHO I would upgrade mysql away from MySQL 5.1 up to MySQL 5.5


chinanx參考


環境說明:
1. 錯誤記錄在Percona MySQL 5.5.20版本中
2. 5.5版本的mysql為5.0的從庫

錯誤日志如下;
120416  2:50:19 [Warning] Invalid (old?) table or database name '#sql1f58_a_340'
120416  2:50:19 [Warning] Invalid (old?) table or database name '#sql1f58_a_341'

級別為警告,沒有發現其他異常.
查看Percona 5.5.20的源代碼

sql/sql_table.cc
275-283行

  if (res)
  {
    /* Better to give something back if we fail parsing, than nothing at all */
    DBUG_PRINT("info", ("Error in explain_filename: %u", res));
    sql_print_warning("Invalid (old?) table or database name '%s'", from);
    DBUG_RETURN(my_snprintf(to, to_length,
                            "<result %u when explaining filename '%s'>",
                            res, from));
  }


可以詳細說明一下你計算臨時表命名的公式嗎?
以前推過,沒有搞明白, 下面是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)


總結:
經過以上代碼調試和分析,得出兩條線索,但是一直未能重現該問題。因此,目前只能對現有服務器進行線索一的處理。如果按照線索一處理方式處理後,仍然出現該問題,將對第二步進行深入的分析

copyright © 萬盛學電腦網 all rights reserved