default_socket_timeout和mysql.connect_timeout之间的确切关系?

时间:2018-08-24 16:01:07

标签: php mysql

网络上有很多文章,并且在StackExchange上都有答案,建议使用类似这样的行(甚至更长的超时时间),以避免在长时间运行的过程(例如但不限于“ MySQL服务器”)中出现MySQL超时错误已经消失”):

ini_set('mysql.connect_timeout', 300);
ini_set('default_socket_timeout', 300);

但是,我无法很好地解释它们是如何解决问题的。在许多情况下,它们似乎是没有明确基础的货物崇拜编程。我很好奇这些设置对MySQL连接生命周期的精确程度:官方文档不清楚它们何时适用和评估。

据我所知mysql.connect_timeout仅涉及与MySQL的原始连接。因此,在最初建立成功的连接之后,此设置似乎与连接失败问题无关。设置default_socket_timeout可能与以后的连接问题更相关,但尚不清楚究竟是什么会触发超时。它也仅在连接时才有意义,还是整个套接字寿命都超时?是什么触发超时?流量不足?缺乏特定类型的流量?

准确了解它们与MySQL连接的交互方式对于能够合理地推断错误行为很重要。

1 个答案:

答案 0 :(得分:1)

在长时间运行的进程中,两种设置都与获取“ mysql走开”无关。从历史上看,MySQL没有办法限制查询的最大运行时间,因为这样可以永久运行,而且由于在I / O事件期间无法检查phps的最大执行时间,因此也无法停止查询。

要限制SQL查询的运行时间,可以在5.7中使用新的MySQL功能:

SELECT /*+ MAX_EXECUTION_TIME(1000) */ status, count(*) FROM articles GROUP BY status ORDER BY status;
SET SESSION MAX_EXECUTION_TIME=2000;
SET GLOBAL MAX_EXECUTION_TIME=2000;

我在此处写了一篇有关此内容的博客文章,

https://tideways.com/profiler/blog/use-timeouts-to-prevent-long-running-select-queries-from-taking-down-your-mysql

但是要修复MySQL已经不复存在,您需要在长时间运行的脚本中指出一点,您知道它一段时间没有执行任何操作并添加了“ ping”。

try {
    $pdo->query("SELECT 1");
} catch (PDOException $e) {
    if (stripos($pdo->getMessage(), "mysql gone away")) {
        // reconnect
    }
}

这样,每当mysql消失时,您都可以重新连接。