天天看點

linux下性能分析方法執行個體

比較老了~不過可以學習學習分析過程~~

某一天,一個客戶打電話來需要技術幫助,并抱怨平常15秒就可以打開的網頁現在需要20分鐘才可以打開.

具體系統配置如下:

redhat enterprise linux 3 update 7

dell 1850 dual core xenon processors, 2 gb ram, 75gb 15k drives

custom lamp software stack(譯注:llinux+apache+mysql+php

環境)

性能分析之步驟

1.

首先使用vmstat 檢視大緻的系統性能情況:

# vmstat 1 10

procs memory swap io system cpu

r b swpd free buff cache si so bi bo in cs us sy id wa

1 0 249844 19144 18532 1221212 0 0 7 3 22 17 25 8 17 18

0 1 249844 17828 18528 1222696 0 0 40448 8 1384 1138 13 7 65 14

0 1 249844 18004 18528 1222756 0 0 13568 4 623 534 3 4 56 37

2 0 249844 17840 18528 1223200 0 0 35200 0 1285 1017 17 7 56 20

1 0 249844 22488 18528 1218608 0 0 38656 0 1294 1034 17 7 58 18

0 1 249844 21228 18544 1219908 0 0 13696 484 609 559 5 3 54 38

0 1 249844 17752 18544 1223376 0 0 36224 4 1469 1035 10 6 67 17

1 1 249844 17856 18544 1208520 0 0 28724 0 950 941 33 12 49 7

1 0 249844 17748 18544 1222468 0 0 40968 8 1266 1164 17 9 59 16

1 0 249844 17912 18544 1222572 0 0 41344 12 1237 1080 13 8 65 13

分析:

1,不會是記憶體不足導緻,因為swapping

始終沒變化(si 和 so).盡管空閑記憶體不多(free),但swpd

也沒有變化.

2,cpu

方面也沒有太大問題,盡管有一些運作隊列(procs r),但處理器還始終有50%

多的idle(cpu id).

3,有太多的上下文切換(cs)以及disk

block從ram中被讀入(bo).

4,cpu

還有平均20% 的i/o

等待情況.

結論:

從以上總結出,這是一個i/o

瓶頸.

2.

然後使用iostat 檢查是誰在發出io

請求:

# iostat -x 1

linux 2.4.21-40.elsmp (mail.example.com) 03/26/2007

avg-cpu: %user %nice %sys %idle

30.00 0.00 9.33 60.67

device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkb/s wkb/s avgrq-sz avgqu-sz await svctm %util

/dev/sda 7929.01 30.34 1180.91 14.23 7929.01 357.84 3964.50 178.92 6.93 0.39 0.03 0.06 6.69

/dev/sda1 2.67 5.46 0.40 1.76 24.62 57.77 12.31 28.88 38.11 0.06 2.78 1.77 0.38

/dev/sda2 0.00 0.30 0.07 0.02 0.57 2.57 0.29 1.28 32.86 0.00 3.81 2.64 0.03

/dev/sda3 7929.01 24.58 1180.44 12.45 7929.01 297.50 3964.50 148.75 6.90 0.32 0.03 0.06 6.68

9.50 0.00 10.68 79.82

/dev/sda 0.00 0.00 1195.24 0.00 0.00 0.00 0.00 0.00 0.00 43.69 3.60 0.99 117.86

/dev/sda1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

/dev/sda2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

/dev/sda3 0.00 0.00 1195.24 0.00 0.00 0.00 0.00 0.00 0.00 43.69 3.60 0.99 117.86

9.23 0.00 10.55 79.22

/dev/sda 0.00 0.00 1200.37 0.00 0.00 0.00 0.00 0.00 0.00 41.65 2.12 0.99 112.51

/dev/sda3 0.00 0.00 1200.37 0.00 0.00 0.00 0.00 0.00 0.00 41.65 2.12 0.99 112.51

1,看上去隻有/dev/sda3

分區很活躍,其他分區都很空閑.

2,差不多有1200

讀iops,磁盤本身是支援200 iops左右(譯注:參考之前的iops

計算公式).

3,有超過2秒,實際上沒有一個讀磁盤(rkb/s).這和在vmstat

看到有大量i/o wait是有關系的.

4,大量的read iops(r/s)和在vmstat

中大量的上下文是比對的.這說明很多讀操作都是失敗的.

從以上總結出,部分應用程式帶來的讀請求,已經超出了i/o

子系統可處理的範圍.

3.

使用top 來查找系統最活躍的應用程式

# top -d 1

11:46:11 up 3 days, 19:13, 1 user, load average: 1.72, 1.87, 1.80

