[玩轉MySQL之二]MySQL連線機制淺析及運維

沈歐邦發表於2018-09-06

前言

使用MySQL資料庫的第一步必然是建立連線登入,然後在上面執行SQL命令。無論是通過mysql的客戶端,還是通過C-API,JDBC標準介面連線資料庫,這個過程一定少不了。那麼就不經有幾個疑問?1. 可以通過哪幾種方式連線?

  • 當C和S都在同一臺機器上時,那他們之間的通訊方式是否和程式間的通訊差不多?
  • 當C和S不在一臺伺服器上時候,是採用tcp來通訊?還是使用http?
  • 當C和S不在一臺伺服器上時,不論是採用tcp或者http通訊,都會有安全風險,是否有加密措施?

2. MySQL的連線有沒有區別?

  • 如果MySQL的連線有區別,分為哪幾種?他們之間的區別是什麼

3. MySQL伺服器是如何管理客戶端連線請求的?

  • 連線的時候,客戶端每法送一個請求,MySQL伺服器就重新建立一個連線麼?如果不是,那麼伺服器端是如何處理的?
  • MySQL伺服器的連線數有沒有限制?
  • 連線數限制能否精確到使用者?
  • C/S之間的連線是否有時間限制?

4. MySQL伺服器相關的連線配置引數有哪些?

5. MySQL伺服器中連線相關資訊如何檢視?

6. 客戶端連線MySQL伺服器會出現哪些錯誤以及解決辦法?

一、MySQL連線方式

到MySQL5.7為止,總共有五種連線方式,分別是TCP/IP,TLS/SSL,Unix Sockets,Shared Memory,Named pipes,具體區別如下:

連線方式 預設是否開啟 支援系統 只支援本機 如何開啟 引數配置
TCP/IP    所有系統    –skip-networking=yes/no  –port和 –bind-address 
TLS/SSL    所有系統(基於TCP/IP)之上    –ssl=yes/no  –ssl-* options
Unix Sockets    類Unix系統    設定–socket= 來關閉.  –socket=socket path 
Shared Memory    Windows系統    –shared-memory=on/off  –shared-memory-base-name=
Named pipes    Windows系統    –enable-named-pipe=on/off  –socket=

使用教程

由於小編使用的是Mac OS系統,下面只簡單介紹非Windows系統下的三種連線方式。1.Unix Sockets

mysql -uroot

如果在MySQL本機使用這種方式連線MySQL資料庫,預設使用Unix Sockets。

2.TCP/IP

mysql --protocol=tcp -uroot
mysql -P3306 -h127.0.0.1 -uroot

連線的時候指定連線協議,或者指定相應的IP及埠,則連線方式就變成了TCP/IP方式。

3.TLS/SSL

mysql --protocol=tcp -uroot --ssl=on
mysql -P3306 -h127.0.0.1 -uroot --ssl=on

TLS/SSL是基於TCP/IP的,所以只需再指定開啟ssl配置即可。然後我們通過以下語句來查詢目前資料庫的連線情況:

SELECT DISTINCT connection_type from performance_schema.threads where connection_type is not null

如何選擇連線方式呢?1. 如果程式和資料庫在同一臺機子(類Unix系統)上,推薦使用Unix Sockets,因為它效率更高;2. 若資料庫分佈在不同的機子上,且能確保連線安全或者安全性要求不是那麼高,推薦使用TCP/IP,反之使用TLS/SSL;

二、 MySQL連線分類

當資料庫伺服器和客戶端位於不同的主機時,就需要通過建立網路連線來進行通訊。客戶端必須使用資料庫連線來傳送命令和接收應答、資料。根據伺服器的處理機制分為短連線和長連線。1.短連線短連線是指程式和資料庫通訊時需要建立連線,執行操作後,連線關閉。短連線簡單來說就是每一次運算元據庫,都要開啟和關閉資料庫連線,基本步驟是:連線→資料傳輸→關閉連線。

