本文主要是介绍cli执行脚本时出现(2006 MySQL server has gone away) 问题处理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
最近有同事问我,有个cli运行的处理脚本经常没执行完就退出了,导致日志表里显示脚本运行状态一直显示在执行中。
了解到他的逻辑如下:
程序开始时建立两个数据库连接A和B(因为业务数据表和日志表在两个数据库中),连接A用来保存抓取的业务数据,连接B用来保存脚本运行的状态。当抓取的数据保存完后,用连接B将日志表中的脚本运行状态改为已完成。
听到这个问题就觉得可能是数据库连接断开引起的,因为mysql服务器端在连接闲置时间(wait_timeout)达到设定值后,就会释放掉该连接,开始排查吧。
问题排查过程:
//开始执行脚本
php /path/test.php
//查看PHP脚本进程ID
ps -ef|grep "test.php"
//用strace查看进程执行过程
strace -tt -s 512 -p 1111
//手动关闭mysql连接,模拟连接断开的场景
mysql -uroot -p123 -h127.0.0.1show processlist;kill 进程ID;
发现有两个问题
1、在用CURL请求外部接口时,如果请求失败抛异常,但业务代码里没有对异常进行处理,导致请求接口超时或其它错误时直接退出执行。
$errno = curl_errno($ch);if ($errno){curl_close($ch);throw new Exception($errno,0);}
这明显是程序员经验不够,忘记了处理异常。处理方法就是在业务代码里用CURL请求接口时,使用try catch去捕获异常进行处理。
2、当mysql连接被关闭后,再去做select或insert/update操作时,会异常退出(2006 :MySQL server has gone away)。
这里对数据操作类mysqli.class.php做了一些修改,增加了失败错误码为2006时重试机制
if ($this->_linkID->errno == 2006 || $this->_linkID->errno == 2013){$this->close();$this->initConnect(true);$result = $this->_linkID->query($str);if(false !== $result){$this->numRows = $this->_linkID->affected_rows;$this->lastInsID = $this->_linkID->insert_id;return $this->numRows;}}
这篇关于cli执行脚本时出现(2006 MySQL server has gone away) 问题处理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!