176 processes: 174 sleeping, 2 running, 0 zombie, 0 stopped

cpu states: cpu user nice system irq softirq iowait idle

total 12.8% 0.0% 4.6% 0.2% 0.2% 18.7% 63.2%

cpu00 23.3% 0.0% 7.7% 0.0% 0.0% 36.8% 32.0%

cpu01 28.4% 0.0% 10.7% 0.0% 0.0% 38.2% 22.5%

cpu02 0.0% 0.0% 0.0% 0.9% 0.9% 0.0% 98.0%

cpu03 0.0% 0.0% 0.0% 0.0% 0.0% 0.0% 100.0%

mem: 2055244k av, 2032692k used, 22552k free, 0k shrd, 18256k buff

1216212k actv, 513216k in_d, 25520k in_c

swap: 4192956k av, 249844k used, 3943112k free 1218304k cached

pid user pr ni virt res shr s %cpu %mem time+ command

14939 mysql 25 0 379m 224m 1117 r 38.2 25.7% 15:17.78 mysqld

4023 root 15 0 2120 972 784 r 2.0 0.3 0:00.06 top

1 root 15 0 2008 688 592 s 0.0 0.2 0:01.30 init

2 root 34 19 0 0 0 s 0.0 0.0 0:22.59 ksoftirqd/0

3 root rt 0 0 0 0 s 0.0 0.0 0:00.00 watchdog/0

4 root 10 -5 0 0 0 s 0.0 0.0 0:00.05 events/0

1,占用資源最多的好像就是mysql

程序,其他都處于完全idle

狀态.

2,在top(wa)

看到的數值,和在vmstat

看到的wio 數值是有關聯的.

從以上總結出,似乎就隻有mysql

程序在請求資源,是以可以推論它就是導緻問題的關鍵.

4.

現在已經确定是mysql 在發出讀請求,使用strace

來檢查它在讀請求什麼.

# strace -p 14939

process 14939 attached - interrupt to quit

read(29, "/3/1/237/1/366/337/1/222%/4/2/0/0/0/0/0012p/d", 20) = 20

read(29, "ata1/strongmail/log/strongmail-d"..., 399) = 399

_llseek(29, 2877621036, [2877621036], seek_set) = 0

read(29, "/1/1/241/366/337/1/223%/4/2/0/0/0/0/0012p/da", 20) = 20

read(29, "ta1/strongmail/log/strongmail-de"..., 400) = 400

_llseek(29, 2877621456, [2877621456], seek_set) = 0

read(29, "/1/1/235/366/337/1/224%/4/2/0/0/0/0/0012p/da", 20) = 20

read(29, "ta1/strongmail/log/strongmail-de"..., 396) = 396

_llseek(29, 2877621872, [2877621872], seek_set) = 0

read(29, "/1/1/245/366/337/1/225%/4/2/0/0/0/0/0012p/da", 20) = 20

read(29, "ta1/strongmail/log/strongmail-de"..., 404) = 404

_llseek(29, 2877622296, [2877622296], seek_set) = 0

read(29, "/3/1/236/2/366/337/1/226%/4/2/0/0/0/0/0012p/d", 20) = 20

1,大量的讀操作都在不斷尋道中,說明mysql

程序産生的是随機io.

2,看上去似乎是,某一sql

查詢導緻讀操作.

從以上總結出,所有的讀iops

都是mysql 程序在執行某些讀查詢時産生的.

5.

使用mysqladmin 指令,來查找是哪個慢查詢導緻的.

# ./mysqladmin -pstrongmail processlist

+----+------+-----------+------------+---------+------+----------+----------------------------------------

| id | user | host | db | command | time | state | info

| 1 | root | localhost | strongmail | sleep | 10 | |

| 2 | root | localhost | strongmail | sleep | 8 | |

| 3 | root | localhost | root | query | 94 | updating | update `failures` set

`update_datasource`='y' where database_id='32' and update_datasource='n' and |

| 14 | root | localhost | | query | 0 | | show processlist

1,mysql

資料庫裡,似乎在不斷的運作table update查詢.

2,基于這個update

查詢,資料庫是對所有的table

進行索引.

從以上總結出,mysql裡這些update

查詢問題,都是在嘗試對所有table

進行索引.這些産生的讀請求正是導緻系統性能下降的原因.

後續

把以上這些性能資訊移交給了相關開發人員,用于分析他們的php

代碼.一個開發人員對代碼進行了臨時性優化.某個查詢如果出錯了,也最多到100k記錄.資料庫本身考慮最多存在4百萬記錄.最後,這個查詢不會再給資料庫帶來負擔了.