1. 程式人生 > >MySQL Insert語句單個批次數量過多導致的CPU效能問題分析

MySQL Insert語句單個批次數量過多導致的CPU效能問題分析

【問題】

最近有臺伺服器比較頻繁的CPU報警,表現的特徵有CPU sys佔比偏高,大量慢查詢,大量併發執行緒堆積。後面開發對insert的相關業務限流後,伺服器效能恢復正常。

 

【異常期間執行緒處理情況】

下圖是當時生產環境異常時抓取的資訊,該事務正在執行insert,已經執行5秒,執行緒執行在innodb核心,狀態是thread declared inside InnoDB,還有4906 tickets可用

 

統計了下有64個執行緒在innodb層,同時看到還有280個執行緒在排隊等待進入innodb執行緒,狀態是sleeping before entering InnoDB

innodb層的併發執行緒執行的SQL比較慢,產生了阻塞,導致了mysql的併發執行緒堆積。

 

【哪些SQL執行慢】

從正在執行的SQL中,看到了insert的慢查詢SQL語句,統計了下這句SQL批量插入大於342條記錄(SQL被截斷)

 

【批量insert的效能測試】

類似這種批量的insert SQL會對MySQL效能造成影響嗎,多大的批次比較合理呢,做了下面測試

在測試伺服器上新建測試表(表結構同生產環境),並定義了5個插入指令碼,分別為單條insert,每10條1個批次insert,每50條1個批次insert,每100條1個批次insert,每340條1個批次insert

用壓測工具模擬512個併發執行緒的情況下,不同型別的SQL插入100W條記錄伺服器的效能情況,下表是壓測統計

 

 

資料量

併發執行緒

執行時間(秒)

每秒insert

慢查詢數量

Context switch

CPU使用率

CPU sys佔比

普通insert(1條)

1000000

512

33

3W

0

79W

73%

39%

批量SQL(10條)

1000000

512

23

4.3W

0

49W

78%

56%

批量SQL(50條)

1000000

512

21

4.7W

0

42W

80%

60%

批量SQL(100條)

1000000

512

15

6.6W

20

53W

70%

45%

批量SQL(340條)

1000000

512

15

6.6W

200

38W

86%

70%

 

下圖是批量SQL(340條)執行時的效能情況,可以看到當每100條記錄一個批次執行insert時,開始出現慢查詢,每340條1個批次執行insert時,在高併發的情況下,會產生大量的慢查詢,這個現象接近於我們目前生產環境異常時的情況

 

【優化方案】

對於MySQL需要插入大量資料時,每次單條的insert效能較差,為了提升insert效能,我們採用了每批次多條記錄同時insert的方法。

但當批次增大到一定數量時,在高併發訪問的情況下,單個批次執行的效能會出現較大的下降,出現大量慢查詢,併發執行緒堆積,CPU上升出現瓶頸, innodb層的併發執行緒處理被慢查詢阻塞,後面只能通過限流來緩解效能問題。

根據上面的測試結論,建議控制熱表單個批次insert的記錄條數,最好單個批次控制在10條左右(因為即使調大到50條,插入效能沒有大的提升,在高併發場景下,首先要保證當前SQL的執行效能)。

 

【優化後CPU告警消失,執行平穩】