2013-02-25 104 views
1

我正在更新腳本以從ext/mysql移至ext/mysqli。它引入了一些問題。PHP Mysqli不關閉TCP連接

在ext/mysqli下,腳本終止時不會釋放連接。

腳本都是從命令行運行的。沒有Apache或其他HTTP參與。

由於商業原因,我有時需要大量的單個數據庫交互。它們不同時處於活動狀態,每個操作(INSERT,UPDATE,SELECT,DELETE)在下一個開始之前完成。 在來的情況下,我能夠建立大型單個查詢(例如更新... SET ... CASE ...當等),這些都不是一個問題,因爲他們使用更少的連接,當然,但有些場合我無法使用此選項。

我在每個數據庫操作後有一個$mysqli->close(),但(TCP)連接沒有關閉。腳本終止後,連接保持打開狀態直至超時(如「netstat -an」所示)。

對我來說,實際的含義是我的TCP連接不夠用。

這些腳本與ext/mysql完美搭配。

這已經被報告爲bug(http://bugs.mysql.com/bug.php?id=38107),但解決方案是升級到PHP 5.3。我正在使用5.3.8。

例子:

$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 /** 

有沒有人遇到過這個問題,並找到了解決辦法?謝謝。

注意:在Stackoverflow上還有其他類似的問題,但不一樣。請不要將其作爲副本關閉。

更新:我可能會吠叫錯誤的樹。我認爲這是一個連接問題的原因是因爲我得到這個錯誤: mysqli::mysqli(): [2002] Only one usage of each socket address (protocol/network address/port) is normally permitted. 我在這裏找到的解釋(http://www.online-it-support.co.uk/?p=652)表明TCP端口耗盡是原因。 我可以對我的開發環境進行更改,因爲它在我的控制範圍內。生產環境不是。 我假設 - 也許不明智 - 這是不正確的行爲。這是基於ext/mysql不會發生問題的事實。 也許我的問題應該是「如何讓ext/mysqli的行爲像ext/mysql?」。

+0

對不起,試圖格式示例作爲代碼,但我失敗了。 – 2013-02-25 14:47:36

+0

從技術上講,每次操作後都不應關閉連接。除非你有不同證書的多個連接到不同的dbs /服務器,否則數據庫連接CAN應該被重新使用。 - > close()應該只在你知道你完成數據庫操作時才被調用。 – 2013-02-25 14:50:57

+0

這不會讓事情變得更糟嗎?或者至少沒有更好的。 – 2013-02-25 14:52:49

回答

4

連接TIME_WAIT狀態已關閉。沒有錯誤或問題。如果您在很短的時間內創建並關閉大量的TCP連接,您將以TIME_WAIT狀態結束大量TCP連接。

您或者需要重新使用您的連接而不是關閉它們,或者找出爲什麼這會導致您遇到問題並修復它。例如,增加本地端口的範圍可能會有所幫助。

構建和拆除TCP連接非常昂貴。如果你每秒想做幾十次,那麼你做錯了一件事。

+0

謝謝。請你詳細說明「重新使用你的連接」嗎? – 2013-02-25 15:08:59

+0

@SimonRoberts:不要關閉連接,因爲這會迫使你打開一個新連接。相反,請保持連接處於打開狀態,直到腳本完成,這樣才能重用。建立和拆除每個請求的TCP連接是不明智的。 *每次手術後您都會關閉。你在問題中這樣說。這就是爲什麼你有這麼多的關閉連接。 – 2013-02-25 15:10:12

+0

謝謝。我已根據您的建議進行了重新撰寫,問題已經停止。所以這是造成問題的糟糕的腳本。我想這個ext/mysql一定是更加虛擬的寬容。我可以明白爲什麼我的邏輯把我帶到了哪裏,但是你發現了你的診斷和解決方案。 – 2013-02-26 09:18:53

0

您應該使用持久連接在MySQLi

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

這應該離開連接打開,處於可用狀態。