關於MYSQL持久連接

在某些場合,mysql_pconnect( ) 是不適用的。

——————————————————————————–

狀況一:

 使用 1 部 web server 與 1 部 MySQL server(兩者可能同在一部主機上),而 web server 固定只對 MySQL server 上的某一個數據庫進行存取動作。

 因爲每次存取數據庫時,都是由 web 那邊使用同一賬號對 MySQL 上的同一數據庫作業,若我們將 MySQL 與 web server 的「同時聯機數」都調整爲 200,就好像 MySQL 這邊一直有 200 位「服務生」,隨時等着接待來自 web 的 200 位「顧客」似的。而且「顧客」離開之後,「服務生」也不下場休息,時時都站在門口等着接待下一個「顧客」。

 在這種情況下,您只要注意將 MySQL 的「同時聯機數」調得比 web server 的高或相等,就會發現使用 mysql_pconnect( ) 是個不錯的選擇。
——————————————————————————–

狀況二:

 使用 1 部 web server 與 1 部 MySQL server(兩者可能同在一部主機上),而 web server 會對 MySQL server 上的兩個數據庫進行存取動作。

 從 web server 那邊提出數據存取需求時,有時是針對第 1 個數據庫(DB1),有時則是針對第 2 個數據庫(DB2)。若我們也將 MySQL 與 web server 的「同時聯機數」都調整爲 200,這樣一來,就好像 MySQL 這邊有 200 位「服務生」,但同時經營兩個「吧檯」(DB1 與 DB2),而「顧客」可能多達 200 位。

 一開始,DB1 這個「吧檯」比較熱門,MySQL 派了 150 位「服務生」上場接待;同樣地,當「顧客」離開之後,這 150 位「服務生」仍守着 DB1 而不下場休息。後來,DB2 那邊也熱鬧起來了,「顧客」越來越多,MySQL 得加派「服務生」上場,有幾個能派?答案是 50 個!

 爲什麼「服務生」的人力調配會捉襟見肘?那是因爲 web 那邊使用了 mysql_pconnect( ) 來建立聯機。「服務生」一開始被指定到哪個「吧檯」工作,就會持續在那邊停留,絕不「轉檯」。
——————————————————————————–

 請注意,當使用持續性的聯機時,每個已建立的聯機只爲來自同一部 web server、使用同一組賬號,且存取同一數據庫的使用者服務。

 如此一來,假設每部 web server 的「同時聯機數」都是 200,而且同時使用 2 部 web server 會怎麼樣呢?從 web1 來了 50 個「顧客」,先是到 DB1 走一趟,接着再到 DB2 晃一圈,這樣需要多少「服務生」接待他們?100 個(web1->DB1: 50 web1->DB2: 50)!又從 web2 來了 50 個「顧客」,也做了同樣的動作(web2->DB1: 50 web2->DB2: 50)。在此之後,還有「服務生」是閒着的嗎?後續若從 web1 或 web2 同時湧入多於 50 位「顧客」時,誰來應付他們?

 倘若您使用的是像 Apache 這類的 multi-process web server(一個 parent process 協調一組 children processes 運作),某個 children process 建立的「持續聯機」,是不能分享給其它 children process 來使用的(「服務生」只對先前接待過的「顧客」服務)。在這樣的情況下,將會使得 MySQL 上閒置的 process 越積越多(很多「服務生」站在門口等着「老顧客」上門,而不理會「新顧客」)。
 mysql_pconnect( ) 一定是最佳選擇嗎?我想未必盡然。
——– 兩者之間的區別 ————–
mysql_pconnect() 和 mysql_connect() 非常相似,但有兩個主要區別。
首先,當連接的時候本函數將先嚐試尋找一個在同一個主機上用同樣的用戶名和密碼已經打開的(持久)連接,如果找到,則返回此連接

標識而不打開新連接。
其次,當腳本執行完畢後到 SQL 服務器的連接不會被關閉,此連接將保持打開以備以後使用(mysql_close() 不會關閉由

mysql_pconnect() 建立的連接)。
可選參數 client_flags 自 PHP 4.3.0 版起可用。
此種連接稱爲”持久的”。
看到這裏,寫一條代碼來測試一下

/*
* pconnect_test.php
*/

$link = mysql_pconnect("localhost", "mysql_user", "mysql_password")
        
or die("Could not connect: " . mysql_error());
    
print ("Connected successfully");

通過刷新網頁的方式執行這條代碼,發現每執行一次,mysql的進程數就增加一個。在這裏我不禁有了疑問。上面說mysql_pconnect這個函

數的使用的時候,不是說”當連接的時候本函數將先嚐試尋找一個在同一個主機上用同樣的用戶名和密碼已經打開的(持久)連接,如果找到

,則返回此標識而不打開新連接”麼?爲什麼我每刷新一次頁面他就給我打開一個新的連接呢?

考慮到這有可能是PHP的bug,我到PHP的bug列表中找關於和too many connections 有關的條目。
相關的話題主要有三個,分別是

#11966        mysql_pconnect opens new connections with the same parameters
#26117        Persistent connection not reused
#13589        Persistent connections stay open and accumulate

描述比較長,我就不在這裏貼,具體的內容你自己去看。重點主要是”當一個進程打開一個mysql的持續連接,只要該進程還存在,這個持續

的連接就不會斷開,而且每一個進程會打開一個mysql的持續連接,而不能使用其他進程打開的持續連接”。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章