SWAPを使用しているプロセストップ10を表示する

なんかしらんけどSWAPがたくさん

どうも、やまもとやまです。
サーバーリソースのモニタリングをしていると、ときどきやたらとSWAPを使用しているサーバー、ありますよね?
SWAPが増える原因は様々ですが、あまりに使用している場合、まずは何が使っているか特定する必要があります。
というわけで、使用量の多いプロセストップ10を表示してみましょう。
※使用シェルはbashとします

特定方法

SWAPってpsコマンドでは出てこないし、どこを見れば使用量が分かるでしょうか?
実は、/proc 配下のプロセス情報(/proc/[プロセスID]/status)で確認することができます。
※このプロセス情報では、SWAP以外にもプロセスの各種情報を確認できます

例えば、あるサーバーのMySQL(MariaDB)の場合ですが、

$ ps -ef | grep mysql |grep -v grep
mysql     18653      1  0 May11 ?       00:00:00 /bin/sh /usr/bin/mysqld_safe --basedir=/usr
mysql     18852  18653 11 May11 ?     8-16:54:35 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --plugin-dir=/usr/lib64/mysql/plugin --log-error=/var/log/mariadb/mariadb.log --pid-file=/var/run/mariadb/mariadb.pid --socket=/var/lib/mysql/mysql.sock

$ grep VmSwap /proc/18852/status
VmSwap: 3020208 kB

こんな感じで確認できます。
どうやら、SWAPを約3GB使用しているようですね。
ということは、全プロセスをワイルドカードで指定してやってソートすればトップ10が表示できそです。

$ grep VmSwap /proc/*/status | sort -nr -k 2 | head -10
/proc/18852/status:VmSwap:       3015804 kB
/proc/30538/status:VmSwap:        808796 kB
/proc/14284/status:VmSwap:        489768 kB
/proc/2908/status:VmSwap:         177816 kB
/proc/29312/status:VmSwap:         48316 kB
/proc/10752/status:VmSwap:         36116 kB
/proc/10707/status:VmSwap:         35944 kB
/proc/12003/status:VmSwap:         35508 kB
/proc/11068/status:VmSwap:         35360 kB
/proc/11109/status:VmSwap:         35340 kB

無事表示できました!
なお、sortコマンドのオプションでは、-kでソートキーを指定し、-rで降順、-nで文字列を数値として扱っています。

しかし、これ、何か物足りない。プロセス名くらいは表示されて欲しいところです。

先ほどの結果をforで順次処理してやればできそうですが、bashでは通常スペースやタブも区切り文字(デリミタ)になってしまい、そのままでは意図した処理となりません。
そこで、以下のsedで不要なスペースとタブを除去し、ついでに表示不要な文字列も削除します。

sed s/"\s"//g
sed s/status:VmSwap://g

次にスラッシュ(/)区切りに対応するため、以下のようにスラッシュをスペースに変換してやれば、各項目を変数配列へ組み込めます。

spline=(${line//\// })

最後に、/proc/[プロセスID]/status からプロセス名を抜き出し、整形して表示すれば完成です。

$ for line in `grep VmSwap /proc/*/status | sort -nr -k 2 | head -10| sed s/"\s"//g | sed s/status:VmSwap://g`; do spline=(${line//\// }); procname=`grep Name /proc/${spline[1]}/status|sed '/^$/d'`; echo -e "PID: ${spline[1]}\t${procname}\t${spline[2]}"; done
PID: 18852      Name:   mysqld  2858292kB
PID: 30538      Name:   kavscanner      808816kB
PID: 14284      Name:   kavscanner      489768kB
PID: 2908       Name:   named   179252kB
PID: 29312      Name:   /usr/bin/spamd  51332kB
PID: 10752      Name:   /usr/sbin/httpd 36772kB
PID: 10707      Name:   /usr/sbin/httpd 36632kB
PID: 9390       Name:   /usr/sbin/httpd 36228kB
PID: 9420       Name:   /usr/sbin/httpd 36176kB
PID: 9419       Name:   /usr/sbin/httpd 36152kB

できましたね!
ちょっと(ちょっと?)不格好ですが、欲しい情報は取り出せたのでまあOKとしましょう。
しかしこれ、もう少しうまく書けそうな気もする。。。

とりえあずできた

サーバー運用で必要になる(かもしれない)SWAP使用の多いプロセストップ10をワンライナーで表示することができました。
とはいえ、これをそらで手書きするときっとどこかで間違えるような気がしなくもないので、何かしらのスクリプトにする(ついでにもう少しきれいに整形する)方が良さそうですね。
それではまた!