在慢速網路下使用短連線,連線的開銷會很大;在生產繁忙的系統中,連線也可能會受到系統埠數的限制,如果要每秒建立幾千個連線,那麼連線斷開後,埠不會被馬上回收利用,必須經歷一個“FIN”階段的等待,直到可被回收利用為止,這樣就可能會導致埠資源不夠用。在Linux上,可以通過調整/proc/sys/net/ipv4/ip_local_port_range來擴大埠的使用範圍;調整/proc/sys/net/ipv4/tcp_fin_timeout來減少回收延期(如果想在應用伺服器上調整這個引數,一定要慎重!)。

另外一個辦法是主機使用多個IP地址。埠數的限制其實是基於同一個IP:PORT的,如果主機增加了IP,MySQL就可以監聽多個IP地址,客戶端也可以選擇連線某個IP:PORT,這樣就增加了埠資源。

2.長連線長連線是指程式之間的連線在建立之後,就一直開啟,被後續程式重用。使用長連線的初衷是減少連線的開銷,儘管MySQL的連線比其他資料庫要快得多。

以PHP程式為例,當收到一個永久連線的請求時,PHP將檢查是否已經存在一個(前面已經開啟了的)相同的永久連線。如果存在,則將直接使用這個連線;如果不存在,則建立一個新的連線。所謂“相同”的連線是指用相同的使用者名稱和密碼到相同主機的連線。

從客戶端的角度來說,使用長連線有一個好處,可以不用每次建立新連線,若客戶端對MySQL伺服器的連線請求很頻繁,永久連線將更加高效。對於高併發業務,如果可能會碰到連線的衝擊,推薦使用長連線或連線池。

從伺服器的角度來看,情況則略有不同,它可以節省建立連線的開銷,但維持連線也是需要記憶體的。如果濫用長連線的話,可能會使用過多的MySQL伺服器連線。現代的作業系統可以擁有幾千個MySQL連線,但很有可能絕大部分都是睡眠(sleep)狀態的,這樣的工作方式不夠高效,而且連線佔據記憶體,也會導致記憶體的浪費。

對於擴充套件性好的站點來說,其實大部分的訪問並不需要連線資料庫。如果使用者需要頻繁訪問資料庫,那麼可能會在流量增大的時候產生效能問題,此時長短連線都是無法解決問題的,所以應該進行合理的設計和優化來避免效能問題。

如果客戶端和MySQL資料庫之間有連線池或Proxy代理,一般在客戶端推薦使用短連線。對於長連線的使用一定要慎重,不可濫用。如果沒有每秒幾百、上千的新連線請求,就不一定需要長連線,也無法從長連線中得到太多好處。在Java語言中,由於有連線池,如果控制得當,則不會對資料庫有較大的衝擊,但PHP的長連線可能導致資料庫的連線數超過限制,或者佔用過多的記憶體。

對此,研發工程師、系統運維工程師、DBA需要保持溝通,確定合理的連線策略,千萬不要不假思索就採用長連線。

3.連線池由於一些資料庫建立和銷燬連線的開銷很大,或者相對於所執行的具體資料操作,連線所耗的資源過多,此時就可能需要新增連線池來改進效能。

資料庫連線池是一些網路代理服務或應用伺服器實現的特性,如J2EE伺服器,它實現了一個持久連線的“池”,允許其他程式、客戶端來連線,這個連線池將被所有連線的客戶端共享使用,連線池可以加速連線,也可以減少資料庫連線,降低資料庫伺服器的負載。

4.持久連線和連線池的區別長連線是一些驅動、驅動框架、ORM工具的特性,由驅動來保持連線控制程式碼的開啟,以便後續的資料庫操作可以重用連線,從而減少資料庫的連線開銷。而連線池是應用伺服器的元件,它可以通過引數來配置連線數、連線檢測、連線的生命週期等。

