關於mysql持久串連(mysql_connect與mysql_pconnect)

來源:互聯網
上載者:User

在某些場合,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的持續串連,而不能使用其他進程開啟的持續串連”。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.