MySQL反應慢的排查思路(老葉)


 一、導致MySQL慢可能的因素有
1、計算資源不足
2、系統層面未進行基本的優化,或不同進程間資源搶占
3、MySQL配置不科學(附神器:http://imysql.com/my-cnf-wizard.html)
4、垃圾SQL滿天飛

二、查看系統層面負載手段
1、top查看整體負載情況,快速確認哪個進程系負載高
VIRT:virtual memory usage 虛擬內存
1、進程“需要的”虛擬內存大小,包括進程使用的庫、代碼、數據等
2、假如進程申請100m的內存,但實際只使用了10m,那么它會增長100m,而不是實際的使用量

RES:resident memory usage 常駐內存
1、進程當前使用的內存大小,但不包括swap out
2、包含其他進程的共享
3、如果申請100m的內存,實際使用10m,它只增長10m,與VIRT相反
4、關於庫占用內存的情況,它只統計加載的庫文件所占內存大小

SHR:shared memory 共享內存
1、除了自身進程的共享內存,也包括其他進程的共享內存
2、雖然進程只使用了幾個共享庫的函數,但它包含了整個共享庫的大小
3、計算某個進程所占的物理內存大小公式:RES – SHR
4、swap out后,它將會降下來

2、free查看內存情況,是否有內存泄露和用了swap等風險

3、vmstat/sar查看當前系統瓶頸到底在哪,如CPU、IO、網絡等
# sudo vmstat 1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0  95740 136752 729052    0    0     0     4    8    4  0  0 100  0  0
 0  0      0  95740 136752 729088    0    0     0     0  353 1038  1  0 99  0  0
 0  0      0  95740 136752 729088    0    0     0     0  332 1016  1  1 98  0  0
 0  0      0  95740 136752 729088    0    0     0     0  329  993  0  0 100  0  0
 0  0      0  95616 136752 729088    0    0     0     0  345 1036  1  0 99  0  0
 3  0      0  95616 136752 729088    0    0     0    68  340 1012  0  1 99  0  0

sar使用具體參考:https://www.cnblogs.com/howhy/p/6396437.html

sar -d 輸出每一塊磁盤的使用信息(-p 顯示驅動器名稱)

$ sar -d -p 1 10
Linux 2.6.32-279.el6.x86_64 (GD6-DB-049-db-mysql.idc.vipshop.com)       04/21/2019      _x86_64_        (32 CPU)

02:02:09 PM       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util
02:02:10 PM       sda      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
02:02:10 PM       sdb   1129.59     65.31  18375.51     16.33      0.11      0.09      0.06      6.73

02:02:10 PM       DEV       tps  rd_sec/s  wr_sec/s  avgrq-sz  avgqu-sz     await     svctm     %util
02:02:11 PM       sda      0.00      0.00      0.00      0.00      0.00      0.00      0.00      0.00
02:02:11 PM       sdb   1375.51     16.33  20628.57     15.01      0.08      0.06      0.05      7.24

sar -u 統計CPU的使用情況

# sar -u 1 10  
Linux 3.10.0-514.26.2.el7.x86_64 (izuf60bp6kd88idp0no1urz)      04/17/2019      _x86_64_        (1 CPU)

08:49:16 PM     CPU     %user     %nice   %system   %iowait    %steal     %idle
08:49:17 PM     all      1.00      0.00      0.00      0.00      0.00     99.00
08:49:18 PM     all      0.00      0.00      1.01      0.00      0.00     98.99

sar -n 查看網卡信息

DEV顯示網絡接口信息

EDEV顯示關於網絡錯誤的統計數據

NFS統計活動的NFS客戶端的信息

NFSD統計NFS服務器的信息

SOCK顯示套接字信息

ALL顯示所有5個開關。它們可以單獨或者一起使用。

# sar -n DEV 1 10   
Linux 3.10.0-514.26.2.el7.x86_64 (izuf60bp6kd88idp0no1urz)      04/17/2019      _x86_64_        (1 CPU)

09:11:55 PM     IFACE   rxpck/s   txpck/s    rxkB/s    txkB/s   rxcmp/s   txcmp/s  rxmcst/s
09:11:56 PM      eth0      1.00      1.00      0.06      0.15      0.00      0.00      0.00
09:11:56 PM        lo     18.00     18.00      4.43      4.43      0.00      0.00      0.00

IFACE 本地網卡接口的名稱

rxpck/s 每秒鍾接受的數據包

txpck/s 每秒鍾發送的數據庫

rxKB/S 每秒鍾接受的數據包大小,單位為KB

txKB/S 每秒鍾發送的數據包大小,單位為KB

rxcmp/s 每秒鍾接受的壓縮數據包

txcmp/s 每秒鍾發送的壓縮包

rxmcst/s 每秒鍾接收的多播數據包    

其他略,具體參考
4、終極神器perf top查看cpu消耗在哪些系統調用函數
Linux 性能優化工具 perf top  
參考: https://www.cnblogs.com/digdeep/p/4896235.html
案例: http://blog.chinaunix.net/uid-20785090-id-4282589.html
perf top -e xxx 
1) perf top -e cpu-clock: 查看CPU的使用

