Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1356064
  • 博文数量: 107
  • 博客积分: 1715
  • 博客等级: 上尉
  • 技术积分: 3168
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-18 18:42
个人简介

阿里巴巴DBA,原去哪儿网DBA。专注于MySQL源码研究、DBA运维、CGroup虚拟化及Linux Kernel源码研究等。 github:https://github.com/HengWang/ Email:king_wangheng@163.com 微博 :@王恒-Henry QQ :506437736

文章分类

全部博文(107)

文章存档

2014年(2)

2013年(38)

2012年(67)

分类: Mysql/postgreSQL

2012-08-13 18:18:23

    通过最近一段时间对该问题的跟踪,与Percona讨论组进行交流和探讨。虽然问题没有最终定位,也未能重现,但鉴于该问题可能触发一些bug。因此,整理往返的邮件,供大家参考。此外,该问题也提交到mysql官方bug列表,其中内容也供大家参考:http://bugs.mysql.com/bug.php?id=66253 。
    对于之前对该问题源码的跟踪的相关内容,可以参考 mysql的"[Warning] Invalid (old?) table or database name"问题 

Heng Wang:
Recently, I encountered a problem, the details is: The mysql error log
always reports a warning like “[Warning] Invalid (old?) table or
database name? Through analysis of the binlog, there are two
statements in this period. The statements like these “create temporary
table [TEMP_TABLE_NAME] select col1,col2,... from [TABLE_NAME];?,
“alter table [TEMP_TABLE_NAME] add unique idx_col1(col1);?
I debug the mysql source attempt to trace the problem where happened,
but has not been able to repeat it. However, I get some ideas on the
problem through trace the mysql source (based on 5.5.20 source). The
detail as follows:
The warning information appears only in the function of
explain_filename (THD* thd, const char *from, char *to , uint
to_length , enum_explain_filename_mode explain_mode ) in line 279 of
sql/sql_table.cc.
I continue to trace the source and find that only the function
innobase_convert_identifier() in line 1946 of ha_innodb.cc call
explain_filename, the function implement as follows:

/*****************************************************************//**
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 */


Next, I trace the source where call the function of
innobase_convert_identifier(), I found that there are two clues.
First, in line 2034 of ha_innodb.cc, the function
innobase_convert_name() call the innobase_convert_identifier() to
convert a table or index name to the MySQL system_charset_info(UTF-8)
and quote it if needed. So I examine the database of production
environment, and find that the charset of all databases and tables are
utf8. So I think the problem can not be caused by charset. The
function implement as follows:
/*****************************************************************//**
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 */


Second, in line 6269 of ha_innodb.cc, the function create_table_def()
call the innobase_convert_identifier() only when the error state is
DB_DUPLICATE_KEY, and after calling the function of
row_create_table_for_mysql()(row0mysql.c:1820). But I throughout have
not found the detail where change the error state. The function
implement as follows:
/*****************************************************************//**
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 */


In summary, I am sure the problem caused by the second clue, and both
two statements call the create_table_def() function. But I still have
not found the specific reason, so I want you to give me some
information and suggestion to trace the problem.

Laurynas:
Most probably you are experiencing http://bugs.mysql.com/bug.php?id=51180

Heng Wang:
Thank you for you help, but the description of bug #51180 is not very detailed. And the repeat situation seems not to meet our problem. Our mysql server has never been stoped or restarted, and the method of  "copy the .frm file and try DROP TABLE " does not according to our application.
In our application, we need a temporary table to store a large of data summarized from another tables. In order to promote the performance to query the result from temporary table, we add a unique index. The SQL statements like this:
1.   " DROP TABLE IF EXISTS [TEMP_TABLE_NAME];"
2. “create temporary table [TEMP_TABLE_NAME] select col1,col2,... from [TABLE_NAME];"
3. “alter table [TEMP_TABLE_NAME] add unique idx_col1(col1);"

Please give me more detailed information in order to confirm the problem is the bug #51180. 
Thank you very much and looking forward to hearing from you.

Laurynas:
The 51180 "How to repeat" does not list all the ways to repeat the
issue. It is enough to have an open temporary table (can be also an
internal temporary table, such as for ALTER TABLE) and then do any
operation that invokes explain_filename() at one point or another, for
example, issue SHOW ENGINE InnoDB STATUS in other thread. The issue
here is that explain_filename() is not fully compatible with the
"#sql..." names that are generated for those temp tables. Bug
http://bugs.mysql.com/bug.php?id=32430 might provide more background
on this.

