PHP建立MySQL持久化连接(长连接)及mysql与mysqli扩展的区别

如果在 PHP 5.3 的版本以前想要创建MySQL的持久化连接(长连接),需要显式调用 pconnect 创建:

复制代码
$con = mysql_pconnect($server['host'], $server['username'], $server['password']);
if (!($con === false)) {
if (mysql_select_db($server['database'], $con) === false) {
    echo('Could not select database: ' . mysql_error());
    continue;
}
// do something here......
}

从 PHP 5.3 开始, mysqli 扩展开始支持持久化连接,持久化连接已经在 PDO MYSQL 和 ext/mysql 中提供支持。

持久化连接的优势

持久化连接的目的在于重用客户端到服务器之间的连接, 而不是每次在需要的时候都重新建立一个连接。
由于持久化连接可以将已经建立的连接缓存起来,以备后续的使用, 所以省去了建立新的连接的开销, 因此可以带来性能上的提升

不像 mysql 扩展,mysqli 没有提供一个特殊的方法用于打开持久化连接。 如果 mysqli 打开一个持久化连接,需要在创建连接时,在host前面增加p:两个字符。

mysql 和 mysqli 扩展的区别如下:

持久链接建立方式,mysqli是在host前面增加"p:"两个字符;mysql使用mysql_pconnect函数;

mysqli 建立的持久链接,必须在mysqli_close之后,才能被下一个请求复用;mysql的长连接,可以立即被复用;

pdo 建立的持久链接,不必关闭,就能复用;

mysqli 建立持久链接时,会自动清理上一个会话变量、回滚事务、解锁表、释放锁等操作;而 mysql 扩展则不会(这点非常重要 );

mysqli 判断是否为同一持久链接标识是 IP,PORT、USER、PASS、DBNAME、SOCKET;mysql 是 IP、PORT、USER、PASS、CLIENT_FLAGS;

持久化长连接的风险

使用持久化连接也会存在一些风险, 因为在缓存中的连接可能处于一种不可预测的状态。

例如,如果客户端未能正常关闭连接, 可能在这个连接上残留了对库表的锁, 那么当这个连接被其他请求重用的时候,这个连接还是处于 有锁的状态。

所以,如果要很好的使用持久化连接,那么要求代码在和数据库进行交互的时候, 确保做好清理工作,保证被缓存的连接是一个干净的,没有残留的状态。

mysqli 扩展的持久化连接提供了内建的清理处理代码。 mysqli 所做的清理工作包括:

回滚处于活动状态的事务

关闭并且删除临时表

对表解锁

重置会话变量

关闭预编译 SQL 语句(在PHP中经常发生)

关闭处理程序

释放通过 GET_LOCK() 获得的锁

这确保了将连接返回到连接池的时候, 它处于一种"干净"的状态,可以被其他客户端进程所使用。

mysqli 扩展 通过自动调用 C-API 函数 mysql_change_user() 来完成这个清理工作。

自动清理的特性有优点也有缺点:

优点是程序员不再需要担心附加的清理代码, 因为它们会自动调用。

然而缺点就是 性能 可能会 慢一点, 因为每次从连接池返回一个连接都需要执行这些清理代码。

这个自动清理的代码可以通过在编译 php 时定义
MYSQLI_NO_CHANGE_USER_ON_PCONNECT 来关闭。

注意: mysqli 扩展在使用 MySQL Native Driver 或 Mysql Client Library(libmysql)时都支持持久化连接。

为什么我的长连接不生效?

村长多说两句,相信很多小伙伴遇到过这个问题:

明明创建了 pconnect,show process_list 查看数据库链接,却发现长连接没有被复用,而是重新创建了一个,这是为啥呢?这得从PHP的运作模式说起。

一般 php 有2种运行模式, 一是作为 cgi 运行, 二是作为 apache 的模块运行:

作为 cgi 的时候 connect 跟 pconnect 没什么不同, 因为每次 cgi 进行运行结束后都会被销毁清理掉资源;

php 作为 apache 模块方式运行时, 可以使用到数据库持续连接, 但可能会存在潜在的问题;

说白了,如果你是 cgi 运行方式,pconnection 永远也不会生效

长连接最大的缺点就是万一一个用户锁死,当前进程就永久锁死了;假如你在apache里的设置是进程永不销毁的话就...

总之,尽量使用 mysql_connect,因为运行结束后会自动断开;再说了现在的机器性能都不差,不至于缺少那点儿创建销毁带来的内存开销。
最后编辑于:2025-02-05 20:59:54
© 著作权归作者所有,转载或内容合作请联系作者

喜欢的朋友记得点赞、收藏、关注哦!!!

相关推荐
叽哥5 分钟前
Kotlin学习第 1 课:Kotlin 入门准备:搭建学习环境与认知基础
android·java·kotlin
Hy行者勇哥19 分钟前
物联网软件开发过程中,数据流图(DFD),用例图,类图,活动图,序列图,状态图,实体关系图(ERD),BPMN(业务流程建模)详解分析
java·物联网·struts
Miracle65824 分钟前
从 0 到 1 开发校园二手交易系统:飞算 JavaAI 全流程实战
java
A尘埃39 分钟前
Java+Python混合微服务OCR系统设计
java·python·微服务·混合
Seven971 小时前
剑指offer-22、从上往下打印⼆叉树
java
计算机毕设-小月哥1 小时前
完整源码+技术文档!基于Hadoop+Spark的鲍鱼生理特征大数据分析系统免费分享
大数据·hadoop·spark·numpy·pandas·计算机毕业设计
Jinkxs1 小时前
AI重塑金融风控:从传统规则到智能模型的信贷审批转型案例
大数据·人工智能
A尘埃1 小时前
企业级Java项目金融应用领域——保险系统(补充)
java·金融·保险系统
冬天vs不冷1 小时前
Java基础(九):Object核心类深度剖析
java·开发语言·python
悟空聊架构2 小时前
我的网站被攻击了,被干掉了 120G 流量,还在持续攻击中...
java·前端·架构