在csdn上看到有人问:mysql_connect后是不是非要mysql_close,是不是自动释放?

大家伙们,PHP数据库连接是不是在页面执行完之后自己释放,即使不用mysql_close()也可以释放掉?
同理PDO连接到数据库后,是不是非要将PDO实例赋值为NULL,才能将PDO连接断掉?

在N久以前我查过资料,但己经模糊不清了,具说PHP处理每一个被请求的页面时,里面有MYSQL连接的,当页面处理完就立刻释放掉所有用到的资料。如:mysql_connect后的连接。这个说法对吗?PDO同理吗?

第一反应是CGI模式下,mysql_connect是当前请求结束自动释放,而mysql_pconnect是可以被同一web进程(线程)中的多个请求重复使用的。但是为什么呢?

查看php.net上的帮助:

mysql_pconnect() acts very much like mysql_connect() with two major differences.

First, when connecting, the function would first try to find a (persistent) link that’s already open with the same host, username and password. If one is found, an identifier for it will be returned instead of opening a new connection.

Second, the connection to the SQL server will not be closed when the execution of the script ends. Instead, the link will remain open for future use (mysql_close() will not close links established by mysql_pconnect()).

This type of link is therefore called ‘persistent’.

首先,mysql_pconnect建立的链接不会在script结束后释放,那么对于CLI模式呢?从道理和实践代码中检测,都是会释放的。因为进程退出时,所有的资源都会被自动回收。通过以下的代码可以简单的验证:

$db = mysql_pconnect(‘localhost’, ‘mysql’, ‘pwd’);
sleep(100);
var_dump($db);
exit;
同时在mysql中执行:
mysql> show processlist;  # sleep期间
+—-+——-+—————–+——–+———+——+——-+——————+
| Id | User  | Host            | db     | Command | Time | State | Info             |
+—-+——-+—————–+——–+———+——+——-+——————+
|  1 | mysql | localhost:63950 | tshare | Sleep   |    1 |       | NULL             |
| 68 | mysql | localhost       | NULL   | Query   |    0 | NULL  | show processlist |
| 73 | mysql | localhost       | NULL   | Sleep   |   20 |       | NULL |
+—-+——-+—————–+——–+———+——+——-+——————+
3 rows in set (0.01 sec)
mysql> show processlist;  # 进程结束
+—-+——-+—————–+——–+———+——+——-+——————+
| Id | User  | Host            | db     | Command | Time | State | Info             |
+—-+——-+—————–+——–+———+——+——-+——————+
|  1 | mysql | localhost:63950 | tshare | Sleep   |    0 |       | NULL             |
| 68 | mysql | localhost       | NULL   | Query   |    0 | NULL  | show processlist |
+—-+——-+—————–+——–+———+——+——-+——————+
2 rows in set (0.00 sec)

那么CLI模式呢?将上面这段代码cp至一个web页面中,通过浏览器访问结束后,show processlist仍然可以看到有连接存在!这就使得多个web请求可以复用同一mysql链接,从而节省了建立连接的过程。但是这样也可能造成问题,就是当允许的web进程(线程)数目超过mysql的max_connections时,会造成web进程连接mysql服务器的阻塞,因为每个web进程都不释放自己的mysql连接,从而可能造成too many connections的mysql错误。可以参考我之前的blog:http://flykobe.com/index.php/2011/01/20/mysql-too-many-connections%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88/

那么它会存在多久呢?与mysqld的wait_timeout相关。如果一直没有被复用,那么它会存在wait_timeout时长,单位是秒。

mysql> show variables like ‘wait_timeout’;
+—————+——-+
| Variable_name | Value |
+—————+——-+
| wait_timeout  | 28800 |
+—————+——-+
1 row in set (0.00 sec)
当然,如果web server的进程(线程)结束,mysql_pconnect建立的连接也会结束。

Leave a Reply