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

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