MySQL5.1中频繁地无法连接mysqld实例问题,mysql5.1mysqld实例发现及时的话,马上处
MySQL5.1中频繁地无法连接mysqld实例问题,mysql5.1mysqld实例发现及时的话,马上处
现象:
线上某实例从年前到现在,每天晚上0点-2点间至少hang一次。发现及时的话,马上处理掉。发现不及时的话,aurora就切换了。但即使切换了,新的slave(老的master)依然是hang状态,root也无法登陆,tcp里大量 close_wait off连接,也有established 连接。由于无法登进去mysql,所以不知道发生什么事情。然后该主机上凡是要连接该实例的鹰眼报警全部超时。
解决办法只有杀掉进程,然后重启实例。
初步分析:
close_wait是被动端收到FIN并发送ACK后切换的状态。此后按正常逻辑,再close并且FIN切换到LAST_ACK状态。CLOSE_WAIT的timer状态为off(0/0/0), 看起来没有什么问题。
现在MySQL用root帐号也无法登录,需要从mysqld抓些数据来分析。
第一次抓的pmp信息:
抓了pmp信息,由于此个mysqld编译时没有加-g,导致ha_innodb.so库中的符号是无法被识别,也就是看到的??。
从已有的信息中看,mysqld无法连接的原因是被卡住了:
正常的连接被阻塞于THD::init,等待LOCK_global_system_variables。
而此全局变量只可能会被执行set global 语句阻塞,此线程拥有LOCK_logger, 导致6个线程等待rdlock,同时此线程等待LOCK_open。与此同时等待LOCK_open的还有复制的SQL线程。
那么,哪个线程拥有LOCK_open呢?由于编译的问题,抓的backtrace不能反映完整信息,但可能的是最后一个DDL线程, ha_create时被阻塞。此线程很可能拥有LOCK_open。
至于执行DDL的线程被阻塞原因,我还要再跟踪下。
总之,从抓的backtrace看,我觉得很可能是mysqld内部某种死锁导致。
后续打算重新编译一个加编译信息的mysqld(其实是innodb.so),像这种负载较低的,如果是MySQL engine的问题,应该不难搞定。
第二次抓的pmp信息:
set global操作:
sys_var_log_state::update —>占用LOCK_global_system_variables LOGGER::activate_log_handler activate_log open_performance_schema_table open_ltable open_table ———>请求lock_open
本地DDL线程
mysql_alter_table->mysql_create_table_no_lock —–>持有LOCK_open rea_create_table ha_create_table ha_innodb::create intern_sys_var_ptr —->回mysql层获取选项值,请求LOCK_global_system_variables
构成互相等待的死锁条件
这应该是一个Bug!
社区反馈:
@印风向社区反馈,社区确认这是一个已知的bug: bug68461.
但5.5已经确认fix,5.1不打算fix。官方对5.1的态度, 和我预想的一样,不死人就不用管,死人的话也要看死谁。
解决方法:
避免用于监控的频繁地 set global语句,以及调整业务代码中过于频繁的DDL。
评论暂时关闭