php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #51605 Mysqli - zombie links
Submitted: 2010-04-19 21:27 UTC Modified: 2012-05-21 23:12 UTC
From: bastard dot internets at gmail dot com Assigned: mysql
Status: Closed Package: MySQLi related
PHP Version: 5.3.2 OS: vistax64
Private report: No CVE-ID:
 [2010-04-19 21:27 UTC] bastard dot internets at gmail dot com
Description:
------------
Mysqli generated links appear to be persistent regardless of settings as long as the PHP process (or Apache server process if PHP is loaded as a module as in my case) is running.  Any new connections just add to the total link count, and neither closing or unsetting the link nor garbage collection has any effect on removing them.  Restarting mysqld has no effect.

I'm using Vista x64, Apache 2.2, PHP5.3.2 as a module (thread-safe download), and Mysql 5.1.45.

The below code produces no Mysql error, but after the second page reload, PHP generates a 'Too many open links (1)' error from that point on until the PHP server process is restarted.  Mysql shows no connection attempts on its end.  No further db links can be established because of mysqli.max_links being reached.  The only way to solve this that I've found so far is to set mysqli.max_links=-1 and just ignore the ever-growing number of zombie links.  Either that or restart the Apache server every few seconds.

Also of note, no matter how high max_links is set and the script is ran, get_connection_stats() will only show 1 active_connections, 0 active_persistent_connections, 0 connection_reused, 0 reconnect, 0 *_close.

Also, when using mysqli::real_connect method after mysqli_init(), it establishes 1 active_persistent_connections according to get_connection_stats() even though I have mysqli.allow_persistent=Off, where as mysqli::__construct does not.




Test script:
---------------
php.ini...
mysqli.max_links = 1
mysqli.allow_persistent = Off
mysqli.max_persistent = 0
mysqli.reconnect = Off


my.ini...
max_connections=1
max_user_connections=1
connect_timeout=10


// just hit browser refresh once or twice
<?php

$mysqli = mysqli_init();
$mysqli->options(MYSQLI_OPT_CONNECT_TIMEOUT, 5);
$mysqli->real_connect($m_host, $m_user, $m_pass, $m_db);
echo $mysqli->error."<br>";
var_dump($mysqli->get_connection_stats());
mysqli_close($mysqli);
die("finished");

?>

Expected result:
----------------
The above code should never generate a PHP error.  Link in PHP memory should actually be deleted either on close() or on script end.


If this behavior is intended for another purpose, in order to free up memory and available connection/link slots in PHP, can a function or setting be added or tweaked to actually delete the link from memory either on demand or after some user specified time limit, or automatically on script end?  Or is there another method of handling this already?  Should there be a mysql(i).connect_timeout setting in php.ini?  Is mysqli::real_connect disobeying mysqli.allow_persistent=Off?

Actual result:
--------------
[19-Apr-2010 12:56:58] PHP Warning:  mysqli::mysqli(): Too many open links (1) in D:\Server\Scripts\mysql_benchmarks.php on line 15

[19-Apr-2010 12:56:58] PHP Warning:  main(): Couldn't fetch mysqli in D:\Server\Scripts\mysql_benchmarks.php on line 16

[19-Apr-2010 12:56:58] PHP Warning:  mysqli::get_connection_stats(): Couldn't fetch mysqli in D:\Server\Scripts\mysql_benchmarks.php on line 17


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-04-19 21:45 UTC] bastard dot internets at gmail dot com
Correction on what software I'm using.  I'm using these packages...

mysql-noinstall-5.1.45-winx64.zip (via mysql.com)
php-5.3.2-Win32-VC6-x86.zip (via php.net)
httpd-2.2.15-win32-x86-openssl-0.9.8m-r2.msi (via apache.org)
 [2010-04-22 02:53 UTC] bastard dot internets at gmail dot com
Just to clarify - this is a closed server and db dev environment, and I'm the only one running the above script or connecting to the Mysql server.  The 'too many links' PHP error would be expected if multiple users were hitting the page at the exact same time.  But not expected if it's just me hitting refresh every once in a while.
 [2010-04-23 22:14 UTC] felipe@php.net
-Status: Open +Status: Feedback
 [2010-04-23 22:14 UTC] felipe@php.net
Please try using this snapshot:

  http://snaps.php.net/php5.3-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/


 [2010-04-23 22:14 UTC] felipe@php.net
-Assigned To: +Assigned To: mysql
 [2010-04-24 00:40 UTC] bastard dot internets at gmail dot com
-Status: Feedback +Status: Open
 [2010-04-24 00:40 UTC] bastard dot internets at gmail dot com
No Windows snapshots are currently available on http://windows.php.net/snapshots/ or  http://windows.php.net/downloads/snaps/.  Should I instead downgrade to PHP 5.2.13 release?
 [2010-04-24 04:40 UTC] bastard dot internets at gmail dot com
Found a temporary solution - actually use real persistent connections: append "p:" to the hostname on mysqli::__connect(), set "mysqli.allow_persistent = On", set "mysqli.max_persistent = 1", and use all default mysql connection timeout settings.  This correctly reuses the single active persistent link and established tcp socket connection for all page loads for as long as the connection timeout settings allow.  Either that or revert to using the regular mysql extension.

This doesn't take care of the growing number of active, permanent, non-persistent links spawned by any regular mysqli connection though.
 [2010-04-30 00:12 UTC] felipe@php.net
-Status: Open +Status: Assigned
 [2010-05-11 12:03 UTC] andrey@php.net
Automatic comment from SVN on behalf of andrey
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=299239
Log: Fix for bug #51605 (Mysqli zombie links)
 [2010-05-11 12:04 UTC] andrey@php.net
-Status: Assigned +Status: Closed
 [2010-05-11 12:04 UTC] andrey@php.net
Fix will appear in 5.3.3. Thanks for reporting this.
 [2010-05-13 13:05 UTC] andrey@php.net
Automatic comment from SVN on behalf of andrey
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=299335
Log: Better fix for #51605
 [2010-05-13 13:06 UTC] andrey@php.net
Automatic comment from SVN on behalf of andrey
Revision: http://svn.php.net/viewvc/?view=revision&amp;revision=299336
Log: Somehow missed to commit this, for better fix for #51605
 [2012-05-21 23:12 UTC] bastard dot internets at gmail dot com
Corrected issue for http://www.afateam.org/ with exceeding process issues.
 [2012-05-26 23:46 UTC] bastard dot internets at gmail dot com
Re the last comment "[2012-05-21 23:12 UTC] bastard dot internets at gmail dot com" - I did not make this comment.  Looks like the commenter mistakenly put in my email address when submitting.  Delete?
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sun Apr 20 15:01:54 2014 UTC