如果連線池或長連線使用的連線數很多,有可能會超過資料庫例項的限制,那麼就需要留意連線相關的設定了,比如連線池的最小、最大連線數設定,以及php-fpm的程式個數等,否則程式將不能申請新的連線。

三、MySQL伺服器端如何管理客戶端連線

MySQL連線管理器執行緒負責處理伺服器偵聽的網路介面上的客戶端連線請求。連線管理器執行緒將每個客戶端連線與專用於它的執行緒相關聯,以處理該連線的身份驗證和請求處理。

連線管理執行緒在必要時建立一個新執行緒,但是會先嚐試避免這樣做,MySQL連線管理器執行緒首先會檢視執行緒快取是否包含空閒可用於連線的執行緒,如果有,則從執行緒快取中選取一個空閒的執行緒分配給客戶端,如果沒有,則重新建立一個執行緒。當連線結束時,如果快取未滿,則其執行緒返回到執行緒快取中,用於下次使用。

在這種連線線​​程模型中,存在與當前連線的客戶端一樣多的執行緒,這在伺服器工作負載高還必須以處理大量的連線時具有一些缺點,例如,執行緒建立和處理變得昂貴。此外,每個執行緒都需要消耗伺服器的核心資源,如堆疊空間。所以為了適應大量的併發連線,每個執行緒的堆疊大小必須保持較小,否則會由於太大導致消耗伺服器大量記憶體的情況,也可能耗盡其他資源,排程開銷也會變得很大。

為了控制和監視伺服器如何管理客戶端連線的執行緒,有幾個系統和狀態變數可以檢視。

執行緒快取由thread_cache_size系統變數確定其大小,預設值為0(無快取),這將導致為每個新連線設定一個執行緒,並在連線終止時進行處理。設定thread_cache_size為N,啟用N個非活動連線執行緒被快取。thread_cache_size可以在伺服器啟動時設定或在伺服器執行時更​​改,連線執行緒在與其關聯的客戶端連線終止時變為不活動。

通過MySQL狀態變數Threads_cached和Threads_created可以監控快取記憶體中的執行緒數和已經建立了多少個執行緒。另外你也可以通過max_connections變數控制可以同時連線的最大客戶端數。

但當執行緒堆疊太小時,會限制了伺服器可以處理的SQL語句的複雜性,儲存過程的遞迴深度和其他記憶體消耗的操作。

四、 MySQL伺服器相關的連線配置引數

1.skip-networking開啟該選項可以徹底關閉MySQL的TCP/IP連線方式,如果WEB伺服器是以遠端連線的方式訪問MySQL資料庫伺服器則不要開啟該選項!否則將無法正常連線!

2.skip-name-resolve禁止MySQL對外部連線進行DNS解析,使用這一選項可以消除MySQL進行DNS解析的時間。但需要注意,如果開啟該選項,則所有遠端主機連線授權都要使用IP地址方式,否則MySQL將無法正常處理連線請求!

3.max_connectionsmax_connections是指MySql的最大連線數,如果伺服器的併發連線請求量比較大,建議調高此值,以增加並行連線數量,當然這建立在伺服器能支撐的情況下,因為如果連線數越多,由於MySQL會為每個連線提供連線緩衝區,就會開銷越多的記憶體,所以要適當調整該值,不能盲目提高設值。

4.max_user_connectionsmax_user_connections是指每個資料庫使用者的最大連線針對某一個賬號的所有客戶端並行連線到MYSQL服務的最大並行連線數。簡單說是指同一個賬號能夠同時連線到mysql服務的最大連線數。設定為0表示不限制。

順便介紹下show global status中的Max_used_connections:它是指從這次mysql服務啟動到現在,同一時刻並行連線數的最大值。它不是指當前的連線情況,而是一個比較值。如果在過去某一個時刻,MYSQL服務同時有1000個請求連線過來,而之後再也沒有出現這麼大的併發請求時,則Max_used_connections=1000.請注意與show variables 裡的max_user_connections的區別。預設為0表示無限大。

