1. 程式人生 > >mysql超出最大連接數解決方法

mysql超出最大連接數解決方法

nbsp slist del 就會 字段 排查 自己 主機 完數

遇到mysql超出最大連接數,相信不少人第一反應就是查看mysql進程,看有沒有慢查詢,當然這個做法是完全正確的!
但是很多時候真正的問題不在這裏。
今天有遇到同樣的問題,一味查看mysql進程和慢查詢日誌,無果。
後來老大提點了一下,查看一下nginx日誌,發現有一兩個訪問執行時候比較長,然後使用top命令查看了一下服務器負載,驚了,居然超高!
最後發現原來有一臺web分流主機掛了,導致另外幾臺web主機負載增高,從而導致了php-fpm的執行效率降低。
那麽這跟mysql有什麽關系呢?原因很簡單,因為php執行時間過長,mysql連接遲遲未釋放,就會導致連接數過多出現。
最後總結:其實很多時候,一個問題的根本原因並不是那麽直接的呈現出來,需要自己去跟蹤。


老大有一句很實用的話:遇到問題先查日誌(mysql、php、nginx等)

===============================================================

排查連接數過多的方法

當用戶收到鏈接數告警時,意味著連接數即將達到該實例的上限。如果實例的連接數超過了實例規定的連接數,將無法創建新的連接,這個時候會影響用戶的業務

Mysql 的連接通常是一個請求占用一個連接,如果該請求(update,insert,delete,select)長時間沒有執行完畢,則會造成連接的堆積,迅速的消耗完數據庫的連接數,這個時候技術支持人員就要登錄數據庫進行排序,看看到底是那些sql 占用了連接;

問題排查步驟:

1 、查看實例配置:

可登錄RDS控制臺“詳情與配置”查看實例額定鏈接數,我們假設最高支持1500個鏈接

2、 查看當前的連接數:

1)可登錄RDS控制臺“性能監控”查看實例當前鏈接數。

2)或者登錄數據庫查詢當前連接,可以使用同步賬號或者用戶的業務賬號登錄數據庫,執行show processlist;

[[email protected] ~]# mysql -uroot -h127.0.0.1 -P3020 -e “show processlist”|wc -l

1262

可以看到該實例已經有1262 個連接

3、排查是什麽動作占用了這些連接:

[[email protected]

/* */ ~]# myql -uroot -h127.0.0.1 -P3018 -e “show full processlist”>/tmp/1.log

[email protected] # more /tmp/1.log

615083 my_db 223.4.49.212:54115 my_db Query 100 Sending data

INSERT INTO tmp_orders_modify (oid, tid, seller_id, status, gmt_create, gmt_modified)

SELECT oid, tid, seller_id, status, gmt_create, gmt_modified

FROM sys_info.orders WHERE

gmt_modified < NAME_CONST(‘v_last’,_binary’2012-12-24 10:33:00’ COLLATE ‘binary’) AN

D gmt_modified >= NAME_CONST(‘v_curr’,_binary’2012-12-24 10:32:00’ COLLATE ‘binary’)

621564 my_db 223.4.49.212:46596 my_db Query 3890 sorting result

insert into tmp_trades(sid, d, h, tc, tm, tp, ic, new_tp, old_tp)

select a.seller_id as sid,

…………..

from orders_1 as a where seller_id =1 and is_detail = ‘1’

and created < date_format(‘2012-12-24 10:35:00’, ‘%Y-%m-%d %H:00:00’)

and gmt_create < date_format(‘2012-12-24 10:40:00’, ‘%Y-%m-%d %H:%i:00’)

and gmt_create >= date_format(‘2012-12-24 10:35:00’, ‘%Y-%m-%d%H:%i:00’)

group by d, h

order by d

……………….此處省略其他sql

4、分析連接占用的原因:

可以看到數據庫中有長時間沒有執行完成的sql,一直占用著連接沒有釋放,而應用的請求一直持續不斷的湧入數據庫,這個時候數據庫的連接很快就被使用完;所以這個時候需要排查為什麽這些sql 為什麽長時間沒有執行完畢,是索引沒有創建好,還是sql執行耗時嚴重。

第一條sql:

INSERT INTO tmp_orders_modify (oid, tid, seller_id, status, gmt_create, gmt_modified)

SELECT oid, tid, seller_id, status, gmt_create, gmt_modified

FROM sys_info.orders WHERE

gmt_modified < NAME_CONST(‘v_last’,_binary’2012-12-24 10:33:00’ COLLATE ‘binary’) AN

D gmt_modified >= NAME_CONST(‘v_curr’,_binary’2012-12-24 10:32:00’ COLLATE ‘binary’)

是用戶從sys_info 數據庫中拉取訂單到自己的業務庫中那個,但是在orders 表上沒有gmt_modified 的索引,導致了全表掃描;(更加詳盡的排查方法可以參考:為什麽我的RDS慢了);

第二條sql:

看到這條sql 正在進行sorting 排序,為什麽導致sql 長時間sorting,通常情況下為排序的結果集太大導致排序不能在內存中完成,需要到磁盤上排序,進而導致了性能的下降;解決的辦法就是降低排序的結果集,常用的手段是利用索引的有序性,消除排序,或者建立適當的索引減小結果集;我們可以看到第二條sql 的排序字段非常的復雜,但是我們可以看到查詢的時間範圍是很短,只有5 分鐘的時間間隔,這個時候就可以在gmt_create上創建一個索引,過濾掉大部分的記錄:

Alter tale order_1 add index ind_order_gmt_create(gmt_create);

(該用戶對orders 進行了分表,大概有50 多張分表需要添加gmt_create 字段的索引);

5、經過上面兩步的優化後,用戶實例恢復正常:io 情況和connection 情況,可再次登錄RDS控制臺查看連接數。

mysql超出最大連接數解決方法