mysql數據庫cpu飆升800%,如何故障定位及優化?

zhangbaozhi


mysql數據庫cpu飆升800%,基本上就兩種原因:

  1. 訪問量大,大到你8核cpu都承受不了;

  2. 慢查詢,數據庫執行sql語句操作(查詢數據、修改數據)會產生大量的邏輯讀,將讀出來的數據維護到臨時表中(內存),系統需要消耗較多的cpu來維持內存與磁盤數據的一致性。

大多數情況下都是開發人員對sql的把握質量不夠,導致慢sql查詢的產生,進而影響數據庫的整體運行狀況。

大量行鎖衝突、行鎖等待或後臺任務也有可能會導致實例的 CPU 使用率過高,但這些情況出現的概率非常低。

當我們的數據庫性能下降的厲害或者cpu飆升時候,可以進行如下操作定位問題:

查詢mysql進程列表

show full processlist;

獲取到mysql當前使用的進程:

如果進程很多,說明請求量很大,需要區分是否正常業務流量,還是代碼問題導致的。

查詢慢查詢日誌

show variables like '%slow_query_log%';

找到慢查詢日誌文件/home/mysql/data3085/mysql/

slow_query.log

,即可找到慢查詢日誌信息,解決這些慢sql,你的cpu一定會降下來。

避免數據庫cpu飆升

實際開發過程中,我們對數據庫的使用一定要小心,不能等問題發生了再去排查問題解決問題,而是要預防問題的發生,並且在問題可能發生的情況下,提前介入,避免問題擴大化。平時開發過程中需要做好一些準備工作:

  1. 增加CPU使用率告警機制,比如使用率超過80%就短信告警;

  2. 所有的sql語句必須走索引,有DBA則由DBA統一調控,沒有的話開發人員先執行explain看sql執行計劃,必須走索引,屬於強制規則;

  3. 新功能上線必須進行壓測;

  4. 日常mysql運行監控,慢查日誌查看,將隱患扼殺在搖籃之中。

以上就是一些mysql穩定運行的個人看法,大家還有什麼好的建議,歡迎評論去交流討論,批評指正~

java架構設計


MySQL服務器的性能一直項目開發中熱門問題,一個網站的性能瓶頸往往都發生在mysql數據庫上。

mysql數據庫cpu飆升800%,證明數據庫的使用率遠遠大於正常情況下mysql的使用率。原因如下:

1、訪問量過大,導致你CPU的進程切換一直累加而導致使用率過高,mysql是一個多線程工作模式,當你訪問量過大,網站可能會開啟更多線程來提速,如果你的請求量過於的大了,那麼過多的切換就會讓cpu一直持續以工作。


2、sql的執行耗時過長,數據庫執行sql語句操作(查詢數據、修改數據)會產生大量的邏輯讀,將讀出來的數據放入到內存緩衝區裡面去,但是緩衝內存有限,一些過時的數據在查詢後就會通過LRU算法讓其淘汰,這一系列的過程都需要調用cpu來維持內存與磁盤數據的一致。

CPU的調用單位是什麼?

CPU的使用率過高,那麼相應的線程執行也會增多,所以首先可以通過查看mysql的線程列表,判斷是那些執行業務的sql語句過多,然後再進行拆分。並優化業務下面的SQL語句。

線程列表有如下查看方式:1、通過命令:show full processlist;2、通過查詢連接線程相關的表來查看:

select id, db, user, host, command, time, state, info

from information_schema.processlist;

3、通過Navicat軟件下面的,工具欄-->服務器監控 查看

下面對每列做下介紹:

Id:鏈接mysql 服務器線程的唯一標識,可以通過kill來終止此線程的鏈接。

User:當前線程鏈接數據庫的用戶

Host:顯示這個語句是從哪個ip 的哪個端口上發出的。可用來追蹤出問題語句的用戶

db: 線程鏈接的數據庫,如果沒有則為null

Command: 顯示當前連接的執行的命令,一般就是休眠或空閒(sleep),查詢(query),連接(connect)

Time: 線程處在當前狀態的時間,單位是秒

State:顯示使用當前連接的sql語句的狀態,很重要的列,後續會有所有的狀態的描述,請注意,state只是語句執行中的某一個狀態,一個 sql語句,已查詢為例,可能需要經過copying to tmp table,Sorting result,Sending data等狀態才可以完成

Info: 線程執行的sql語句,如果沒有語句執行則為null。這個語句可以使客戶端發來的執行語句也可以是內部執行的語句


如果到State為查詢到有大量的Copying to tmp table on disk狀態 明顯是由於臨時表過大導致mysql將臨時表寫入硬盤影響了整體性能,就需要調高臨時表大小


慢日誌查詢分析

如果是因為執行的SQL語句導致整個計算的時間延長,那最好的辦法就是針對慢查詢日誌裡執行慢的sql語句進行優化,如果sql語句用了大量的group by等語句,union聯合查詢等肯定會將mysql的佔用率提高。所以就需要優化sql語句。並基於索引來快速檢索。

show variables like 'slow_query%';

參數說明:

  1. slow_query_log 慢查詢開啟狀態 OFF 未開啟 ON 為開啟
  2. slow_query_log_file 慢查詢日誌存放的位置



PHP智慧與能力


看服務器有多少個邏輯核心,800%是MySQL有8個線程持續性工作,很可能是大量讀取或者寫入,看業務需求,是否必須如此,若必須大量將數據在內存和磁盤之間傳輸,可考慮多硬盤分配表格,壓縮表格,將大量內存分配給數據庫供其緩存表格,並按照數據庫特性,將內存分塊用線程管理,加大並行處理效率。


分享到:


相關文章: