在php中每一個new的PDO對象,都會去連接mysql,都會創建一條tcp連接.當pdo對象賦予的變量是一個的時候,那么他只會保持一個tcp連接,沒有被引用的對象連接會直接斷掉.如果不對這個對象進行任何操作,不傳輸任何數據,這條連接會在10秒后被mysql服務斷掉.
如果使用了長連接參數,那么不管循環執行幾次new PDO,只會有一個tcp連接
關於超時現象,網上的資料大部分說受兩個參數interactive_timeout和wait_timeout影響,但是經過我測試,修改了這兩個參數,如果10秒沒有任何操作,連接仍然會被mysql斷掉,不管是使不使用長連接參數.
如果每隔一秒傳輸數據,那么這條連接就會一直存在,狀態一直是ESTABLISHED.如果是會出現兩次執行時間較長,連接會被mysql斷掉
對於需要長期執行的數據庫操作腳本,比較穩妥的方式是每隔8秒左右重新new PDO對象,或者每隔循環一定次數確保在10秒內重新new PDO對象
測試過程如下:
開一個終端,不停的查看當前的連接情況
while true;do clear;date;netstat -altupn|grep 3306;sleep 1;done
另一個終端執行php腳本,可以暫時把長連接參數去掉,可以看到有很多tcp連接,狀態是time_wait,是客戶端主動關閉的.
而被mysql斷掉的連接是close_wait狀態,也就是被關閉一方,mysql服務里的連接是FIN_WAIT2
<?php //$option=array(PDO::ATTR_PERSISTENT => true); for($i=0;$i<10;$i++){ $pdo=new PDO("mysql:host=127.0.0.1;dbname=my_test","root","xxx",$option); var_dump($pdo); } while(1){ sleep(5); $pdo->query("set names utf8"); sleep(11); }