5. max_connect_errors設定每個主機的連線請求異常中斷的最大次數,當超過該次數,MySQL伺服器將禁止host的連線請求,直到mysql伺服器重啟或通過flush hosts命令清空此host的相關資訊。

6.thread_handingMysql 服務中執行緒處理模式包括兩種:

  • no-threads(單執行緒處理,多用於debug)
  • one- thread-per-connection(每個請求對應一個執行緒,目前被作為預設值);

7.thread_cache_size這個值表示可以重新利用儲存在快取中執行緒的數量,當斷開連線時如果快取中還有空間,那麼客戶端的執行緒將被放到快取中,如果執行緒重新被請求,那麼請求將從快取中讀取,如果快取中是空的或者是新的請求,那麼這個執行緒將被重新建立,如果有很多新的執行緒,增加這個值可以改善系統效能.因為當應用發起一個對資料庫的操作時,在整個應用中是一個不小的開銷,從建立連線之初,CPU 要給它劃分一定的thread stack,然後進行使用者身份認證,建立上下文資訊,最後請求完成,關閉連線,同時釋放資源,可以稱的上是秒級的過程,在高併發的情況下,將給系統帶來巨大的壓力更不能保證效能。所以,採用執行緒重用,減小這部分的消耗。通過比較 Connections 和 Threads_created 狀態的變數,可以看到這個變數的作用。

mysql> show status like `thread%`;
mysql> show status like `thread%`;
+-------------------+-------+
| Variable_name     | Value |
+-------------------+-------+
| Threads_cached    | 649   |  <—當前被快取的空閒執行緒的數量
| Threads_connected | 93    | <—正在使用(處於連線狀態)的執行緒
| Threads_created   | 742   |  <—服務啟動以來,建立了多少個執行緒
| Threads_running   | 5     | <—正在忙的執行緒(正在查詢資料,傳輸資料等等操作)
+-------------------+-------+```
檢視開機起來資料庫被連線了多少次?
```bash
mysql> show status like `%connections%`;
mysql> show global status like `%connections%`;
+-----------------------------------+---------------------+
| Variable_name                     | Value               |
+-----------------------------------+---------------------+
| Connection_errors_max_connections | 0                   |
| Connections                       | 101395055           |   <–服務啟動以來,歷史連線數
| Max_used_connections              | 742                 |
| Max_used_connections_time         | 2018-08-21 15:42:38 |
+-----------------------------------+---------------------+

通過連線執行緒池的命中率來判斷設定值是否合適?命中率超過90%以上,設定合理。(Connections – Threads_created) / Connections * 100 %

8. thread_stack每個連線執行緒被建立時,MySQL給它分配的記憶體大小。當MySQL建立一個新的連線執行緒時,需要給它分配一定大小的記憶體堆疊空間,以便存放客戶端的請求的Query及自身的各種狀態和處理資訊。當然如果遇到下面的錯誤提示就應該考慮增加這個值了。mysql-debug: Thread stack overrun 如:

java.sql.SQLException: Thread stack overrun: 5456 bytes used of a 131072 byte stack, and 128000 bytes needed. Use `mysqld --thread_stack=#` to specify a bigger stack.

9.Connect_Timeout字面上看意思是連線超時,指的是MySQL連線過程中握手的超時時間,在5.0.52以後預設為10秒,之前版本預設是5秒。

connect_timeout: The number of seconds that the mysqld server waits for a connect packet before responding with Bad handshake. The default value is 10 seconds as of MySQL 5.0.52 and 5 seconds before that

