2012-10-11 215 views
0

我在24/7 PHP shell腳本中遇到MySQL超時問題。php mysql斷開連接是否真的斷開連接?

我的印象是,梨DB DB :: connect()會創建新的句柄,但似乎並非如此。即使在循環中使用五次,DB :: connect()實際上也會返回「服務器已經消失」的錯誤。

我現在在DB :: connect()之前向腳本添加了db-> disconnect()和unset($ db)。這會導致底層mysql模塊在連接(localhost)之前釋放資源嗎?如果沒有,那麼我不會看到除使用專有new_link之外的其他選項。

+0

爲什麼你連接到一個數據庫五次?你有五個不同的數據庫嗎? (爲什麼不在循環之前打開一次連接,然後使用該連接直到完成) –

+0

@TerrySeidler它只是試圖在循環中連接五次,直到放棄爲止。連接總是返回錯誤「已消失」。 – anttir

+0

oooh ...我明白了。現在更有意義:} –

回答

0

嗯。尚無定論。

我做了示例php腳本連接兩次相同的設置,運行mysql_close(),然後第三個連接。 我也在另一個窗口中運行tcpdump。

在前幾次運行中,在後續連接上有一些流量通過服務器。然後這個流量消失了。

現在結果是,如果沒有mysql_close(),mysql_connect()確實使用以前的連接,並且後續的mysql_connect()上的流量爲零。

運行mysql_close()時,轉儲將指示TCP連接已關閉。

第三次連接時,連接從頭開始重新建立。

13:37:57.842598 IP 192.168.1.1.58772 > 192.168.2.2.mysql: S 3281731243:3281731243(0) win 5840 <mss 1460,sackOK,timestamp 503312235 0,nop,wscale 7> 
13:37:57.887534 IP 192.168.2.2.mysql > 192.168.1.1.58772: S 1293434507:1293434507(0) ack 3281731244 win 5792 <mss 1460,sackOK,timestamp 3402066848 503312235,nop,wscale 7> 
13:37:57.887639 IP 192.168.1.1.58772 > 192.168.2.2.mysql: . ack 1 win 46 <nop,nop,timestamp 503312245 3402066848> 
13:37:57.932750 IP 192.168.2.2.mysql > 192.168.1.1.58772: P 1:61(60) ack 1 win 46 <nop,nop,timestamp 3402066859 503312245> 
13:37:57.932843 IP 192.168.1.1.58772 > 192.168.2.2.mysql: . ack 61 win 46 <nop,nop,timestamp 503312256 3402066859> 
13:37:57.935983 IP 192.168.1.1.58772 > 192.168.2.2.mysql: P 1:62(61) ack 61 win 46 <nop,nop,timestamp 503312258 3402066859> 
13:37:57.981130 IP 192.168.2.2.mysql > 192.168.1.1.58772: . ack 62 win 46 <nop,nop,timestamp 3402066871 503312258> 
13:37:57.981181 IP 192.168.2.2.mysql > 192.168.1.1.58772: P 61:72(11) ack 62 win 46 <nop,nop,timestamp 3402066871 503312258> 
13:37:58.017172 IP 192.168.1.1.58772 > 192.168.2.2.mysql: . ack 72 win 46 <nop,nop,timestamp 503312279 3402066871> 

at 13:38:01 there was the second mysql connection 

at 13:38:04 now the mysql_close():  
13:38:03.989796 IP 192.168.1.1.58772 > 192.168.2.2.mysql: P 62:67(5) ack 72 win 46 <nop,nop,timestamp 503313772 3402066871> 
13:38:03.989844 IP 192.168.1.1.58772 > 192.168.2.2.mysql: F 67:67(0) ack 72 win 46 <nop,nop,timestamp 503313772 3402066871> 
13:38:04.034818 IP 192.168.2.2.mysql > 192.168.1.1.58772: F 72:72(0) ack 68 win 46 <nop,nop,timestamp 3402068385 503313772> 
13:38:04.034920 IP 192.168.1.1.58772 > 192.168.2.2.mysql: . ack 73 win 46 <nop,nop,timestamp 503313783 3402068385> 

at 13:38:07 the third connection after mysql_close(). Afterwards script exits and mysql connection is closed. 
13:38:06.995120 IP 192.168.1.1.58773 > 192.168.2.2.mysql: S 3287179963:3287179963(0) win 5840 <mss 1460,sackOK,timestamp 503314523 0,nop,wscale 7> 
13:38:07.035065 IP 192.168.2.2.mysql > 192.168.1.1.58773: S 1439831970:1439831970(0) ack 3287179964 win 5792 <mss 1460,sackOK,timestamp 3402069136 503314523,nop,wscale 7> 
13:38:07.035166 IP 192.168.1.1.58773 > 192.168.2.2.mysql: . ack 1 win 46 <nop,nop,timestamp 503314533 3402069136> 
13:38:07.075107 IP 192.168.2.2.mysql > 192.168.1.1.58773: P 1:61(60) ack 1 win 46 <nop,nop,timestamp 3402069146 503314533> 
13:38:07.075188 IP 192.168.1.1.58773 > 192.168.2.2.mysql: . ack 61 win 46 <nop,nop,timestamp 503314543 3402069146> 
13:38:07.075437 IP 192.168.1.1.58773 > 192.168.2.2.mysql: P 1:62(61) ack 61 win 46 <nop,nop,timestamp 503314543 3402069146> 
13:38:07.115123 IP 192.168.2.2.mysql > 192.168.1.1.58773: . ack 62 win 46 <nop,nop,timestamp 3402069156 503314543> 
13:38:07.115178 IP 192.168.2.2.mysql > 192.168.1.1.58773: P 61:72(11) ack 62 win 46 <nop,nop,timestamp 3402069156 503314543> 
13:38:07.115821 IP 192.168.1.1.58773 > 192.168.2.2.mysql: P 62:67(5) ack 72 win 46 <nop,nop,timestamp 503314553 3402069156> 
13:38:07.115844 IP 192.168.1.1.58773 > 192.168.2.2.mysql: F 67:67(0) ack 72 win 46 <nop,nop,timestamp 503314553 3402069156> 
13:38:07.155524 IP 192.168.2.2.mysql > 192.168.1.1.58773: F 72:72(0) ack 68 win 46 <nop,nop,timestamp 3402069166 503314553> 
13:38:07.155606 IP 192.168.1.1.58773 > 192.168.2.2.mysql: . ack 73 win 46 <nop,nop,timestamp 503314563 3402069166> 

和腳本:

<?php 

output("starting"); 
$start = microtime(true); 
$res = mysql_connect('192.168.2.2','user','pass'); 
if($res === FALSE) 
     die(output("SQL error on connect\n")); 
output(sprintf("Connect took: %.3f", (microtime(true)-$start))); 

output("sleep 3"); 
sleep(3); 

$start = microtime(true); 
$res = mysql_connect('192.168.2.2','user','pass'); 
if($res === FALSE) 
     die(output("SQL error on connect\n")); 
output(sprintf("Connect took: %.3f", (microtime(true)-$start))); 

output("sleep 3"); 
sleep(3); 

output("closing"); 
mysql_close($res); 

output("sleep 3"); 
sleep(3); 

$start = microtime(true); 
$res = mysql_connect('192.168.2.2','user','pass'); 
if($res === FALSE) 
     die(output("SQL error on connect\n")); 
output(sprintf("Connect took: %.3f", (microtime(true)-$start))); 

output("all done"); 
exit; 

function output($str) 
{ 
     echo date('Y-m-d H:i:s')." ".$str."\n"; 
} 
0

manual

許多Web應用程序將受益於製作持久連接 到數據庫服務器。持久連接在腳本末尾 處未關閉,但在另一個腳本使用相同憑據請求連接時被緩存並重新使用。每當腳本需要與數據庫交談時,持久連接 緩存允許您避免建立新連接的開銷,從而在更快的Web應用程序中產生 。

這被稱爲連接池。連接使用連接池進行。即使你創建了一個新的連接,它也被從游泳池中取出並提供給你。

不是關閉連接,因爲它會降低性能,並沒有給你帶來任何好處。