-------- mysql_connect ----------- 函數原型: resource mysql_connect ( [string server [, string username [, string password [, bool new_link [, int client_flags]]]]]) 返回: 如果成功則返回一(yī)個 MySQL 連接标識,失敗則返回 FALSE。 描述: mysql_connect() 建立一(yī)個到 MySQL 服務器的連接。當沒有提供可選參數時使用以下(xià)默認值:server = 'localhost:3306',username = 服務器進程所有者的用戶名,password = 空密碼。 如果用同樣的參數第二次調用 mysql_connect(),将不會建立新連接,而将返回已經打開(kāi)的連接标識。參數 new_link 改變此行爲并使 mysql_connect() 總是打開(kāi)新的連接,甚至當 mysql_connect() 曾在前面被用同樣的參數調用過。參數 client_flags 可以是以下(xià)常量的組合 :MYSQL_CLIENT_COMPRESS,MYSQL_CLIENT_IGNORE_SPACE 或者 MYSQL_CLIENT_INTERACTIVE。 注: new_link 參數自 PHP 4.2.0 起可用。 client_flags 參數自 PHP 4.3.0 起可用。 一(yī)旦腳本結束,到服務器的連接就會被關閉。除非之前已經調用了 mysql_close() 來關閉它。 ------- mysql_pconnect ------------- 函數原型: resource mysql_pconnect ( [string server [, string username [, string password [, int client_flags]]]]) 返回: 如果成功則返回一(yī)個正的 MySQL 持久連接标識符,出錯則返回 FALSE。 描述: mysql_pconnect() 建立一(yī)個到 MySQL 服務器的連接。如果沒有提供可選參數,則使用如下(xià)默認值:server = 'localhost:3306', username = 服務器進程所有者的用戶名,password = 空密碼。client_flags 參數可以是以下(xià)常量的組合:MYSQL_CLIENT_COMPRESS, MYSQL_CLIENT_IGNORE_SPACE 或者 MYSQL_CLIENT_INTERACTIVE。 server 參數也可以包括端口号,例如 "hostname:port",或者是本機套接字的的路徑,例如 ":/path/to/socket"。 注: 對 ":port" 的支持是 3.0B4 版添加的。 對 ":/path/to/socket" 的支持是 3.0.10 版添加的。 -------- 兩者之間的區别 -------------- mysql_pconnect() 和 mysql_connect() 非常相似,但有兩個主要區别。 首先,當連接的時候本函數将先嘗試尋找一(yī)個在同一(yī)個主機上用同樣的用戶名和密碼已經打開(kāi)的(持久)連接,如果找到,則返回此連接 标識而不打開(kāi)新連接。 其次,當腳本執行完畢後到 SQL 服務器的連接不會被關閉,此連接将保持打開(kāi)以備以後使用(mysql_close() 不會關閉由 mysql_pconnect() 建立的連接)。 可選參數 client_flags 自 PHP 4.3.0 版起可用。 此種連接稱爲"持久的"。 看到這裏,寫一(yī)條代碼來測試一(yī)下(xià) /* * pconnect_test.php */ $link = mysql_pconnect("localhost", "mysql_user", "mysql_password") or die("Could not connect: " . mysql_error()); print ("Connected successfully"); 通過刷新網頁的方式執行這條代碼,發現每執行一(yī)次,mysql的進程數就增加一(yī)個。在這裏我(wǒ)(wǒ)不禁有了疑問。上面說mysql_pconnect這個函 數的使用的時候,不是說"當連接的時候本函數将先嘗試尋找一(yī)個在同一(yī)個主機上用同樣的用戶名和密碼已經打開(kāi)的(持久)連接,如果找到 ,則返回此标識而不打開(kāi)新連接"麽?爲什麽我(wǒ)(wǒ)每刷新一(yī)次頁面他就給我(wǒ)(wǒ)打開(kāi)一(yī)個新的連接呢? 考慮到這有可能是PHP的bug,我(wǒ)(wǒ)到PHP的bug列表中(zhōng)找關于和too many connections 有關的條目。 相關的話(huà)題主要有三個,分(fēn)别是 #11966 mysql_pconnect opens new connections with the same parameters #26117 Persistent connection not reused #13589 Persistent connections stay open and accumulate 描述比較長,我(wǒ)(wǒ)就不在這裏貼,具體(tǐ)的内容你自己去(qù)看。重點主要是"當一(yī)個進程打開(kāi)一(yī)個mysql的持續連接,隻要該進程還存在,這個持續 的連接就不會斷開(kāi),而且每一(yī)個進程會打開(kāi)一(yī)個mysql的持續連接,而不能使用其他進程打開(kāi)的持續連接"。 到這裏,我(wǒ)(wǒ)把相關的信息發給上海的朋友張宏,他提示我(wǒ)(wǒ)把apache的子進程數限制到不高于mysql的最大(dà)連接數。我(wǒ)(wǒ)問了我(wǒ)(wǒ)們的系統管理員(yuán) ,他說我(wǒ)(wǒ)們的服務器上apache的最大(dà)子進程數是256,而mysql的最大(dà)連接數限制爲600。就是說mysql的最大(dà)連接數已經遠遠超過httpd的進程數 ,爲什麽還會出現Too many connections 這樣的錯誤呢?答案就在于PHP程序。打開(kāi)以前同事寫的程序,發現同一(yī)個運行腳步中(zhōng)過多的調用 mysql_pconnect函數。如果在應用服務器上,每一(yī)個httpd子進程使用一(yī)個php腳本,每一(yī)個php腳本打開(kāi)不止一(yī)個mysql的連接。因爲httpd所産 生(shēng)的子進程的生(shēng)存期是apache服務器指定的,一(yī)般服務器不重啓,這些進程就一(yī)直存在。就算服務器重啓,也可以指定保存這些進程。由于進 程的存在,那麽這些連接都不會斷掉,并且每個進程打開(kāi)幾個連接數,那麽統計起來,連接數就達到了mysql限制的最大(dà)連接數。這時就出現 Too many connections 錯誤。 小(xiǎo)結一(yī)下(xià),要保證你的系統不會出現Too many connections 錯誤,需要注意兩點: 1.保證你的apache的最大(dà)進程數不超過mysql的最大(dà)連接數; 2.不要在程序裏面用過多mysql_pconnect連接到同一(yī)個數據庫服務器(一(yī)個就夠了).這需要好的編碼習慣和規範.特别是不斷的給系統增加
|