IE盒子

搜索
查看: 120|回复: 0

php yii2 出现mysql-gone-away-2006解决

[复制链接]

2

主题

9

帖子

14

积分

新手上路

Rank: 1

积分
14
发表于 2023-1-4 16:04:44 | 显示全部楼层 |阅读模式
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
)
"用php跑数据 任务时间过长,每次都会出现这个,能帮忙把这个超时时间设置到最大吗,下周我们仔细看看这个是啥问题,之前用JDBC跑数 不会出现这个问题,应该是php,yii2一直拿connection没有释放"
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

  • 'db => [
  • 'class' => 'yii\db\Connection',
  • 'dsn' => $scm_config['db.dsn'],
  • 'username' => $scm_config['db.username'],
  • 'password' => $scm_config['db.password'],
  • 'charset' => 'utf8',
  • 'tablePrefix' => 'tb_',
  • 'commandClass' => 'app\components\Command' //自己写的子类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 '[Mysql-'.$e->errorInfo[1].'] problem handler with app\components\Command execute()...'.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 '[Mysql-'.$e->errorInfo[1].'] problem handler with app\components\Command queryInternal()...'.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('MySql_Gone_Away_2006 test......');
  • $seconds = 20;
  • $hours = $seconds/3600;
  • $minutes = $seconds/60;
  • $this->setMysqlInteractiveTimeout($seconds-10);
  • $this->setMysqlWaitTimeout($seconds-10);
  • Yii::$app->db->createCommand("select * from test")->queryAll();
  • $this->print_f('sleep start ....');
  • $this->print_f("sleep time {$hours}h={$minutes}m={$seconds}s ....");
  • sleep($seconds);
  • $this->print_f('sleep end ....');
  • Yii::$app->db->createCommand("insert into test(name,age) VALUES ('liuyifan',40)")->execute();
  • Yii::$app->db->createCommand("insert into test(name,age) VALUES ('xiuyuding',3)")->execute();
  • Yii::$app->db->createCommand("insert into test(name,age) VALUES ('wangyong',28)")->execute();
  • Yii::$app->db->createCommand("insert into test(name,age) VALUES ('guandongdong',26)")->execute();
  • Yii::$app->db->createCommand("insert into test(name,age) VALUES ('changhuanhuan',-1)")->execute();
  • Yii::$app->db->createCommand("insert into test(name,age) VALUES ('wangdandan',-1)")->execute();
  • }
  • public function setMysqlInteractiveTimeout($seconds) {
  • $sql = "set interactive_timeout=$seconds";
  • Yii::$app->db->createCommand($sql)->execute();
  • }
  • public function setMysqlWaitTimeout($seconds) {
  • $sql = "set wait_timeout=$seconds";
  • 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。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表