mysql的基本原理是有個監聽執行緒迴圈接收請求,當有請求來時,建立執行緒(或者從執行緒池中取)來處理這個請求。由於mysql連線採用TCP協議,那麼之前勢必是需要進行TCP三次握手的。TCP三次握手成功之後,客戶端會進入阻塞,等待服務端的訊息。服務端這個時候會建立一個執行緒(或者從執行緒池中取一個執行緒)來處理請求,主要驗證部分包括host和使用者名稱密碼驗證。host驗證我們比較熟悉,因為在用grant命令授權使用者的時候是有指定host的。使用者名稱密碼認證則是服務端先生成一個隨機數傳送給客戶端,客戶端用該隨機數和密碼進行多次sha1加密後傳送給服務端驗證。如果通過,整個連線握手過程完成。(具體握手過程後續找到資料再分析)

由此可見,整個連線握手可能會有各種可能出錯。所以這個connect_timeout值就是指這個超時時間了。可以簡單測試下,執行下面的telnet命令會發現客戶端會在10秒後超時返回。

$time telnet mysql_ip_addr port
$ time telnet 127.0.0.1 5051
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is `^]`.
?
Connection closed by foreign
host.
real    0m5.005s #這裡的5秒即mysql預設的連線超時
user    0m0.000s
sys 0m0.000s

Telnet未退出前通過show processlist檢視各執行緒狀態可見,當前該連線處於授權認證階段,此時的使用者為“unauthenticated user”。

256 | unauthenticated user | localhost:60595 | NULL | Connect | NULL | Reading from net | NULL 

10.wait_timeout&interactive_timeout等待超時,那mysql等什麼呢?確切的說是mysql在等使用者的請求(query),如果發現一個執行緒已經sleep的時間超過wait_timeout了那麼這個執行緒將被清理掉,從文件上來看wait_timeout和interactive_timeout都是指不活躍的連線超時時間,而interactive_timeout針對互動式連線,wait_timeout針對非互動式連線。MySQL連線執行緒啟動的時候wait_timeout會根據是互動模式還是非互動模式被設定為這兩個值中的一個。如果我們執行mysql -uroot -p命令登陸到mysql,wait_timeout就會被設定為interactive_timeout的值。如果我們在wait_timeout時間內沒有進行任何操作,那麼再次操作的時候就會提示超時,這是mysql client會重新連線。關於兩者的區別,請參考雲小祕部落格MySQL之wait_timeout和interactive_timeout引數

11. net_read_timeout資料庫從客戶端讀取資料超時時間。在終止讀之前,從一個連線獲得資料而等待的時間秒數;當服務正在從客戶端讀取資料時,net_read_timeout控制何時超時。即客戶端執行資料讀取,等待多少秒仍未執行成功時自動斷開連線。 可能的原因為網路異常或客戶端/伺服器端忙無法及時傳送或接收處理包。

12. net_write_timeout資料庫往客戶端寫資料超時時間。和net_read_timeout意義類似,在終止寫之前,等待多少秒把block寫到連線;當服務正在寫資料到客戶端時,net_write_timeout控制何時超時。一般在網路條件比較差的時,或者客戶端處理每個資料塊耗時比較長時,由於 net_write_timeout導致的連線中斷很容易發生。

13. net_retry_count如果MySQL服務端在讀寫資料時,出現連線中斷,會重試net_retry_count指定的次數。在系統FreeBSD中有效,Linux中只有在build的時候指定NO_ALARM引數時net_retry_count才會起作用。

