关于php连接mysql超时问题以及mysql参数

分类:技术文档 - JS文档 | 阅读(3959) | 发布于:2014-06-27 10:09

MySQL server has gone away 报错处理
最新在写一个程序需要php一直保持运行状态,并且每隔一段时间就会链接mysql数据库做查询.

但是发现每次只有第一次查询是成功的,后面均为失败.而缩小间隔时间,确可以正常查询。由于mysql链接只在脚本刚运行的时候

链接过一次。后面sleep之后使用的是之前的连接资源。而缩小sleep的时间则可以正常查询。

于是猜测是否因为php脚本sleep时间过长导致mysql的链接超时而被mysql主动关闭了链接。

于是网上查了查资料,发现是nteractive_timeout和wait_timeout这2个参数在捣鬼。

根据mysql手册原文说明:

wait_timeout:

The number of seconds the server waits for activity on a noninteractive connection before closing it. This timeout applies only to TCP/IP and Unix socket file connections, not to connections made using named pipes, or shared memory.

On thread startup, the session wait_timeout value is initialized from the global wait_timeout value or from the global interactive_timeout value, depending on the type of client (as defined by the CLIENT_INTERACTIVEconnect option to mysql_real_connect()).

interactive_timeout:
The number of seconds the server waits for activity on an interactive connection before closing it. An interactive client is defined as a client that uses the CLIENT_INTERACTIVE option to  mysql_real_connect() .

原来php链接mysql的时候分为2种链接类型,一种是交互模式(interactive ),一种叫非交互模式(noninteractive )。

而wait_timeout 参数就是非交互模式链接中,mysql服务器等待链接超时的时间(即服务器端 链接sleep的时间,可以在mysql服务端通过show processlist 命令查看链接sleep的时间)

interactive_timeout 就是交互模式链接中,mysql服务器等待链接超时的时间了.

而一个链接的是否是交互模式则取决于客户端链接mysql时传递的参数,对于php来说就是调用mysql_connect时 第五个参数是否设置为

MYSQL_CLIENT_INTERACTIVE。如果设置为 MYSQL_CLIENT_INTERACTIVE 则interactive_timeout 参数生效否则wait_timeout参数生效

 

我查看了一下服务端的 这2个参数均设置为240s,而php sleep的时间为300s。那么mysql查询失败的原因就很明白了。

 

解决方案有2种:1、当然是修改这2个参数 使其大于php  sleep的时间即可

2、php端使用mysql_pconnect 即mysql持久化链接

说到 mysql_pconnect 也顺便提一句.当使用mysql_pconnect的时候,php脚本结束时是不会自动关闭mysql链接,即使调用mysql_close也无法关闭。另附php收藏关于持久化链接的说明:

数据库永久连接

永久的数据库连接是指在脚本结束运行时不关闭的连接。当收到一个永久连接的请求时。PHP 将检查是否已经存在一个(前面已经开启的)相同的永久连接。如果存在,将直接使用这个连接;如果不存在,则建立一个新的连接。所谓“相同”的连接是指用相同的用户名和密码到相同主机的连接。

对 web 服务器的工作和分布负载没有完全理解的读者可能会错误地理解永久连接的作用。特别的,永久连接不会在相同的连接上提供建立“用户会话”的能力,也不提供有效建立事务的能力。实际上,从严格意义上来讲,永久连接不会提供任何非永久连接无法提供的特殊功能。

为什么?

这和 web 服务器工作的方式有关。web 服务器可以用三种方法来利用 PHP 生成 web 页面。

第一种方法是将 PHP 用作一个“外壳”。以这种方法运行,PHP 会为向 web 服务器提出的每个 PHP 页面请求生成并结束一个 PHP 解释器线程。由于该线程会随每个请求的结束而结束,因此任何在这个线程中利用的任何资源(例如指向 SQL 数据库服务器的连接)都会随线程的结束而关闭。在这种情况下,使用永久连接不会获得任何地改变——因为它们根本不是永久的。

第二,也是最常用的方法,是把 PHP 用作多进程 web 服务器的一个模块,这种方法目前只适用于 Apache。对于一个多进程的服务器,其典型特征是有一个父进程和一组子进程协调运行,其中实际生成 web 页面的是子进程。每当客户端向父进程提出请求时,该请求会被传递给还没有被其它的客户端请求占用的子进程。这也就是说当相同的客户端第二次向服务端提出请求时,它将有可能被一个不同的子进程来处理。在开启了一个永久连接后,所有请求 SQL 服务的后继页面都能够重新使用这个已经建立的 SQL Server 连接。

最后一种方法是将 PHP 用作多线程 web 服务器的一个插件。目前 PHP 4 已经支持 ISAPI、WSAPI 和 NSAPI(在 Windows 环境下),这些使得 PHP 可以被用作诸如 Netscape FastTrack (iPlanet)、Microsoft's Internet Information Server (IIS) 和 O'Reilly's WebSite Pro 等多线程 web 服务器的插件。永久连接的行为和前面所描述的多过程模型在本质上是相同的。注意 PHP 3 不支持 SAPI。

如果永久连接并没有任何附加的功能,那么使用它有什么好处?

答案非常简单——效率。当客户端对 SQL 服务器的连接请求非常频繁时,永久连接将更加高效。连接请求频繁的标准取决于很多因素。例如,数据库的种类,数据库服务和 web 服务是否在同一台服务器上,SQL 服务器如何加载负载等。但我们至少知道,当连接请求很频繁时,永久连接将显著的提高效率。它使得每个子进程在其生命周期中只做一次连接操作,而非每次在处理一个页面时都要向 SQL 服务器提出连接请求。这也就是说,每个子进程将对服务器建立各自独立的永久连接。例如,如果有 20 个不同的子进程运行某脚本建立了永久的 SQL 服务器永久连接,那么实际上向该 SQL 服务器建立了 20 个不同的永久连接,每个进程占有一个。

注意,如果永久连接的子进程数目超过了设定的数据库连接数限制,系统将会产生一些缺陷。如果数据库的同时连接数限制为 16,而在繁忙会话的情况下,有 17 个线程试图连接,那么有一个线程将无法连接。如果这个时候,在脚本中出现了使得连接无法关闭的错误(例如无限循环),则该数据库的 16 个连接将迅速地受到影响。请查阅使用的数据库的文档,以获取关于如何处理已放弃的及闲置的连接的方法。

标签:mysql超时