Heng Wang:
Thanks Laurynas Biveinis , but I think the bug#51180 is not the same problem. The error log always reports the warning like these:
120410  2:15:21 [Warning] Invalid (old?) table or database name '#sql5790_2e86_186e'
120410  2:15:21 [Warning] Invalid (old?) table or database name '#sql5790_2e86_186e'
120410  2:15:21 [Warning] Invalid (old?) table or database name '#sql5790_2e86_186f'

Through analysis of the binlog,there are three statements in this period. the statements like these:
1.   " DROP TABLE IF EXISTS [TEMP_TABLE_NAME];"
2. “create temporary table [TEMP_TABLE_NAME] select col1,col2,... from [TABLE_NAME];"
3. “alter table [TEMP_TABLE_NAME] add unique idx_col1(col1);"

And the difference from bug#51180 is the error log never reports the information like these:
does not exist in the InnoDB internal
InnoDB: data dictionary though MySQL is trying to drop it.

So I think there are some other points triggering the problem.
Thank you very much and looking forward to hearing from you.

Laurynas:
Perhaps I keep missing some you point you make, but I still think that
this is #51180. The second error message in the bug report, which you
don't have in your logs, is secondary. The bug report is about the
first message, which you do experience, and which is caused by
incorrect temp table name handling in explain_filename().

Heng Wang:
Thanks Laurynas help, The previous emails ignore another warning followed by " Invalid (old?) table or database name ".  Now, provide the parts of mysql server error log and attach the full error log  from 2012/08/05 to now  in the email, maybe it is useful for confirming the problem.

The detail:
120807  2:50:32 [Warning] Invalid (old?) table or database name '#sql4925_56c424_8fe'
120807  2:50:32 [Warning] Invalid (old?) table or database name '#sql4925_56c424_8ff'
120807  2:50:32 [Warning] Invalid (old?) table or database name '#sql4925_56c424_8fe'
120807  2:50:32 [Warning] Invalid (old?) table or database name '#sql4925_56c424_8fe'
120807  2:50:32 [Warning] Invalid (old?) table or database name '#sql4925_56c424_8fe'
120807  2:50:32 [Warning] Invalid (old?) table or database name '#sql4925_56c424_8fe'
120807  2:50:32 [Warning] Invalid (old?) table or database name '#sql4925_56c424_8fe'
120807  2:50:32 [Warning] Invalid (old?) table or database name '#sql4925_56c424_8fe'
120807  2:50:32 [Warning] Invalid (old?) table or database name '#sql4925_56c424_8fe'
120807  2:50:32 [Warning] Invalid (old?) table or database name '#sql4925_56c424_8fe'
InnoDB: Warning: hash index ref_count (4) is not zero after fil_discard_tablespace().
index: "PRIMARY" table: "[DATABASE]/[TABLE]"
InnoDB: Warning: hash index ref_count (4) is not zero after fil_discard_tablespace().
index: "PRIMARY" table: "[DATABASE]/[TABLE]"
InnoDB: Warning: hash index ref_count (4) is not zero after fil_discard_tablespace().
index: "PRIMARY" table: "[DATABASE]/[TABLE]"
InnoDB: Warning: hash index ref_count (4) is not zero after fil_discard_tablespace().
index: "PRIMARY" table: "[DATABASE]/[TABLE]"
InnoDB: Warning: hash index ref_count (4) is not zero after fil_discard_tablespace().
index: "PRIMARY" table: "[DATABASE]/[TABLE]"
InnoDB: Warning: hash index ref_count (4) is not zero after fil_discard_tablespace().
index: "PRIMARY" table: "[DATABASE]/[TABLE]"
InnoDB: Warning: hash index ref_count (4) is not zero after fil_discard_tablespace().
index: "PRIMARY" table: "[DATABASE]/[TABLE]"

Thank you very much and look forward to hearing from you.

Laurynas:
The error message is annoying but entirely benign. If you want to fix
it, you have to fix explain_filename() only and nothing else.

Yes, I ignored the second error message before. It happens on
tablespace discard (DROP TABLE with file per table enabled) and it
means that not all of the adaptive hash index entries concerning the
tablespace being removed were dropped yet. This should be benign as
well (in the worst case, if those entries are actually never dropped,
this amounts to AHI performance degradation). If you have a repeatable
isolated testcase, feel free to submit a bug report to us. Also try
changing the innodb_lazy_drop_table setting, and testing with at least
Percona Server 5.5.23.

    在此,非常感谢percona讨论组的Laurynas的热心帮助,给我提供了很多思路。
阅读(1548) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~