【案例】常駐查詢引發的thread pool 效能問題之二
一 現象
某業務單機4個例項中的一個例項出現連線數遠高於其他三個例項(正常是4K,問題例項是8K+),但是這4個例項的配置完全相同。業務開發反饋為部分連線失敗。
執行show processlist結果顯示:
存在大量的Killed狀態的連線126個,處於Connect狀態的6K+,以及6個binlog dump連線(如果看了前面一篇文章是否有點觸動,會不會是這個導致的?)
執行pt-pmp結果顯示:
mysqld 十分的空閒
執行show engine innodb status:
不存在空閒大事務
二 處理
根據上一篇文章的知識,初步判斷該資料庫例項遇到為Thread Pool的部分group被阻塞了,(能把query堵在login階段的大部分為threadpool排程的問題,當然也不排除是因為邏輯原因造成login中出現內部鎖等待)
在調整thread_pool_oversubscribe後所有的Connect/Killed狀態的連線全部消失,連線數恢復正常。
三 問題分析
雖然問題是解決了,但是還有大量的疑問存在,顯然在原因未知的情況下,如果在業務高峰期意外出現類似現象,後果非常嚴重,因此我們開始挖掘深層次的原因。
【曲折】
既然調整thread_pool_oversubscribe後問題就解決了,很顯然是有group被阻塞了,因此最重要的就是找出是什麼阻塞了Thread Pool。
這次最能引起人注意的現象當然是這126個Killed狀態的連線了,我們知道當連線在執行中,被kill後處於回滾階段時,會顯示Killed。一般來說這個階段非常短暫(除非有大量的rollback工作,但是State資訊是空的,顯然不是在rollback),pt-pmp的結果也證明了這一點。最開始一直懷疑是這些Killed的連線阻塞了threadpool的某些group,但是想來想去沒有想到合理的解釋,這裡浪費了很多的時間。
【柳暗花明】
在Killed session上走不通,那隻能看看其他session了,這時發現被阻塞的Connect連線的thread id十分有規律:
間隔32遞增,很明顯是其中一個group被阻塞了。對32取模後發現全部為19號group,那看來是binlog dump沒跑了。
對binlog dump執行緒的thread id對32取模後發現,6個thread中有4個在19號group中,而thread_pool_oversubscribe才3(內部限制為3+1),因此把19號group完全堵死。
到這裡完全解釋了本次擁堵產生的原因。本次問題中的126個Killed session極大的誤導了我們的判斷。
【深入分析】
回過頭來有人會問,那126個Killed session是怎麼來的呢?
這裡就需要講一下Thread Pool對kill處理的原理:
但是本case中,在這126個session被kill以後,剛好有一個binlog dump連線連到了即將擁堵的19號group。
看上圖緊跟在Killed連線後面的4261459連線,使得19號group徹底被堵住,可憐的Killed連線連退出的機會都沒有了,這就是這126個Killed連線的由來...
某業務單機4個例項中的一個例項出現連線數遠高於其他三個例項(正常是4K,問題例項是8K+),但是這4個例項的配置完全相同。業務開發反饋為部分連線失敗。
執行show processlist結果顯示:
存在大量的Killed狀態的連線126個,處於Connect狀態的6K+,以及6個binlog dump連線(如果看了前面一篇文章是否有點觸動,會不會是這個導致的?)
執行pt-pmp結果顯示:
mysqld 十分的空閒
執行show engine innodb status:
不存在空閒大事務
二 處理
根據上一篇文章的知識,初步判斷該資料庫例項遇到為Thread Pool的部分group被阻塞了,(能把query堵在login階段的大部分為threadpool排程的問題,當然也不排除是因為邏輯原因造成login中出現內部鎖等待)
在調整thread_pool_oversubscribe後所有的Connect/Killed狀態的連線全部消失,連線數恢復正常。
三 問題分析
雖然問題是解決了,但是還有大量的疑問存在,顯然在原因未知的情況下,如果在業務高峰期意外出現類似現象,後果非常嚴重,因此我們開始挖掘深層次的原因。
【曲折】
既然調整thread_pool_oversubscribe後問題就解決了,很顯然是有group被阻塞了,因此最重要的就是找出是什麼阻塞了Thread Pool。
這次最能引起人注意的現象當然是這126個Killed狀態的連線了,我們知道當連線在執行中,被kill後處於回滾階段時,會顯示Killed。一般來說這個階段非常短暫(除非有大量的rollback工作,但是State資訊是空的,顯然不是在rollback),pt-pmp的結果也證明了這一點。最開始一直懷疑是這些Killed的連線阻塞了threadpool的某些group,但是想來想去沒有想到合理的解釋,這裡浪費了很多的時間。
【柳暗花明】
在Killed session上走不通,那隻能看看其他session了,這時發現被阻塞的Connect連線的thread id十分有規律:
-
| 4261587 | unauthenticated user | connecting host | NULL | Connect | NULL | login | NULL |
-
| 4261619 | unauthenticated user | connecting host | NULL | Connect | NULL | login | NULL |
-
| 4261651 | unauthenticated user | connecting host | NULL | Connect | NULL | login | NULL |
-
| 4261683 | unauthenticated user | connecting host | NULL | Connect | NULL | login | NULL |
-
| 4261715 | unauthenticated user | connecting host | NULL | Connect | NULL | login | NULL |
- | 4261747 | unauthenticated user | connecting host | NULL | Connect | NULL | login | NULL |
對binlog dump執行緒的thread id對32取模後發現,6個thread中有4個在19號group中,而thread_pool_oversubscribe才3(內部限制為3+1),因此把19號group完全堵死。
到這裡完全解釋了本次擁堵產生的原因。本次問題中的126個Killed session極大的誤導了我們的判斷。
【深入分析】
回過頭來有人會問,那126個Killed session是怎麼來的呢?
這裡就需要講一下Thread Pool對kill處理的原理:
- 當一個正在執行的連線被kill的時候,它所執行的sql會失敗,其thd->killed會被置為THD::KILL_CONNECTION,同時通知Thread Pool(回撥函式)。Thread Pool在回撥函式中會發出一個io訊號,worker需要捕獲這個event(和正常的event一樣處理)後,才會退出這個session,否則一直可以在show processlist看上類似本例子中126個session的狀態。
-
| 4261363 | xxxx | 10.9.6.57:10843| xxxx_0133 | Killed | 246196 | | NULL |
-
| 4261395 | xxxx | 10.8.9.18:35401| xxxx_0133 | Killed | 246186 | | NULL |
-
| 4261459 | xxxx | 10.8.2.61:60919| NULL| Binlog Dump | 246110| Master has sent all binlog to slave; waiting for binlog to be updated | NULL |
-
| 4261491 | unauthenticated user | connecting host | NULL | Connect | NULL | login | NULL |
-
| 4261502 | xxxx | 10.8.2.41:11862 | xxxx_0133 | Sleep | 1 | | NULL |
- | 4261523 | unauthenticated user | connecting host | NULL | Connect | NULL | login | NULL |
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/30221425/viewspace-2133718/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 【案例】常駐查詢引發的thread pool 效能問題之一thread
- 優化案例--重建索引引發的sql效能問題優化索引SQL
- 【效能測試】常見的效能問題分析思路(二)案例&技巧
- 一次效能問題原因查詢
- reflow和repaint引發的效能問題AI
- Oracle多層級查詢相容的效能問題Oracle
- mysql 的thread poolMySqlthread
- 由VIP漂移引發的演算法異常問題調查和解決演算法
- Oracle效能問題檢查 - 常用查詢指令碼(final)Oracle指令碼
- BIEB:關於CRM系統查詢效能問題
- sql server datediff函式引發的效能問題SQLServer函式
- 分頁及查詢引數傳遞問題分享
- 併發查詢資料庫問題資料庫
- Oracle優化案例-IB網及會話登陸審計引發的效能問題(十七)Oracle優化會話
- 【案例】RAID卡寫策略改變引發的問題AI
- Hystrix Thread Pool 解析thread
- DUBBO Thread pool is EXHAUSTED!thread
- 查詢演算法之二分查詢演算法
- 一個使用JDBC按Date查詢查詢的問題JDBC
- 效能為王:SQL標量子查詢的優化案例分析SQL優化
- 分頁查詢的排序問題排序
- 模板中的名字查詢問題
- Hibernate的Criteria查詢問題。
- 批次查詢的翻頁問題
- sql 模糊查詢問題SQL
- Xilinx問題查詢
- 斷號查詢問題
- Thread pool引數引起的程式連線資料庫響應慢thread資料庫
- .net異常處理的效能問題
- SQL SERVER資料庫datediff函式引發的效能問題SQLServer資料庫函式
- log4j2同步日誌引發的效能問題
- 一次TiDB GC阻塞引發的效能問題分析TiDBGC
- Django ORM 引發的資料庫 N+1 效能問題DjangoORM資料庫
- 一個MySQL多表查詢的問題MySql
- 分頁查詢的排序問題(二)排序
- 從trc查詢死鎖的問題
- 關於Hibernate的查詢問題
- Laravel5.7 查詢問題Laravel