简体   繁体   中英

PHP Mysqli not closing TCP connections

I'm updating my scripts to move from ext/mysql to ext/mysqli. It's introduced some problems.

Under ext/mysqli, connections are not released when a script terminates.

The scripts are all run from the command line. There is no Apache or other HTTP involvement.

For business reasons, I sometimes need to have a large number of single DB interactions. They aren't concurrently active, each action (INSERT, UPDATE, SELECT, DELETE) is completed before the next is commenced. In come cases, I am able to build large single queries (eg UPDATE...SET...CASE...WHEN etc) and these aren't a problem as they use fewer connections, of course, but there are occasions where I cannot use this option.

I have a $mysqli->close() after each DB operation, but the (TCP) connections do not close. After the script has terminated, the connections remain open until they time out (as shown by “netstat -an”).

The practical implication for me is that I am running out of TCP connections.

These scripts perform perfectly with ext/mysql.

This has been previously reported as a bug ( http://bugs.mysql.com/bug.php?id=38107 ) but the solution was to upgrade to PHP 5.3. I'm using 5.3.8.

Example:

$mysqli = new mysqli(DB_SERVER, DB_SERVER_USERNAME,DB_SERVER_PASSWORD, DB_DATABASE)         or die ("Unable to connect: " . $mysqli->error());
$result = $mysqli->query($query) or die ("Query failed: " . $mysqli->error . " Actual query: " . $query);
// Do domething interesting with $result
$mysqli->close();
/** TCP connection remains open until it times out at an OS level /**

Has anyone experienced this problem and found a solution? Thanks.

NB: There are other questions on Stackoverflow which are similar, but not the same. Please don't close this as a duplicate.

UPDATE: I may be barking up the wrong tree. The reason I believe it is a connection issue is because I am getting this error: mysqli::mysqli(): [2002] Only one usage of each socket address (protocol/network address/port) is normally permitted. The explanation I found here ( http://www.online-it-support.co.uk/?p=652 ) suggests TCP port exhaustion is the cause. I can make changes to my development environment as it's within my control. The production environment isn't. I assumed - perhaps unwisely - that this was incorrect behavior. this was based on the fact that the problem does not occur with ext/mysql. Perhaps my question ought to be "how to I make ext/mysqli behave like ext/mysql?".

Connections in TIME_WAIT state are closed. There's no bug or issue. If you create and close large numbers of TCP connections in a small amount of time, you'll wind up with lots of TCP connections in TIME_WAIT state.

You either need to re-use your connections rather than closing them or figure out why this is causing you a problem and fix it. For example, increasing the range of local ports may help.

Building up and tearing down a TCP connection is expensive. If you're trying to do that dozens of times a second, you're doing something very wrong.

You should use the persistent connections in MySQLi

Prepending host by p: opens a persistent connection. mysqli_change_user() is automatically called on connections opened from the connection pool.

That should leave the connections open, in a usable state.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM