background image

PHP 使用数据库永久连接方式操作 MySQL

本文主要讲述了 PHP 使用数据库永久连接方式操作 MySQL,供大家参考下
PHP 程序员应该都知道连接 MySQL 数据库可以使用 mysql_pconnect(永久连接)函数,
使用数据库永久连接可以提高效率,但是实际应用中数据库永久连接往往会导致出现一
些问题,通常的表现就是在大访问量的网站上时常发生断断续续的无法连接数据库的情
况,出现类似"Too many connections in ..."的错误提示信息,重新启动服务器又正常了,
但过不了一会儿又出现同样的故障。对于这些问题的成因,恐怕就不是每个人都能说清楚
的了,虽然 PHP 文档里有一些相关资料,但是解释的并不浅显易懂,这里我厚着脸皮试
图做一个简单的讨论,所述观点不见得全都正确,欢迎大家反馈意见。

首先看看数据库永久连接的定义:
永久的数据库连接是指在脚本结束运行时不关闭的连接。当收到一个永久连接的请求时 。
PHP 将检查是否已经存在一个(前面已经开启的)相同的永久连接。如果存在,将直接使

用这个连接;如果不存在,则建立一个新的连接。所谓 相同 的连接是指用相同的用户名
和密码到相同主机的连接。

PHP 使用永久连接方式操作 MySQL 是有前提的:就是 PHP 必须安装为多线程或多进程
Web 服务器的插件或模块。最常见的形式是把 PHP 用作多进程 Apache 服务器的一个模块。
对于一个多进程的服务器,其典型特征是有一个父进程和一组子进程协调运行,其中实
际生成 Web 页面的是子进程。每当客户端向父进程提出请求时,该请求会被传递给还没
有被其它的客户端请求占用的子进程。这也就是说当相同的客户端第二次向服务端提出请
求时,它将有可能被一个不同的子进程来处理。在开启了一个永久连接后,所有不同子进
程请求 SQL

 

服务的后继页面都能够重新使用这个已经建立的 SQL 服务器连接。它使得每

 

个子进程在其生命周期中只做一次连接操作,而非每次在处理一个页面时都要向 SQL 服
务器提出连接请求。每个子进程将对服务器建立各自独立的永久连接。PHP 本身并没有数
据库连接池的概念,但是 Apache 有进程池的概念, 一个 Apache 子进程结束后会被放回进
程池, 这也就使得用 mysql_pconnect 打开的的那个 mysql 连接资源可以不被释放,而是依
附在相应的 Apache 子进程上保存到了进程池中。于是在下一个连接请求时它就可以被复
用 。 一 切 看 起 来 似 乎 都 很 正 常 , 但 是 在 Apache 并 发 访 问 量 大 的 时 候 , 如 果 使 用
mysql_pconnect

 

,会由于之前的 Apache 子进程占用的 MySQL 连接没有 close, 很快使

MySQL 达到最大连接数,使得之后的请求可能得不到响应。

上面的部分文字是摘抄自 PHP 文档,以下用例子来说明问题:

假设 Apache 配置最大连接数为 1000,MySQL 配置最大连接数为 100,当 Apache 服务器
接到 200 个并发访问的时候,其中 100 个涉及到数据库访问,剩下的 100 个不涉及数据库
访问,因为这个时候还不存在可用的数据库连接,所以这里面涉及到数据库访问的 100
个并发会同时产生 100 个数据库永久连接,达到了数据库最大连接数,当这些操作没有