mysql 随机产生show命令失败

来源:互联网 发布:java贪吃蛇源代码详解 编辑:程序博客网 时间:2024/05/20 10:15

1.  系统环境

CentOS release 6.7

percona-server-5.6.21-70.0(源码编译安装)

 

2.  故障简述

MySQL会不定期发生执行show ……命令失败的情况。

 

3.  故障排查

3.1. 查看错误日志

客户端返回错误信息:

Can't create/write tofile '/…… /tmp/#sql_3ce_1.MYI' (Errcode: 17 - File exists)

 

错误日志有如下日志报出:

/……/percona-5.6.21/bin/mysqld: Incorrect key file for table '/…… /tmp/#sql_3ce_1';try to repair it

 

查看缓存文件目录/....../tmp,文件#sql_3ce_1.MYI存在,文件大小为0。

执行命令,查看当前线程状态,所有线程状态正常:

mysql>showprocesslist

通过以上信息无法定位产生问题的原因,无法进行错误排查。

3.2. 搜集更多的信息

该现象会不定期的出现,我们采取如下方式进行更多信息的收集。

开启general_log,收集执行的所有的执行的sql信息,等待错误重现后,查看是否有特殊的sql语句可能引起问题。注意定时清理general log,防止出现日志文件较大,导致磁盘被写满的情况。

 

根据错误日志中的内容和客户端的报错信息,在互联网查找相关的信息。较多的故障分析(包括percona官方)为缓存表磁盘空间不足,导致文件损坏或者文件存在创建失败。经排查,我们不存在磁盘空间不足的问题,排除这种情况。

 

3.3. 分析general_log信息

在开启general_log后问题仍然复现,查看general log,在客户端发生错误的时间点和错误日志产生的时间点,查看对应的sql语句。查看结果如下:

> 有一定的并发量,一秒钟执行50条以上的语句

> 无写入语句,全部为show full field和select …from … where语句并没有特殊的语句

 

3.4. 尝试复现BUG

由于general_log显示执行的sql语句仅为如下两种:

show full fields from …

select … from … wherea=…

 

我们编写工具,以一定的并发量重复执行上述两种语句,幸运的是,BUG复现了,执行一段时间后就会出现上述现象。

但是经过几次复现后,发现BUG有如下几个特点:

> 复现周期不定,有时几秒钟就可以复现,有时要超过30分钟

>  每次发生问题的缓存表文件不确定,#sql_xxx_1.MYI、#sql_xxx_17.MYI、#sql_xxx_90.MYI等

>  每次发生问题的现象不定,有时直接报错后不影响业务,有时会阻塞到等待mutex、有时会发生core dump

 

3.5. 追踪BUG产生的原因

由于BUG发生时,是在高并发的情况下,并且发生问题的文件也不确定,我们尝试查看发生问题时进程堆栈。

查看源码,两种错误对应的错误码如下:

Can't create/write tofile '/…… /tmp/#sql_3ce_1.MYI'

EE_CANTCREATEFILE/ ER_CANT_CREATE_FILE


Incorrect key file fortable '/…… /tmp/#sql_3ce_1'; try to repair it

ER_NOT_KEYFILE

查看编译后自动生成的头文件mysqld_error.h,对上述错误码有如下定义:

#defineER_CANT_CREATE_FILE 1004

#define ER_NOT_KEYFILE1034

 

 

使用gdb工具设置条件断点

(gdb)bmysqld.cc:3381 if error = 1004

(gdb)bmysqld.cc:3381 if error = 1034

 

在发生问题后查看进程堆栈,发现在校验缓存表文件合法性的时候,发生错误,文件内容为空,同时tmp目录下该文件的大小为0。仍然不能确认BUG产生的原因。猜测是由于并发的进行缓存表文件创建和删除存在BUG。

 

3.6. 使用其他方法追踪BUG

主要使用如下方法追踪BUG:

 

3.6.1. 查找bug修复文档

使用更多信息来查找相关的bug,不再局限于错误日志报出的信息,同时查找表文件删除、创建方面的bug

3.6.2. 使用新的版本

使用新的版本来复现BUG,查看新版本时候已经修复了BUG,同时可以缩小查找bug修复列表的范围

3.6.3. 继续使用gdb追踪

继续使用gdb工具来追踪bug,以获得更多的信息。

 

最终,通过使用新版本复现bug来缩小bug修复的版本的范围,在release node中查找多该问题对应的bug。

 

4.  总结

官方描述,在由于某些原因发生创建缓存表失败时,会发生对创建文件标志重复清理的情况。导致两个线程使用相同的标志来创建缓存文件,从而发生上述问题。

 

对于大并发产生的BUG,尤其是现象不稳定的BUG,较难定位到具体的问题所在。在自己身无法较快的定位问题时,可以尝试通过其他方法去了解BUG产生的原因。

 

其中bug修复版本为Percona-Server-5.6.23-72.1,细节为:

https://github.com/percona/percona-server/commit/5a587b6d2897e786b515d05a09b37ef81695dab7

 

5.  遗留问题

1.    官方修复的描述为由于某些原因导致缓存表创建失败,并没有说明某些原因是否为mysql自身的原因

2.    并没有分析为什么会有文件遗留,只是优化了对遗留文件的处理 

0 0
原创粉丝点击