AP遠端連接MySQL Connection暴增最後造成ERROR 1040 (HY000): Too many connections

PHP連接遠端mysql server最終造成ERROR 1040 (HY000): Too many connections

最近遇到一個很詭異的問題,原本的PHP系統要擴增AP Server並把MySQL移到一台獨立的Server上運作,原本認為這個task幾乎是沒有風險的,沒想到一接上線,大量的Client端的請求不僅無法消化,MySQL這邊的Connection數目竟然會很快地暴增,進而讓MySQL不斷吐Too many connections的錯誤的訊息。

但是如果去google “ERROR 1040 (HY000): Too many connections” 的話,許多文章會要你修改max_connections的數目或connection expire(逾期)的時間(例如這篇,下面的指令內容也都引用自此篇文章)。

  • 提高max_connection的數值
    • 查詢現在的max connections設定,以在任何可以query的地方執行下面的指令
      • select VARIABLE_VALUE from information_schema.GLOBAL_VARIABLES where VARIABLE_NAME=’MAX_CONNECTIONS’;
    • 查詢現在已經使用的connections數目
      • select count(*) from information_schema.PROCESSLIST;
    • 服務執行中動態更改max connections,可以在任何可以query的地方執行下面的指令 (下面的xxxx是數字,即允許的最大的connection數目),不過這種設定方式,mysql服務重啟就會失效。
      • set global max_connections = xxxx;
    • 透過修改設定檔增加max_connections (my.cnf 或是 my.ini),在 [mysqld] 的下面修改 max_connections的數值 (如果沒有的話要自己加進去,預設值是100),修改後需要重啟mysql服務才會生效
  • 修改connection的逾期時間(expire time),讓connection不會佔用過久的時間 interactive_timeout (單位是秒),下面這個是動態修改的方法。靜態修改也是直接在mysqld裡面加入或修改interactive_timeout的參數就可以了。
    • set global interactive_timeout = 3600;

不過在這個case裡面去修改max_connections的參數是沒有用的,因為connection增加的速度太快,最終會灌爆MySQL的 max_connection (我曾有把max_connections改到九十萬,不過connection炸到3萬左右正個系統就癱瘓了)。

因為原本的系統不會有這樣的問題,所以開始換OS、Switch Hub怪罪所有修改過的東西,後來trial and error卻發現,如果AP改用SSH Tunnel來連MySQL就不會有相同的問題,這十分怪異。後來百思不得其解的時候突然在某篇討論串中有人提到可能的原因之一是MySQL試著去反解AP的主機名稱,而DNS又沒有設定AP Server的反解的record才會出現這個問題。所以,解決的方法如下:

  1. 去DNS把每台要連的主機名稱設反解
  2. 設定MySQL Server的/etc/hosts (各系統hosts放置位置請參考這一篇),把要連的AP主機的主機名稱與IP設定上去。 (例如:下面這樣)

      192.168.100.101     ap-server1
      192.168.100.102     ap-server2

      127.0.0.1 localhost mysql-serv
      ….

  3. 修改MySQL的設定檔my.cnf (在windows上是my.ini),在[mysqld]下面多加一行 skip-name-resolve 讓mysql不要在去反解主機名稱

修改了主機名稱反解的問題後,connections就不再暴增了,提供上面幾個解決方法,請參考嚕,希望有幫助。

4 Replies to “AP遠端連接MySQL Connection暴增最後造成ERROR 1040 (HY000): Too many connections”

  1. 你好 我的主機好像也遇到類似你說的問題
    我ㄧ開始也是使用ubuntu 架設 而我則是web跟mysql在同一台
    一開始我也沒有設置skip-name-resolve,且/etc/host也沒有更動

    我的狀況則是,平常都沒有問題,但是只要人依開始多起來,或者突然暴衝人數,mysql的連接數就會暴衝,接著mysql就癱瘓了

    想請問一下,我這種狀況,也是因為mysql嘗試想要反解主機造成的嗎?

    我後來一直以為是ubuntu不穩,接著我換了CentOS,但是狀況還是一樣的發生

    我剛剛看了你的文章,我去檢查了my.cnf的設定,設定裏面skip-name-resolve也確實有打上去

    此時我還需要更改/etc/host裡面的東西嗎?

    我有看到你加入127.0.0.1 localhost mysql-serv
    這行,請問這行是必要要打的嗎?

    另外想請問一下,假設我apahce的max user設置1000
    但是mysql的max connection設置才500

    那這樣是不是也會有問題?
    我的網站人數很多,尤其是晚上,說實在的apache的1000人設定完全不夠,

    是因為我最近mysql會異常的爆量(connection直接噴上去)然後mysql就掛掉了,我以為是人數太多,才把apache提低試試看

    但是我又想到,mysql的max connection 低於apache的人數好像也怪怪的,目前我已經把mysql調1W 然後apache 先維持在1000
    先試試看

    想問你說,你知道我的問題可能出在哪邊嗎?

    可以的話幫我解答一下>”< 我努力找了一個月都沒什麼顯著的改善

    我的連絡mail 是 missyou_z@msn.com 我姓羅~

    謝謝~

  2. 感覺concurrent user很難超過1000,建議檢查一下程式是不是有問題。

    我這篇的狀況是mysql server要反解client端的主機名稱失敗所以造成連線數爆了,你也可以試著將client端的主機名稱與IP寫在mysql server的/etc/hosts裡面,不過總覺得不是相同的問題。

  3. 謝謝你的回應,我不知道concurrent user要超過1000 容易與否
    其實我也是慢慢在try我的問題到底出在哪,目前都還停留在架設環境的測試
    php的部分還沒有測,因為我沒有使用pconnet,且整個站台只有需要select ,最複雜的也只有三個table做join,一般沒有出狀況時,slow query log也沒東西。

    我的網站流量很大,alexa在台灣區排名5XX
    google那邊測得同時在線人數常常都是2000以上
    每天流量30-40W,睌上尖峰時刻真的很多人

    最常出現的問題在我文章一發出去,網友透過facebook粉絲團連入我的主機時,會當掉

    原本我也在想說concurrent不太可能同時超過
    但是有一個現象讓我開始懷疑是這個問題

    假設我mysql設置max connect為300
    但是如果你想要用超過300的數字去做mysqlslap同時併發300個連線時,mysql確定沒有辦法處理,會出現mysql_init() faild,

    於是我就朝著,我的網站人很多,要是真的有這麼剛好,同時concurrent超過設定的臨界值,確實會造成mysql當掉的可能

    剛剛已經把max connect調大去測試了><"

    另外想請教你,我的web跟mysql都在同一台,我的/etc/hosts
    裡面又要打什麼@@?

  4. 我不知道google analytic的同時在線是怎麼算的,不過concurrent user是同時發出的request數目,我是覺得跟同時在線人數應該是不大一樣。

    至於如果您是在同一台主機測的,這樣應該就不必看這篇文章了,這邊發生的問題是反解主機名稱的時候有問題,本地端連接不會有這種問題。

    建議優先檢查程式的問題,例如:搜尋語法是不是有效率、常用欄位有沒有加入索引之類的。

    如果真的就是這麼busy,可以查看目前有許多MySQL fine tune的軟體可以參考,或者提高伺服器的硬體規格、若只需要查詢的話可以架多台mysql server做replication slave使用。

    一點點意見,供您參考。

Comments are closed.