简体   繁体   English

PHP Mysqli没有关闭TCP连接

[英]PHP Mysqli not closing TCP connections

I'm updating my scripts to move from ext/mysql to ext/mysqli. 我正在更新我的脚本以从ext / mysql移动到ext / mysqli。 It's introduced some problems. 它引入了一些问题。

Under ext/mysqli, connections are not released when a script terminates. 在ext / mysqli下,脚本终止时不会释放连接。

The scripts are all run from the command line. 这些脚本都是从命令行运行的。 There is no Apache or other HTTP involvement. 没有Apache或其他HTTP参与。

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. 它们不是同时活动的,每个动作(INSERT,UPDATE,SELECT,DELETE)在下一个动作开始之前完成。 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. 在这种情况下,我能够构建大型单个查询(例如UPDATE ... SET ... CASE ... WHEN等),这些不是问题,因为它们使用较少的连接,当然,但有时候我不能使用这个选项。

I have a $mysqli->close() after each DB operation, but the (TCP) connections do not close. 我在每个数据库操作后都有一个$mysqli->close() ,但是(TCP)连接没有关闭。 After the script has terminated, the connections remain open until they time out (as shown by “netstat -an”). 脚本终止后,连接将保持打开状态,直到超时(如“netstat -an”所示)。

The practical implication for me is that I am running out of TCP connections. 对我来说,实际意义是我的TCP连接已经用完了。

These scripts perform perfectly with ext/mysql. 这些脚本与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. 这已经被报道为一个错误( http://bugs.mysql.com/bug.php?id=38107 ),但解决方案是升级到PHP 5.3。 I'm using 5.3.8. 我正在使用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. 注意:Stackoverflow上还有其他类似的问题,但不一样。 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. 我认为它是连接问题的原因是因为我收到此错误: 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. 我在这里找到的解释( http://www.online-it-support.co.uk/?p=652 )表明TCP端口耗尽是原因。 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. 这是基于ext / mysql不会出现问题的事实。 Perhaps my question ought to be "how to I make ext/mysqli behave like ext/mysql?". 也许我的问题应该是“如何使ext / mysqli像ext / mysql一样运行?”。

Connections in TIME_WAIT state are closed. 处于TIME_WAIT状态的连接关闭。 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. 如果您在很短的时间内创建并关闭大量TCP连接,那么您将在TIME_WAIT状态下获得大量TCP连接。

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. 建立和拆除TCP连接是昂贵的。 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 您应该在MySQLi中使用持久连接

Prepending host by p: opens a persistent connection. 通过p:预先添加主机打开持久连接。 mysqli_change_user() is automatically called on connections opened from the connection pool. 在从连接池打开的连接上自动调用mysqli_change_user()。

That should leave the connections open, in a usable state. 这应该使连接处于打开状态,处于可用状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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