PHP activerecord mysql服务器已经消失了

RTB*_*RTB 12 php mysql activerecord phpactiverecord wrench

我现在正在使用php-activerecord一段时间,我非常喜欢它.Php-activerecord是一个基于ActiveRecord模式的开源ORM库.但是,我最近尝试将它与基于Wrench的websocket应用程序结合使用.

这非常有效但是为了启动脚本,应用程序必须作为linux上的守护进程运行才能使websocket始终处于可用状态.在不使用应用程序然后尝试再次使用它之后,它会抛出一些数据库异常:

起初它会发出警告:

PHP Warning: Error while sending QUERY packet. PID=XXXXX in /home/user/domains/example.com/public_html/vendor/php-activerecord/php-activerecord/lib/Connection.php on line 322
Run Code Online (Sandbox Code Playgroud)

然后它抛出一个致命的错误:

PHP Fatal error: Uncaught exception 'ActiveRecord\DatabaseException' with message 'exception 'PDOException' with message 'SQLSTATE[HY000]: General error: 2006 MySQL server has gone away' in /home/user/domains/example.com/public_html/vendor/php-activerecord/php-activerecord/lib/Connection.php:322
Run Code Online (Sandbox Code Playgroud)

堆栈跟踪:

#0 /home/user/domains/example.com/public_html/vendor/php-activerecord/php-activerecord/lib/Connection.php(322): PDOStatement->execute(Array)

#1 /home/user/domains/example.com/public_html/vendor/php-activerecord/php-activerecord/lib/Table.php(218): ActiveRecord\Connection->query('SELECT * FROM ...', Array)

#2 /home/user/domains/example.com/public_html/vendor/php-activerecord/php-activerecord/lib/Table.php(209): ActiveRecord\Table->find_by_sql('SELECT * FROM `...', Array, false, NULL)

#3 /home/user/domains/example.com/public_html/vendor/php-activerecord/php-activerecord/lib/Model.php(1567): ActiveRecord\Table->find(Array)

#4 in /home/user/domains/example.com/public_html/vendor/php-activerecord/lib/Connection.php on line 325
Run Code Online (Sandbox Code Playgroud)

似乎php-activerecord一直保持mysql连接在websocket服务器运行时保持打开状态,如果它自动尝试重新连接并再次运行查询,那么这个问题应该不是问题.但它没有.

我读过有关设置的内容MYSQL_OPT_RECONNECT.但我不确定这是否有效或如何使用php-activerecord设置该选项.这里有人有这方面的经验吗?

编辑:这是我的全局超时配置变量

VARIABLE_NAME                   VARIABLE_VALUE  
DELAYED_INSERT_TIMEOUT          300
WAIT_TIMEOUT                    28800
CONNECT_TIMEOUT                 10
LOCK_WAIT_TIMEOUT               31536000
INNODB_ROLLBACK_ON_TIMEOUT      OFF
THREAD_POOL_IDLE_TIMEOUT        60
NET_WRITE_TIMEOUT               60
INNODB_LOCK_WAIT_TIMEOUT        50
INTERACTIVE_TIMEOUT             28800
DEADLOCK_TIMEOUT_LONG           50000000
SLAVE_NET_TIMEOUT               3600
DEADLOCK_TIMEOUT_SHORT          10000
NET_READ_TIMEOUT                30
Run Code Online (Sandbox Code Playgroud)

chu*_*die 5

PHP ActiveRecord使用PDO.绝对没有办法关闭PDO连接,对于长时间运行的后台任务来说,它是错误的数据库层.

您可以尝试使用以下代码段影响 PDO连接的断开连接.

//if not using ZF2 libraries, disconnect in some other way
$db->getDriver()->getConnection()->disconnect()
$db = NULL;
gc_collect_cycles();
Run Code Online (Sandbox Code Playgroud)

断开连接,将引用设置为null,然后运行垃圾收集器.希望是调用PDO的内部__destruct方法来实际关闭连接.

必须在自己的长期运行脚本中管理数据库连接.如果您的工作人员不必在一段时间内处理工作,则必须断开连接,并且必须在工作时重新连接.

真正的解决方案是不使用PDO并正常断开连接和重新连接.

如果您只是将服务器和客户端库超时都设置为无限,那么您将遇到永不消亡的失控脚本的问题,迫使您重新启动整个服务器(不是一个好主意混乱超时).

编辑:我实际上有这个确切的问题,并在去年使用这个确切的解决方案.这解决了我99%的问题.但是,每隔一段时间就会遇到一个我无法捕捉并试图重新连接的杂散连接异常.我只是每天重启一次进程,以摆脱那些错误的连接错误.这就是为什么我的答案是,不要使用PDO.立即切换,实现对断开连接和重新连接的真正控制.