connect_timeout在獲取連線階段(authenticate)起作用,interactive_timeout和wait_timeout在連線空閒階段(sleep)起作用,而net_read_timeout和net_write_timeout則是在連線繁忙階段(query)起作用。 獲取MySQL連線是多次握手的結果,除了使用者名稱和密碼的匹配校驗外,還有IP->HOST->DNS->IP驗證,任何一步都可能因為網路問題導致執行緒阻塞。為了防止執行緒浪費在不必要的校驗等待上,超過connect_timeout的連線請求將會被拒絕。 即使沒有網路問題,也不能允許客戶端一直佔用連線。對於保持sleep狀態超過了wait_timeout(或interactive_timeout,取決於CLIENT_INTERACTIVE標誌)的客戶端,MySQL會主動斷開連線。 即使連線沒有處於sleep狀態,即客戶端忙於計算或者儲存資料,MySQL也選擇了有條件的等待。在資料包的分發過程中,客戶端可能來不及響應(傳送、接收、或者處理資料包太慢)。為了保證連線不被浪費在無盡的等待中,MySQL也會選擇有條件(net_read_timeout和net_write_timeout)地主動斷開連線。比如我在客戶端用load data infile的方式匯入很大的一個檔案到資料庫中,然後中途用iptables禁用掉mysql的3306埠,這個時候伺服器端該連線狀態是reading from net,在等待net_read_timeout後關閉該連線。同理,在程式裡面查詢一個很大的表時,在查詢過程中同樣禁用掉埠,製造網路不通的情況,這樣該連線狀態是writing to net,然後在net_write_timeout後關閉該連線。

五、 MySQL連線相關狀態檢視

檢視MySQL狀態命令:

1. show global status  # 輸出所有記錄的狀態
2. show global status like `%xxxx%`  # 輸出記錄帶有xxx關鍵字的狀態
   : show global status like thread%

1. Aborted_clients由於客戶端沒有正確關閉連線導致客戶端終止而中斷的連線數。 如,客戶端和服務端建立連線好之後,等待wait_time時間後,客戶端和伺服器之間的連線自動退出,此時會發現Aborted_clients計數器加1。

2. Aborted_connects試圖連線到MySQL伺服器而失敗的連線數。如:telnet 127.0.0.1 3306, 然後什麼都不做, ctrl+],quit退出,就會發現aborted_connects計數器加1。

3. connections試圖連線到(不管成功與否)MySQL伺服器的連線數計數。

4. Bytes_received從所有客戶端接收到的位元組數。

5. Bytes_sent傳送給所有客戶端的位元組數。

6. Threads_cached代表當前此時此刻執行緒快取中有多少空閒執行緒。

7.Threads_connected代表當前已建立連線的數量,因為一個連線就需要一個執行緒,所以也可以看成當前被使用的執行緒數。

8. Threads_created建立用來處理連線的執行緒數。如果Threads_created較大,則需要增加thread_cached_size的值。

9.Threads_running代表當前啟用的(非睡眠狀態)執行緒數。

六、MySQL連線常見錯誤

1.ERROR 1045 (28000): Access denied for user `testcon`@`10.24.236.231` (using password: YES)

原因1: 可能是使用者密碼錯誤原因2: 可能是使用者錯誤原因3: 可能是host錯誤

解決辦法:

  • 如果確認密碼正確,檢查mysql.user表裡面的account資訊(主要是user,host列),確認連線的account符合user裡面的匹配項
  • 如果通過mysql.user account正常,可以嘗試更改一下密碼再進行測試
  • 最快速簡單的方法是重新建立一個賬號,授予相關的許可權

2.ERROR 2005 (HY000): Unknown MySQL server host `com-mysql.coflodhn1n0y.us-west-1.rds.amazonaws.com` (110)

原因: 可能DNS解析異常

解決方法:通過ping來觀察dns的解析,並檢查系統dns配置。如果ping資料庫域名無法獲取IP,則可以判斷dns配置有問題。

3. ERROR 1449 (HY000): The user specified as a definer (`testcon`@`10.24.236.231`) does not exist 或者ERROR 1045 (28000): user not exist

原因: account不存在

解決辦法 : 檢查mysql.user表裡面的account資訊(主要是user,host列),確認連線的account符合user裡面的匹配項

