max_user_connections 是 MySQL 用戶鏈接數的最大值設置,整段語句的意思是:服務器的 MySQL 的最大鏈接數參數設置不足。解決方法:修改 MySQL 安裝目錄下 my.ini 或者 my.cnf 文件內的 max_user_connections 參數的數值,重啓 MySQL 服務器。
可是正常來講,MySQL默認的100個鏈接數是 足夠的。咱們須要從程序上去考慮。MySQL的默認最大鏈接數爲100(N),實際給普通用戶使用只有N-1個,保留一個鏈接是留給超級管理員使用的,防 止鏈接佔滿了不會把管理員也踢出來。不少網站在運行的時候都會出現鏈接數受限現象,我認爲十之八九並不是是網站的真實訪問量太大致使鏈接數超標,更可能是由於 咱們在設計網站程序的時候採用了不合理的設計架構或數據結構引發的。非正常鏈接超限可能緣由以下(天緣即時概括未必完整或無錯訛僅供參考):
相似人數、在線時間、瀏覽數等統計功能與主程序數據庫同屬一個數據空間時就很容易出現。
複雜的動態頁尤爲是用戶每次瀏覽都涉及到多數據庫或多表操做時候也很容易出現。
還有就是程序設計的不合理(好比複雜運算、等待等操做放置在數據庫交互行爲中間進行),或者程序存在釋放BUG。
計算機硬件配置過低卻安裝過高版、過高配置的MySQL。
未採用緩存技術。
數據庫未通過優化或表格設計及其複雜。
等 等一些緣由,都會延長數據庫的數據交互時間或增長交互次數。因此,若是你們遇到這類問題,首先要考慮程序是否存在BUG致使鏈接釋放失敗,再次就是考慮優 化軟硬件。固然修改MySQL鏈接數也是軟件優化的操做方法之一,但願你們都可以本着學習的態度經過研究一下自身的緣由從而解決這一問題。若是實在是找不 到緣由,那就只好先修改鏈接數,暫緩定位真實緣由了。
關於PHP的數據庫持久鏈接 mysql_pconnect
PHP程序 員應該都知道鏈接MySQL數據庫可使用mysql_pconnect(永久鏈接)函數,使用數據庫永久鏈接能夠提升效率,可是實際應用中數據庫永久連 接每每會致使出現一些問題,一般的表現就是在大訪問量的網站上時常發生斷斷續續的沒法鏈接數據庫的狀況,出現相似"Too many connections in ..."的錯誤提示信息,從新啓動服務器又正常了,但過不了一下子又出現一樣的故障。對於這些問題的成因,恐怕就不是每一個人都能說清楚的了,雖然PHP文 檔裏有一些相關資料,可是解釋的並不淺顯易懂,這裏我厚着臉皮試圖作一個簡單的討論,所述觀點不見得全都正確,歡迎你們反饋意見。
首先 看看數據庫永久鏈接的定義:永久的數據庫鏈接是指在腳本結束運行時不關閉的鏈接。當收到一個永久鏈接的請求時。PHP 將檢查是否已經存在一個(前面已經開啓的)相同的永久鏈接。若是存在,將直接使用這個鏈接;若是不存在,則創建一個新的鏈接。所謂"相同"的鏈接是指用相 同的用戶名和密碼到相同主機的鏈接。
PHP使用永久鏈接方式操做MySQL是有前提的:就是PHP必須安裝爲多線程或多進程Web服務 器的插件或模塊。最多見的形式是把PHP用做多進程Apache服務器的一個模塊。對於一個多進程的服務器,其典型特徵是有一個父進程和一組子進程協調運 行,其中實際生成Web頁面的是子進程。每當客戶端向父進程提出請求時,該請求會被傳遞給尚未被其它的客戶端請求佔用的子進程。這也就是說當相同的客戶 端第二次向服務端提出請求時,它將有可能被一個不一樣的子進程來處理。在開啓了一個永久鏈接後,全部不一樣子進程請求SQL服務的後繼頁面都可以從新使用這個 已經創建的 SQL服務器鏈接。它使得每一個子進程在其生命週期中只作一次鏈接操做,而非每次在處理一個頁面時都要向 SQL 服務器提出鏈接請求。每一個子進程將對服務器創建各自獨立的永久鏈接。PHP自己並無數據庫鏈接池的概念,可是Apache有進程池的概念, 一個Apache子進程結束後會被放回進程池, 這也就使得用mysql_pconnect打開的的那個mysql鏈接資源能夠不被釋放,而是依附在相應的Apache子進程上保存到了進程池中。因而在 下一個鏈接請求時它就能夠被複用。一切看起來彷佛都很正常,可是在Apache併發訪問量大的時候,若是使用mysql_pconnect,會因爲以前的 Apache子進程佔用的MySQL鏈接沒有close, 很快使MySQL達到最大鏈接數,使得以後的請求可能得不到響應。
上面的部分文字是摘抄自PHP文檔,看起來可能仍是有些文縐縐的很差理解,那麼我就用大白話再舉一個例子來講明問題:
假 設Apache配置最大鏈接數爲1000,MySQL配置最大鏈接數爲100,當Apache服務器接到200個併發訪問的時候,其中100個涉及到數據 庫訪問,剩下的100個不涉及數據庫訪問,由於這個時候還不存在可用的數據庫鏈接,因此這裏面涉及到數據庫訪問的100個併發會同時產生100個數據庫永 久鏈接,達到了數據庫最大鏈接數,當這些操做沒有結束的時候,任何其餘的鏈接都沒法再得到數據庫鏈接,當這些操做結束了,相應的鏈接會被放入進程池,此時 Apache的進程池裏就有了200個空閒的子進程,其中100個是帶有數據庫鏈接的,因爲Apache會爲訪問請求隨機的挑選空閒子進程,因此你獲得的 子進程極可能是不包含數據庫鏈接的那100箇中的一個,而數據庫鏈接已經達到了最大值,你也不可能成功的創建新的數據庫鏈接,唉,你便只好不停的刷新頁 面,哪一個時候運氣好,碰巧分配到了帶有數據庫鏈接的子進程,才能正常瀏覽頁面。若是是大訪問量的網站來講,任什麼時候候均可能存在大量的併發,因此瀏覽者可能 就會不停的發現沒法鏈接數據庫的現象了。
或許你會說,咱們把Apache和MySQL的最大鏈接數調成同樣大不就能夠了麼?是的,合理 的調整這個最大鏈接數某種程度上會避免這個問題的發生,可是Apache和MySQL的負載能力是不一樣的,若是按照Apache的負載能力來設置,對於 MySQL來講,這個最大鏈接數就偏大,會產生大量的MySQL數據庫永久鏈接,打個比方,就好像和平時代還要養活一個幾百萬的軍隊同樣,其開銷得不償 失;而若是按照Mysql的負載能力設置,對於Apache來講,這個最大鏈接數就偏小,有點殺雞牛刀的感受,沒法發揮Apache的最大效率。
所 以按照PHP手冊上的介紹,只適合在併發訪問不大的網站上使用數據庫永久鏈接,但對於一個併發訪問不大的網站來講,使用數據庫永久鏈接帶來的效率提升彷佛 沒有太大的意義,從這個角度上來看,我以爲PHP中的數據庫永久鏈接基本上是一個雞肋的角色,若是你必定要使用數據庫鏈接池的概念,能夠嘗試一下 sqlrelay或者Apache自己提供的mod_dbd,說不定會有驚喜。
關於mysql_free_result和mysql_close
以前用mysql的時候一直是在用短連接,調用mysql_store_result獲取一次數據以後就直接調用: mysql
可是有兩個問題:
當使用長鏈接時(即connect以後一直不close),若是最後會調用mysql_close,需不須要每次都調用mysql_free_result呢?
當mysql_close調用以後,m_result的數據是否還能夠用。
先說一下結論:
必須每次調用。由於通過測試,每次mysql_store_result的指針都是不一樣的,可見並非共享了同一塊buf。
仍是可使用。通過valgrind掃描,只調用mysql_close的掃描結果是: sql
之後再慢慢研究。。數據庫