|
mysql gone away 简单的说就是连接不见了,那为啥不见了?
这个我会在最后说。
以下是网上的文章,觉得有些旁敲侧击了。
<hr/>
http://blog.csdn.net/u012260707/article/details/78223008
问题描述:
Error Info:
Array
(
[0] => HY000
[1] => 2006
[2] => MySQL server has gone away
)
&#34;用php跑数据 任务时间过长,每次都会出现这个,能帮忙把这个超时时间设置到最大吗,下周我们仔细看看这个是啥问题,之前用JDBC跑数 不会出现这个问题,应该是php,yii2一直拿connection没有释放&#34;
JDBC中!=null 就close 这种事我觉得应该是框架做的
上述可知用JDBC无此问题,用yii2频繁出现,定位是yii2的问题,gone-away意思是连接不见了,断掉了,那么有没有colse和open的方法呢,断掉了我们手动去open一下
查了一下open和close的写法为
[php] view plain copy
- Yii::$app->db->open();
- Yii::$app->db->close();
思路是在
try{
//code
}catch(Exception $e){
//去判断 $e是不是2006,然后去open一下,然后再colse一下
}
每个方法都去写一个这样的try{}catch{}不是很科学,通常的做法是在顶级父类的afterAction或入口去拦截这样的错误
最终选取的做法,重载yii\db\Command的execute和queryInternal方法
阅读yii\db\Command源码可知
execute()--->所有的增删改操作的入口
queryInternal()---->所以的查询操作的入口
最终书写一个Command去继承yii\db\Command,然后在数据库db配置中把默认的command Class 改成我们自己写的子类command
scm 修改示例
[php] view plain copy
- &#39;db => [
- &#39;class&#39; => &#39;yii\db\Connection&#39;,
- &#39;dsn&#39; => $scm_config[&#39;db.dsn&#39;],
- &#39;username&#39; => $scm_config[&#39;db.username&#39;],
- &#39;password&#39; => $scm_config[&#39;db.password&#39;],
- &#39;charset&#39; => &#39;utf8&#39;,
- &#39;tablePrefix&#39; => &#39;tb_&#39;,
- &#39;commandClass&#39; => &#39;app\components\Command&#39; //自己写的子类Command
- ],
[php] view plain copy
- <?php
- /**
- * Created by PhpStorm.
- * User: liuyifan
- * Date: 16/09/17
- * Time: 下午 04:24
- */
- namespace app\components;
- use yii\db\Exception;
- use yii\db\Command as YiiCommand;
- /**
- * Class Command
- * @package app\components
- * 解决mysql-gone-away 2006,2013的问题
- */
- class Command extends YiiCommand
- {
- const SLEEP_TIME = 60;
- /***
- * @return int
- * @throws Exception
- * 所有[增删改]操作调用
- */
- public function execute()
- {
- try {
- return parent::execute();
- } catch (Exception $e) {
- if ($e->errorInfo[1] == 2006 || $e->errorInfo[1] == 2013) {
- echo &#39;[Mysql-&#39;.$e->errorInfo[1].&#39;] problem handler with app\components\Command execute()...&#39;.PHP_EOL;
- $this->db->close();
- $this->db->open();
- $this->pdoStatement = null ;
- sleep(self::SLEEP_TIME);
- return parent::execute();
- }else{
- throw $e;
- }
- }
- }
- /***
- * @param string $method
- * @param null $fetchMode
- * @return mixed
- * @throws Exception
- * 所有[查操作]都会调用queryInternal方法
- */
- protected function queryInternal($method, $fetchMode = null){
- try {
- return parent::queryInternal($method, $fetchMode);
- } catch (Exception $e) {
- if ($e->errorInfo[1] == 2006 || $e->errorInfo[1] == 2013) {
- echo &#39;[Mysql-&#39;.$e->errorInfo[1].&#39;] problem handler with app\components\Command queryInternal()...&#39;.PHP_EOL;
- $this->db->close();
- $this->db->open();
- $this->pdoStatement = null ;
- sleep(self::SLEEP_TIME);
- return parent::queryInternal($method, $fetchMode);
- }else{
- throw $e;
- }
- }
- }
- }
附上测试类
[php] view plain copy
- //php yii test/my-sql-gone-away-2006
- public function actionMySqlGoneAway2006() {
- $this->print_f(&#39;MySql_Gone_Away_2006 test......&#39;);
- $seconds = 20;
- $hours = $seconds/3600;
- $minutes = $seconds/60;
- $this->setMysqlInteractiveTimeout($seconds-10);
- $this->setMysqlWaitTimeout($seconds-10);
- Yii::$app->db->createCommand(&#34;select * from test&#34;)->queryAll();
- $this->print_f(&#39;sleep start ....&#39;);
- $this->print_f(&#34;sleep time {$hours}h={$minutes}m={$seconds}s ....&#34;);
- sleep($seconds);
- $this->print_f(&#39;sleep end ....&#39;);
- Yii::$app->db->createCommand(&#34;insert into test(name,age) VALUES (&#39;liuyifan&#39;,40)&#34;)->execute();
- Yii::$app->db->createCommand(&#34;insert into test(name,age) VALUES (&#39;xiuyuding&#39;,3)&#34;)->execute();
- Yii::$app->db->createCommand(&#34;insert into test(name,age) VALUES (&#39;wangyong&#39;,28)&#34;)->execute();
- Yii::$app->db->createCommand(&#34;insert into test(name,age) VALUES (&#39;guandongdong&#39;,26)&#34;)->execute();
- Yii::$app->db->createCommand(&#34;insert into test(name,age) VALUES (&#39;changhuanhuan&#39;,-1)&#34;)->execute();
- Yii::$app->db->createCommand(&#34;insert into test(name,age) VALUES (&#39;wangdandan&#39;,-1)&#34;)->execute();
- }
- public function setMysqlInteractiveTimeout($seconds) {
- $sql = &#34;set interactive_timeout=$seconds&#34;;
- Yii::$app->db->createCommand($sql)->execute();
- }
- public function setMysqlWaitTimeout($seconds) {
- $sql = &#34;set wait_timeout=$seconds&#34;;
- Yii::$app->db->createCommand($sql)->execute();
- }
附上网上找的老外写的总结性文章: sqlstatehy000-general-error-2006-mysql-server-has-gone-away
<hr/>
首先要看看mysql的配置文件里的wati_timeoutwait设置对没,这个参数的单位是秒,如果设置的很低,比如5,那么当数据提交内容较多,存入数据久些,则会出现 mysql gone away。根本的办法还是更改mysql配置文件,然后重启mysql。 |
|