2)perf top -e faults : 查看 page faults

3)perf top -e block:block_rq_issue : 查看系統IO的請求,比如可以在發現系統IO異常時,可以使用該命令進行調查,就能指定到底是什么原因導致的IO異常。 block_rq_issue 表示 block_request_issue 就是IO請求數。其實從這些可以看出,分析和調查Linux上的各種性能問題,需要我們對Linux內核有比較多的了解,不然恐怕是無從下手的。


三、查看MySQL的整體情況
1、觀察show processlist輸出中是否有臨時表、排序、大量邏輯讀、鎖等待等狀態
檢查事務鎖
-- mysql 5.6
information_schema 簡稱I_S
innodb_trx
innodb_locks
innodb_lock_waits

SELECT  lw.requesting_trx_id AS request_XID, trx.trx_mysql_thread_id as request_mysql_PID
, trx.trx_query AS request_query,  lw.blocking_trx_id AS blocking_XID
, trx1.trx_mysql_thread_id as blocking_mysql_PID, trx1.trx_query AS blocking_query
, lo.lock_index AS lock_index 
FROM     information_schema.innodb_lock_waits lw 
INNER JOIN information_schema.innodb_locks lo ON lw.requesting_trx_id = lo.lock_trx_id 
INNER JOIN information_schema.innodb_locks lo1 ON lw.blocking_trx_id = lo1.lock_trx_id 
INNER JOIN information_schema.innodb_trx trx ON lo.lock_trx_id = trx.trx_id 
INNER JOIN information_schema.innodb_trx trx1 ON lo1.lock_trx_id = trx1.trx_id limit 100 ;

2、觀察show engine innodb status輸出中是否有大事務、長事務、鎖等待等狀態


四、干掉垃圾SQL,常用手段
1、用explain、desc觀察執行計划
2、用profiling定位sql執行的瓶頸
set profiling=1; //打開分析 
run your sql1; 
run your sql2; 
show profiles;    //查看sql1,sql2的語句分析 
show profile for query 1;    //查看sql1的具體分析 
show profile ALL for query 1;    //查看sql1相關的所有分析【主要看i/o與cpu,下邊分析中有各項意義介紹】
set profiling=0;
SHOW profile CPU,BLOCK IO io FOR query 1;

3、用pt-query-digest分析慢sql

pt-query-digest --user=root --password=admin /home/data/slowlog/slow.log

 樣例:

slow log 分析:
報告最近半個小時的慢查詢:
./pt-query-digest --report --since 1800s /var/lib/mysql/slow.log
報告一個時間段的慢查詢:
./pt-query-digest --report --since '2014-12-30 14:50:00' --until '2014-12-30 14:59:59' /var/lib/mysql/slow.log
報告只含select語句的慢查詢:
./pt-query-digest --filter '$event->{fingerprint} =~ m/^select/i' /var/lib/mysql/slow.log
報告針對某個用戶的慢查詢:
./pt-query-digest --filter '($event->{user} || "") =~ m/^dbapp/i' /var/lib/mysql/slow.log
報告所有的全表掃描或full join的慢查詢:
./pt-query-digest --filter '(($event->{Full_scan} || "") eq "yes") || (($event->{Full_join} || "") eq "yes")' slow.log
把查詢保存到query_review表
./pt-query-digest  --user=root –password=abc123 --review  h=localhost,D=test,t=query_review--create-review-table  slow.log
把查詢保存到query_history表
./pt-query-digest  --user=root –password=abc123 --review  h=localhost,D=test,t=query_ history--create-review-table  slow.log_20140401
./pt-query-digest  --user=root –password=abc123--review  h=localhost,D=test,t=query_history--create-review-table  slow.log_20140402
通過tcpdump抓取mysql的tcp協議數據,然后再分析
tcpdump -s 65535 -x -nn -q -tttt -i any -c 1000 port 3306 > mysql.tcp.txt
./pt-query-digest --type tcpdump mysql.tcp.txt> slow_report9.log
分析binlog
mysqlbinlog mysql-bin.000093 > mysql-bin000093.sql
./pt-query-digest  --type=binlog  mysql-bin000093.sql > slow_report10.log
分析general log
./pt-query-digest  --type=genlog  localhost.log > slow_report11.log

 

五、幾個竅門

1、mysqld進程消耗CPU長時間超過90%的話,99.9%是因為沒用好索引
2、cpu的%sys高的話,大概率是swap或中斷不均衡導致,也可能是有多個索引且超高並發寫入(更新),或者有很嚴重的鎖等待事件
3、最大的瓶頸通常是在磁盤I/O上,因此盡量用高速磁盤設備
4、如果物理磁盤無法再升級,則通過增加內存提升性能容量
5、遇到無法診斷的問題時,試試perf top來觀測跟蹤
6、SQL執行慢,有時未必是效率低,也可能是因為鎖等待,甚至是磁盤滿了

詳情戳:https://ke.qq.com/course/392646


免責聲明!

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



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