(12)Cannot allocate memory: fork: Unable to fork new process が出たので調査を開始


(12)Cannot allocate memory: fork: Unable to fork new process が出たので調査を開始 | Bamboo lath 日々の記録やったことのメモ。

(12)Cannot allocate memory: fork: Unable to fork new process
が発生したので調査のためにスクリプトを追加。

発生までの経緯をみるとどうもswapが徐々に喰いつぶされていき、swapが無くなると
上記のエラーが発生しているような感じ。

徐々にといっても何らかのタイミングでガクンとswapが減るのでそれをどうにか
突き止めたい。。。

いろいろ調べて以下のページを参考にしてスクリプトを作成(そのまま)

Find Out What Is Using Your Swap
http://northernmost.org/blog/find-out-what-is-using-your-swap/
/proc/以下のプロセスのフォルダ内のsmaps内をさらって合計していく感じ。

■getswap.sh

    #!/bin/bash
    # Get current swap usage for all running processes
    # Erik Ljungstrom 27/05/2011
    SUM=0
    OVERALL=0
    for DIR in `find /proc/ -maxdepth 1 -type d | egrep "^/proc/[0-9]"` ; do
            PID=`echo $DIR | cut -d / -f 3`
            PROGNAME=`ps -p $PID -o comm --no-headers`
            for SWAP in `grep Swap $DIR/smaps 2>/dev/null| awk '{ print $2 }'`
            do
                    let SUM=$SUM+$SWAP
            done
            echo "PID=$PID - Swap used: $SUM - ($PROGNAME )"
            let OVERALL=$OVERALL+$SUM
            SUM=0

    done
    echo "Overall swap used: $OVERALL"

■cronswap.sh
クーロンで叩く用。

    #!/bin/bash
    FILENAME=`date +"%Y%m%d_%H%M%S"`
    echo "${FILENAME}"
    /root/swapLog/getswap.sh  | egrep -v "Swap used: 0" |sort -n -k 5 > /root/swapLog/log/"${FILENAME}".log

■logs
このフォルダに日時の形式で出力

■cronの設定
1ファイル2KB程度なのでとりあえずとりっぱなしで。10分毎。

    #swaplog
    */10 * * * * /root/swapLog/cronswap.sh

■設置時のswap出力例
swapを使ってるプロセスが表示される。

    $ less 20150914_162958.log 
    Overall swap used: 123388                                                                                                                                                                                                                    
    PID=1840 - Swap used: 28 - (syslogd )
    PID=2245 - Swap used: 28 - (saslauthd )
    PID=2247 - Swap used: 28 - (saslauthd )
    PID=2248 - Swap used: 28 - (saslauthd )
    PID=2244 - Swap used: 32 - (saslauthd )
    PID=2246 - Swap used: 32 - (saslauthd )
    PID=1843 - Swap used: 44 - (klogd )
    PID=2328 - Swap used: 48 - (mingetty )
    PID=2323 - Swap used: 52 - (mingetty )
    PID=2332 - Swap used: 52 - (mingetty )
    PID=2307 - Swap used: 56 - (gam_server )
    PID=2324 - Swap used: 56 - (mingetty )
    PID=2330 - Swap used: 56 - (mingetty )
    PID=2329 - Swap used: 60 - (mingetty )
    PID=1 - Swap used: 64 - (init )
    ・・・・
    PID=2274 - Swap used: 148 - (hald-runner )
    PID=9940 - Swap used: 148 - (pop3-login )
    PID=2054 - Swap used: 152 - (mysqld_safe )
    PID=2017 - Swap used: 224 - (vsftpd )
    PID=496 - Swap used: 260 - (udevd )
    PID=1962 - Swap used: 304 - (sshd )
    PID=1901 - Swap used: 448 - (3dm2 )
    PID=1914 - Swap used: 448 - (3dm2 )
    PID=1915 - Swap used: 448 - (3dm2 )
    PID=2273 - Swap used: 1900 - (hald )
    PID=2320 - Swap used: 7172 - (miniserv.pl )
    PID=1804 - Swap used: 7468 - (miniserv.pl )
    PID=17177 - Swap used: 7736 - (spamd )
    PID=17197 - Swap used: 8364 - (spamd )
    PID=2303 - Swap used: 10060 - (yum-updatesd )
    PID=2158 - Swap used: 24512 - (spamd )
    PID=2101 - Swap used: 44588 - (mysqld )

あと合わせてsarコマンドも設定

参考
http://blog.ybbo.net/2013/07/10/oom-killer%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6/
http://b.l0g.jp/dev/finding-bottleneck-with-sar1/
http://b.l0g.jp/dev/finding-bottleneck-with-sar2/

pstreeも確認するようにする。

$ pstree -lcph

http://itpro.nikkeibp.co.jp/article/COLUMN/20071204/288730/

またアクセスログの記録と対応するようにApacheのaccess_logの先頭にPIDを表示するように設定を変更した。
「%P」はPIDを出力する。先頭に追加。
これでswapを確保したままになっているのがhttpのプロセスだった場合にどのアクセスと対応しているのか
がわかるはず。

    $ diff httpd.conf httpd.conf_back20150914 
    485,486c485,486
    < LogFormat "%P %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    < LogFormat "%P %h %l %u %t \"%r\" %>s %b" common
    ---
    > LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
    > LogFormat "%h %l %u %t \"%r\" %>s %b" common

再起動必須。

実際「Cannot allocate memory」が出て已む無くapacheをリスタートしようと
したのに起動に失敗したときの対応は以下。

#service httpd restart
失敗した!
#/usr/sbin/lsof -i | grep http
開いているファイルのプロセスを特定
#kill-9 プロセスID
そのほかのプロセスも殺す。
#service httpd start

後はswapの残りを監視してアラート飛ばすのを作る予定。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です