4.ERROR 2003 (HY000): Can`t connect to MySQL server on `test.mysql.rds.aliyuncs.com` (110)

原因1: 安全限制,不允許訪問,比如防火牆或者雲RDS的白名單原因2: 埠錯誤,如MySQL執行埠不是3306原因3: mysql服務未正確執行

解決辦法:

  • 執行lsof -i:3306, 檢查下3306埠的程式資訊
  • 執行ps -ef | grep mysql,檢查下程式資訊
  • 如果前兩步沒有輸出,可能mysql server未在主機正確執行
  • 如果前兩步有輸出,說明MySQL正常執行,則檢查一下防火牆配置規則,或者使用telnet host 3306
  • 雲資料庫RDS,需檢查RDS的白名單中是否包含客戶端伺服器IP

5. ERROR 1135 (HY000): Can`t create a new thread (errno 11); if you are not out of available memory, you can consult the manual for a possible OS-dependent bug

原因1: 伺服器作業系統limits.conf檔案對max user processes做了限制原因2: MySQL沒有可用記憶體

解決辦法:

  • 通過命令 ulimit -a檢視max user processes配置,如果較小,修改核心引數
  • 增加MySQL記憶體

6. ERROR 1130 (HY000): Host `192.168.1.3` is not allowed to connect to this MySQL server

原因: mysql.user表裡沒有匹配的host名稱

解決辦法:檢查mysql.user表裡面的account資訊(主要是user,host列),確認連線的account符合user裡面的匹配項

7.ERROR 1045 (HY000): #28000ip not in whitelist

原因: rds for mysql的提示,且訪問模式為高安全模式才會出現,原因是ip地址沒有在rds的白名單中

解決辦法檢查RDS的白名單中是否包含客戶端伺服器IP地址

8.ERROR 5 (HY000): Out of memory (Needed 260400 bytes)

原因: MySQL沒有可用記憶體

解決辦法:(先確認記憶體是否已經不足):增加mysql的記憶體,如果是rds,可以考慮升級RDS的例項規格 

9. ERROR 1129 (HY000): Host `10.24.236.231` is blocked because of many connection errors; unblock with `mysqladmin flush-hosts`

原因: account達到了MySQL伺服器設定的max_connect_errors的值

解決辦法:系統命令列下執行mysqladmin flush-hosts或者mysql命令列裡執行flush hosts

10. ERROR 1226 (42000): User `testcon` has exceeded the `max_user_connections` resource (current value: 2)

原因: 達到了該account設定的max_user_connections大小

解決辦法:重新使用grant設定使用者的max_user_connections或者調整系統變數max_user_connections,如果沒有許可權,也可以刪除賬號重新建立

11. ERROR 1226 (42000): User `testcon` has exceeded the `max_connections_per_hour` resource (current value: 2)

原因: 達到了該account設定的max_connections_per_hour大小

解決辦法:重新grant該賬號max_connections_per_hour為0,如果沒有許可權,也可以刪除賬號重新建立

12.ERROR 1040 (HY000): Too many connections

原因: 達到了mysql系統引數max_connections的限制

解決辦法:

  • 檢查MySQL server的CPU,IO,記憶體等狀態的變化,是否有明顯的升高現象,如果有明顯的升高,實時的通過show processlist獲取session資訊,通過獲取到的session資訊分析cpu,io以及記憶體跑高的原因,綜合分析(是否是遇到了阻塞或者慢查詢)kill掉相關會話來解決
  • 檢查MySQL server的CPU,IO,記憶體等狀態的變化,是否有明顯的升高現象,如果沒有明顯的升高,實時的通過show processlist獲取session資訊,通過獲取到的session資訊找到會話來源(看下是否是sleep連線較多),嘗試調整來源主機的應用行為
  • 如果無法手動干預,嘗試調整MySQL的max_connections的值,如果是rds for mysql,需要升級例項規格來提升連線數

參考資料

MySQL網路協議分析MySQL初識-架構-安裝-初始化-連線-管理工具-資料檔案mysql timeout各種超時的機制以及區別MySQL效能優化之引數配置mysql timeout知多少mysql檢視connect_timeout設定MySQL 各種超時引數的含義mysql timeout各種超時的機制以及區別MySQL連線錯誤的十二“坑”


相關文章