數據庫CPU 100%處理記錄


問題描述

2020年7月13日一大早收到告警,測試環境數據庫CPU告警。
登錄aws查看監控如下圖

 

 

 

問題分析

出現這種cpu 100%的問題,都是因為sql性能問題導致的,
主要表現於 cpu 消耗過大,有慢sql造成、慢sql全表掃描,掃描數據庫過大,內存排序,隊列等等
並發現寫入相對於查詢來說比較高(這是一個關鍵點)
有了大概的思路下邊開始排查吧
 
查看進程
show full processlist;


發現有大量的語句狀態為 sending data
sending data: sql正從表中查詢數據,如果查詢條件沒有適當索引,會導致sql執行時間過長。
 
查看慢日志配置
mysql> show variables like 'slow_query%';
+---------------------+----------------------------------------------+
| Variable_name       | Value                                        |
+---------------------+----------------------------------------------+
| slow_query_log      | ON                                           |
| slow_query_log_file | /rdsdbdata/log/slowquery/mysql-slowquery.log |
+---------------------+----------------------------------------------+
2 rows in set
mysql> show variables like 'slow_launch_time';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| slow_launch_time | 1     |
+------------------+-------+
1 row in set

 

看到慢日志已經開啟
登錄aws cloudwatch查看慢日志發現大部分為這條sql
# User@Host: admin[admin] @  [10.0.11.12]  Id:  2302
# Query_time: 3.602910  Lock_time: 0.100585 Rows_sent: 2  Rows_examined: 4454
SET timestamp=1594629311;
SELECT a.enum_value,a.bsh_enum_value
        FROM external_mapping a
        LEFT JOIN external_bsh_command_key b ON a.bsh_command_id=b.id
        LEFT JOIN external_bsh_command_options c ON a.bsh_options_id=c.id
        LEFT JOIN external_command_key d ON a.command_id=d.id
        LEFT JOIN category h ON a.category_id=h.id
        where 1=1
            AND b.code='BSH.Common.Status.Event'
            AND c.code='BSH.Common.Setting.Rm4Valve'
            AND d.code='Rm4_Valve'
            AND a.platform_id=119
            AND h.cname = 'TT';

 

 
查看是否有鎖表
mysql> show OPEN TABLES where In_use > 0;
#查看是否有鎖表
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
#查看正在鎖的事務
Empty set
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
#查看等待鎖的事務
Empty set
暫時沒有看到鎖表的情況

 

 
查看緩存命中
mysql> show global status like 'Qca%';
+-------------------------+-----------+
| Variable_name           | Value     |
+-------------------------+-----------+
| Qcache_free_blocks      | 1         |
| Qcache_free_memory      | 134199912 |
| Qcache_hits             | 0         |
| Qcache_inserts          | 0         |
| Qcache_lowmem_prunes    | 0         |
| Qcache_not_cached       | 44950579  |
| Qcache_queries_in_cache | 0         |
| Qcache_total_blocks     | 1         |
+-------------------------+-----------+
8 rows in set
說明:
Qcache_hits:查詢緩存命中次數。
Qcache_inserts:將查詢和結果集寫入到查詢緩存中的次數。
Qcache_not_cached:不可以緩存的查詢次數。
Qcache_queries_in_cache:查詢緩存中緩存的查詢量。

 

查看到緩存命中為0%
 
查看引擎狀態
mysql> show engine innodb status;

 

通過上邊一系列的查詢,發現以下幾個問題
1、慢查詢、全表掃描過多
描述
慢sql:查看到sql語句執行時間過長。
全表掃描:這個策略用於檢查百分比((Handler_read_rnd+Handler_read_rnd_next)/(Handler_read_first+Handler_read_key+Handler_read_next+Handler_read_prev+Handler_read_rnd+Handler_read_rnd_next))。 這是一個需要讀取全表內容的操作,而不是僅讀取使用索引選定的部分。 通常使用小型查找表執行,或者在具有大型表的數據倉庫情況下執行而其中所有可用數據都被聚合和分析。
建議
慢sql:根據sql 檢查語句並進行索引優化。
全表掃描:應該盡量保持這個值盡可能的低。嘗試隔離那些不使用索引的查詢。一旦識別了那些查詢,請創建適當的索引或重寫查詢以使用索引。MySQL 有一個很棒的功能 - 慢速查詢日志,它允許你記錄所有需要超過指定時間運行的查詢。慢速速查詢日志可用於識別需要很長時間才能完成的查詢。
 
2、數據庫最大並發連接數量
描述
當服務器啟動后,(max_used_connections)變量將提供一個基准,以幫助你確定服務器支持的最大連接數量。 它還可以幫助進行流量分析。
建議
如果需要支持更多的連接,應該增加變量 max_connections 的值。MySQL 支持的最大連接數量是取決於給定平台上線程庫的質量、可用 RAM 的數量、每個連接可使用多少 RAM、每個連接的工作負載以及所需的響應時間。
 
3、查詢緩存要配置
緩存描述
這個策略用於檢查查詢緩存命中率(Qcache_hits/(Qcache_hits + Com_select))。 MySQL 查詢緩存將緩存一個分析的查詢及其整個結果集。 當你有許多小型的查詢返回小型數據集時,這是非常好的,因為查詢緩存將允許返回結果立即可供使用,而不是每次發生時都重新運行查詢。
建議
理想情況下,查詢緩存的命中率應該接近 100%。MySQL 的查詢緩存是一項強大的技術,並且在管理良好的情況下可以顯着提高數據庫的吞吐量。一旦你的應用程序被創建,你可以看看它如何使用數據庫,並相應地調整查詢緩存。有足夠大的緩存,避免碎片化和排除大型的查詢,你就應該能夠保持極高的緩存命中率,並享受出色的性能。
 

處理過程

根據上邊發現的問題進行了配置的修改

1、修改慢查詢以及全表掃描

此問題聯系開發進行索引優化,減少全表掃描。

2、數據庫最大連接數量

修改配置 max_user_connections 我這邊設置的為1000

 

3、查詢緩存的配置

參數說明
query_cache_size:分配用於緩存查詢結果的內存量。
query_cache_limit:不要緩存大於此字節數的結果。
query_cache_type:對於查詢結果,不緩存(= OFF),不緩存NO_CACHE(= ON),或僅緩存(= DEMAND)分別用012 表示
 
修改完數據但是需要重啟才能生效。
 

問題解決

正在准備空閑時間重啟RDS的時候,開發那邊有了進展。
開發同事把緩存寫錯了。
理下業務
程序暴露接口給測試部門,測試部門在上報了50W條數據,開發這邊程序有沒有添加數據過濾(過濾掉垃圾數據),並且...開發在程序中寫錯了緩存。所以導致相對於讀取來說寫入較高。因為在緩存查詢不到想到的數據,就進行了全表掃描,繼而出現了大量進程以及連接數隊列等等。。

總結

處理問題可以,別主動背鍋。。。在接手數據庫的時候最好檢查下配置,了解數據庫的情況,在出現問題的時候能夠最快速的定位解決問題。
另外,經過此次的故障處理,加固了對業務以及數據庫一些參數的理解。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM