PHP使用数据库永久连接方式操作MySQL的是与非-阿里云开发者社区

开发者社区> 云栖希望。> 正文

PHP使用数据库永久连接方式操作MySQL的是与非

简介:
+关注继续查看

首先看看数据库永久连接的定义:

  永久的数据库连接是指在脚本结束运行时不关闭的连接。当收到一个永久连接的请求时。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达到最大连接数,使得之后的请求可能得不到响应。

——————————————————————————

 

状况一:

 使用 1 部 web server 与 1 部 MySQL server(两者可能同在一部主机上),而 web server 固定只对 MySQL server 上的某一个数据库进行存取动作。

 因为每次存取数据库时,都是由 web 那边使用同一账号对 MySQL 上的同一数据库作业,若我们将 MySQL 与 web server 的「同时联机数」都调整为 200,就好像 MySQL 这边一直有 200 位「服务生」,随时等着接待来自 web 的 200 位「顾客」似的。而且「顾客」离开之后,「服务生」也不下场休息,时时都站在门口等着接待下一个「顾客」。

 在这种情况下,您只要注意将 MySQL 的「同时联机数」调得比 web server 的高或相等,就会发现使用 mysql_pconnect( ) 是个不错的选择。

状况二:

 使用 1 部 web server 与 1 部 MySQL server(两者可能同在一部主机上),而 web server 会对 MySQL server 上的两个数据库进行存取动作。

 从 web server 那边提出数据存取需求时,有时是针对第 1 个数据库(DB1),有时则是针对第 2 个数据库(DB2)。若我们也将 MySQL 与 web server 的「同时联机数」都调整为 200,这样一来,就好像 MySQL 这边有 200 位「服务生」,但同时经营两个「吧台」(DB1 与 DB2),而「顾客」可能多达 200 位。

 一开始,DB1 这个「吧台」比较热门,MySQL 派了 150 位「服务生」上场接待;同样地,当「顾客」离开之后,这 150 位「服务生」仍守着 DB1 而不下场休息。后来,DB2 那边也热闹起来了,「顾客」越来越多,MySQL 得加派「服务生」上场,有几个能派?答案是 50 个!

 为什么「服务生」的人力调配会捉襟见肘?那是因为 web 那边使用了 mysql_pconnect( ) 来建立联机。「服务生」一开始被指定到哪个「吧台」工作,就会持续在那边停留,绝不「转台」。

——————————————————————————

请注意,当使用持续性的联机时,每个已建立的联机只为来自同一部 web server、使用同一组账号,且存取同一数据库的使用者服务。

 如此一来,假设每部 web server 的「同时联机数」都是 200,而且同时使用 2 部 web server 会怎么样呢?从 web1 来了 50 个「顾客」,先是到 DB1 走一趟,接着再到 DB2 晃一圈,这样需要多少「服务生」接待他们?100 个(web1->DB1: 50 web1->DB2: 50)!又从 web2 来了 50 个「顾客」,也做了同样的动作(web2->DB1: 50 web2->DB2: 50)。在此之后,还有「服务生」是闲着的吗?后续若从 web1 或 web2 同时涌入多于 50 位「顾客」时,谁来应付他们?

 倘若您使用的是像 Apache 这类的 multi-process web server(一个 parent process 协调一组 children processes 运作),某个 children process 建立的「持续联机」,是不能分享给其它 children process 来使用的(「服务生」只对先前接待过的「顾客」服务)。在这样的情况下,将会使得 MySQL 上闲置的 process 越积越多(很多「服务生」站在门口等着「老顾客」上门,而不理会「新顾客」)。
mysql_pconnect( ) 一定是最佳选择吗?我想未必尽然。

 

——– 两者之间的区别 ————–
mysql_pconnect() 和 mysql_connect() 非常相似,但有两个主要区别。
首先,当连接的时候本函数将先尝试寻找一个在同一个主机上用同样的用户名和密码已经打开的(持久)连接,如果找到,则返回此连接

标识而不打开新连接。
其次,当脚本执行完毕后到 SQL 服务器的连接不会被关闭,此连接将保持打开以备以后使用(mysql_close() 不会关闭由

mysql_pconnect() 建立的连接)。
可选参数 client_flags 自 PHP 4.3.0 版起可用。
此种连接称为”持久的”。
看到这里,写一条代码来测试一下

/*
* pconnect_test.php
*/

$link = mysql_pconnect("localhost", "mysql_user", "mysql_password")
        
or die("Could not connect: " . mysql_error());
    
print ("Connected successfully");

通过刷新网页的方式执行这条代码,发现每执行一次,mysql的进程数就增加一个。在这里我不禁有了疑问。上面说mysql_pconnect这个函

数的使用的时候,不是说”当连接的时候本函数将先尝试寻找一个在同一个主机上用同样的用户名和密码已经打开的(持久)连接,如果找到

,则返回此标识而不打开新连接”么?为什么我每刷新一次页面他就给我打开一个新的连接呢?

考虑到这有可能是PHP的bug,我到PHP的bug列表中找关于和too many connections 有关的条目。
相关的话题主要有三个,分别是

#11966        mysql_pconnect opens new connections with the same parameters
#26117        Persistent connection not reused
#13589        Persistent connections stay open and accumulate

描述比较长,我就不在这里贴,具体的内容你自己去看。重点主要是”当一个进程打开一个mysql的持续连接,只要该进程还存在,这个持续

的连接就不会断开,而且每一个进程会打开一个mysql的持续连接,而不能使用其他进程打开的持续连接”。

本文转自博客园知识天地的博客,原文链接:PHP使用数据库永久连接方式操作MySQL的是与非,如需转载请自行联系原博主。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
MySQL 基础---数据操作
数据的操作(CRUD): 插入数据记录(CREATE) 查询数据记录(READ) 更新数据记录(UPDATE) 删除数据记录(DELETE) 插入数据记录("INSERT INTO") 插入数据: 插入完整数据记录、插入数据记录一部分、插入多条数据记录、插入查询结果。
480 0
thinkphp对数据库操作有哪些内置函数
原文:thinkphp对数据库操作有哪些内置函数 getModelName() 获取当前Model的名称 getTableName() 获取当前Model的数据表名称 switchModel(type,vars=array()) 动态切换模型 table() 设置当前操作的数据表 field...
926 0
使用Spring AOP实现MySQL数据库读写分离案例分析
使用Spring AOP实现MySQL数据库读写分离案例分析 前言 分布式环境下数据库的读写分离策略是解决数据库读写性能瓶颈的一个关键解决方案,更是最大限度了提高了应用中读取 (Read)数据的速度和并发量。
1746 0
使用 Math 类操作数据
使用 Math 类操作数据 Math 类位于 java.lang 包中,包含用于执行基本数学运算的方法, Math 类的所有方法都是静态方法,所以使用该类中的方法时,可以直接使用类名.
555 0
使用iOS原生sqlite3框架对sqlite数据库进行操作(二)
使用iOS原生sqlite3框架对sqlite数据库进行操作
18 0
阿里云大数据计算服务MaxCompute命令行工具——odpscmd的操作使用
在MaxCompute生态中,命令行工具究竟处于什么样的位置?它又发挥着什么样的作用?能够帮助开发者如何更好使用MaxCompute?在本文中,阿里巴巴计算平台产品专家曲宁将通过一个完整简单的小例子为大家介绍MaxCompute命令行工具odpscmd的使用以及其所具有的各种能力。
4567 0
Node.js使用mongodb操作MongoDB数据库
Node.js使用mongodb操作MongoDB数据库
24 0
+关注
云栖希望。
我是个随便的人
761
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载