回覆列表
  • 1 # 計算理論

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

  • 2 # 愛可生雲資料庫

    mysql中CPU佔用過高的診斷思路,舉個栗子~

    mpstat -P ALL 1,檢視cpu使用情況,主要消耗在sys即os系統呼叫上

    perf top,cpu主要消耗在_spin_lock

    生成perf report檢視詳細情況

    CPU主要消耗在mutex爭用上,說明有鎖熱點。

    採用pt-pmp跟蹤mysqld執行情況,熱點主要集中在mem_heap_alloc和mem_heap_free上。

    Pstack提供更詳細的API呼叫棧

    #0 0x0000003e0caf80cf in __lll_unlock_wake_private () from /lib64/libc.so.6#1 0x0000003e0ca7cf6a in _L_unlock_5936 () from /lib64/libc.so.6#2 0x0000003e0ca78bbc in _int_free () from /lib64/libc.so.6#3 0x000000000097dcb3 in mem_area_free(void*, mem_pool_t*) ()#4 0x000000000097d2d2 in mem_heap_block_free(mem_block_info_t*, mem_block_info_t*) ()#5 0x00000000009e6474 in row_vers_build_for_consistent_read(unsigned char const*, mtr_t*, dict_index_t*, unsigned long**, read_view_t*, mem_block_info_t**, mem_block_info_t*, unsigned char**) ()#6 0x00000000009dce75 in row_search_for_mysql(unsigned char*, unsigned long, row_prebuilt_t*, unsigned long, unsigned long) ()#7 0x0000000000939c95 in ha_innobase::index_read(unsigned char*, unsigned char const*, unsigned int, ha_rkey_function) ()

    Innodb在讀取資料記錄時的API路徑為

    row_search_for_mysql --》row_vers_build_for_consistent_read --》mem_heap_create_block_func --》mem_area_alloc --》malloc --》_L_unlock_10151 --》__lll_unlock_wait_private

    row_vers_build_for_consistent_read會陷入一個死迴圈,跳出條件是該條記錄不需要快照讀或者已經從undo中找出對應的快照版本,每次迴圈都會呼叫mem_heap_alloc/free。

    而該表的記錄更改很頻繁,導致其undo history list比較長,搜尋快照版本的代價更大,就會頻繁的申請和釋放堆記憶體。

    Linux原生的記憶體庫函式為ptmalloc,malloc/free呼叫過多時很容易產生鎖熱點。

    當多條 SQL 併發執行時,會最終觸發os層面的spinlock,導致上述情形。

    解決方案

    將mysqld的記憶體庫函式替換成tcmalloc,相比ptmalloc,tcmalloc可以更好的支援高併發呼叫。

    修改my.cnf,新增如下引數並重啟

    [mysqld_safe]malloc-lib=tcmalloc

    上週五早上7點執行的操作,到現在超過72小時,期間該例項沒有再出現cpu長期飆高的情形。

    以下是修改前後cpu使用率對比

  • 3 # java架構設計

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

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

    慢查詢,資料庫執行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飆升

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

    增加CPU使用率告警機制,比如使用率超過80%就簡訊告警;

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

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

    日常mysql執行監控,慢查日誌檢視,將隱患扼殺在搖籃之中。

  • 4 # 蓮花童子哪吒

    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%";

    引數說明:

    slow_query_log 慢查詢開啟狀態 OFF 未開啟 ON 為開啟slow_query_log_file 慢查詢日誌存放的位置
  • 中秋節和大豐收的關聯?
  • 生產環境Python程序卡死,怎麼去定位?