Linux

障害対応でよくつかうコマンド覚書(逐次更新)

More than 1 year has passed since last update.

はじめに

よく障害対応の際につかうコマンドの見方を自分でまとめていたものを一般公開してみる。
詳細についてはここを参考にせずにちゃんとmanをよみましょう!

w

ヘッダ部

  • 現在の時刻
  • Uptime(システムが稼働している期間)
  • 現在ログインしているユーザーの数
  • 過去1,5,15minでのシステムのロードアベレージ

Uptimeが短いと再起動した。

また、ロードアベレージの1が高く5,14が低いなら直近、
全部が高いなら継続、
1が低く他が高いならすでに問題が解消した可能性が高い。

下部

  • USER :ユーザ名
  • TTY :
  • FROM :アクセス元
  • LOGIN:ログイン時間
  • IDLE :アイドル(現在時間-最後にttyにアクセスした時間)している時間
  • JCPU :そのttyから実行されている全プロセスが使った時間。これには 過去のバックグラウンドジョブは含まれないが、現在実行しているバックグラウンドジョブは含まれる。
  • PCPU :"what" 項目で示されているカレントプロセスが使っている時間。 -WHAT :実行されているカレントプロセス

ログイン時間とアイドル時間を確認してアラート直前にログインがあったか?(作業の可能性)やアイドル時間が短くないかを確認。

last

ログイン履歴を見ることができる。
不審なユーザがさっきまでうごいてたっぽいけど現在見つからないなどの時に。
また、IPでgrepして過去にログインがあったか(=不審ではないか)みたいな使い方も。
結構長く表示されるのでlessやheadに渡して見るとよい。
/var/log/wtmpからデータを読み取っているのでこれが改ざんされた場合は不正ログイン等を検出できないので注意。

ps

基本的に

ps auxf

を利用する。
ここでオプションの意味は

  • a tty端末を持つすべてのプロセスを表示する(xと組み合わせて全プロセス)
  • u RUID(実ユーザID)ではなく、ユーザ名で表示する
  • x tty端末を持たないプロセスも表示する(aと組み合わせて全プロセス)
  • f プロセスの親子関係をツリー状にして表示する

となっている。
注目すべきポイントはツリーが伸びているところ(プロセスを多く生成していたり,cronで起動されていないかを確認できる。
また、多数のプロセスが起動されている場合だれが起動したのかを確認する。
アラート付近で上がったプロセスは要注意。
出力のCPU使用率は算出方法があれなので正しい値が表示されない(直近に立ち上がったものほど過大評価)

ps --sort <フォーマット指定子>

を使えばソートできる。
便利そうなのが

ps --sort -%mem

また

ps auxfww

とすることで切れることなく折り返して表示してくれる。(ps auxfよりこっちのほうがよくつかうかもしれない?)

  • VSZ プロセスの仮想メモリサイズ (KiB, 1024 バイト単位) 起動したらとりあえず確保される
  • RSS 常駐セットの大きさ。 タスクが使用しているスワップされていない物理メモリ (kB 単位)

STAT

プロセス状態を表す

  • D 割り込み不可能なスリープ状態 (通常 IO 中)
  • R 実行中または実行可能状態 (実行キューにある)
  • S 割り込み可能なスリープ状態 (スリープやユーザからの入力待ちなどイベントの完了を待っている)
  • T ジョブ制御シグナルまたはトレースされているために停止中の状態
  • W ページング状態 (2.6.xx カーネルからは無効)
  • X 死んだ状態 (見えるべきではない)
  • Z 終了したが、親プロセスによって回収されなかった、消滅したプロセス。いわゆるゾンビ。

BSD 形式で stat キーワードが用いられたときは、 以下の添付文字が表示されることがある。

  • < 優先度の高いプロセス (他のユーザーに対して良くない)
  • N 優先度の低いプロセス (他のユーザーに対して良い)
  • L 実メモリのページをロックして利用している (リアルタイム処理やカスタム IO 向け)
  • s セッションリーダ
  • l マルチスレッド化されている (NPTL pthreads が行うように、CLONE_THREAD が使われている)
  • + フォアグラウンドのプロセスグループに含まれている

Dステータス、Zステータスのものはよく確認することがおおい?

  • START
    プロセスの開始時間

  • TIME
    プロセスの総実行時間

  • COMMAND
    実行しているコマンド

netstat

ネットワークの状態を調査するのに利用する。(CentOS7より非推奨になり基本的にssコマンドを使うべき)
rootでないとすべての情報をみることができない。

netstat -antp

ここでオプションの意味は

  • a 接続待ちもそうでないのも表示する
  • t tcpに限定して表示
  • n 名前解決しない
  • p ソケットが所属しているプログラムとPIDを表示

となっている。

出力としては
内部アドレス(Local Adress)の部分で自分のIPアドレスと開いているポート、
外部アドレス(Foreign Adress)の部分で相手のIPアドレスと接続しているポート
をみることができる。
状態(State)の部分ではその接続状態を知ることができる。(詳細は後述)
PID/Program nameではその接続を利用しているプログラムとそのプロセスIDが表示される。

基本的に出力が多いので全体見た後

netstat -antp|grep :<サービスのポート>

と使うことが多い気がする。

State詳細

接続をつないだり、切ったりするときの状態に対応していて以下のようなものが存在する。

  • ESTABLISHED ソケットは確立した接続状態にある。
  • SYN_SENT ソケットは接続を確立しようと試みている。
  • SYN_RECV 接続要求をネットワークから受信している。
  • FIN_WAIT1 ソケットはクローズされており、接続は切断中である。
  • FIN_WAIT2 接続はクローズされ、ソケットはリモート側からの切断を待っている。
  • TIME_WAIT ソケットは、クローズ後にリモートからの切断が再送されるのを待っている。
  • CLOSED ソケットは使用されていない。
  • CLOSE_WAIT リモート側は既に切断され、ソケットがクローズされるのを待っている。
  • LAST_ACK リモート側は既に切断され、ソケットもクローズされている。 確認 (acknowledgement) を待っている。
  • LISTEN ソケットは接続待ち (listen) である。
  • CLOSING 両方のソケットが切断されているが、まだ全てのデータが送られていない。
  • UNKNOWN ソケットの状態は不明である。

具体的には以下のような状態を反映する。

I. 接続する

  1. A,BともにCLOSEDの状態からAがBにつなげる
  2. AからBに接続要求としてSYNパケットを送信(この時点でAはSYN_SENTになる)
  3. BがAからのSYNパケットを受信(BはSYN_RECVになる)
  4. Bが受信完了およびAと接続を確立するためにACK,SYNパケットを送信
  5. AはACKパケットを受け取り(AはESTABLISHEDになる)BにACKパケットを送信
  6. BはACKパケットを受け取る(BはESTABLISHEDになる)
  7. 接続が両方向に確立

II. 接続を切断する場合

  1. AがBに,FINパケットを送信(AはFIN_WAIT1となる)
  2. AがBにACK,FINパケットを送信しソケットを閉じる(AはFIN_WAIT1となる)
  3. Bがパケットを受け取り(CLOSE_WAITとなる)ACKパケットをAに送信する
  4. AがACKパケットをうけとる(AはFIN_WAIT2となる)
  5. もう一度BからFINパケットが送られる(BはLAST_ACKとなる)
  6. AはFINパケットを受け取り(AはTIME_WAITとなる)、BにACKを送る
  7. BはACKを受け取りCLOSEになる。
  8. Aは一定時間後CLOSEになる

またLISTENになっているものは、ポートは開いているものの接続が確立していないものを表す。

df

ファイルシステムのディスク容量の使用状況を表示する

df -h

とする。
ここで-hオプションは人間が読みやすいような書式で表示する。
また、

df -ih

とすればinodeの使用率を見ることができる。

※inode ファイルに付けられるメタ情報
「データの検索」「読み込み」「書き込み」
足りなくなると空き容量があってもファイルが作れなくなる。

※tmpfs
あたかもディスクのように扱われているメモリ領域。
デフォルトでは/dev/shmに割り当てられている

du

du -scm *

で現在いるディレクトリ以下の容量をMB単位で計算できる。
duコマンドは負荷が高いので通常

ionice -c2 -n7 nice -n19 du -scm *

としたほうがよい。
また、容量の大きいディスクだとかなり時間かかるのでできるかぎり--exclude

基本的にduでは隠しファイル(.から始めるファイル)は集計されないので注意
隠しファイルまで集計する場合は下記

du -scm <対象ディレクトリ>/* <対象ディレクトリ>/.[^.]* | sort -rn

find

いろいろファイルを検索できる。

duとくみあわせて条件に合致するファイルの容量を調べる場合

find <対象ディレクトリ>/* -mtime -15 -exec du -sm {} \;|awk '{sum += $1;print $1,$2}END{print sum,"total"}'

free

メモリの状況を確認する。

free -m

基本的に-/+ buffers/cache:を見る。
(ディスクアクセスを減らすため、できる限りメモリにキャッシュしようとする。
この領域は基本的に開放しようと思えばいつでもできる(例外はあるが)ため
単にfreeな領域だけを見るのはナンセンス)

※buffers
ファイルバッファはメモリ上に設定された、プログラムとファイルの間で一時的にデータを蓄える
場所。プログラムからファイルにデータを出力する、あるいはファイルからプログラムにデータ
を読み込む場合には、必ずいったんファイルバッファを仲介する。

より詳しい情報が欲しい場合は/proc/meminfoなどを見る。

vmstat

vmstat 1 -w

として時間的な流れを追う。

procs

  • r: 実行待ちプロセス rのプロセス数が CPU の数より大きい場合, 実行可能プロセスが CPU 待ちをしている状態にある
  • b: 割り込み不可能なスリープ状態にあるプロセス数 つまり、I/O待ちプロセス

rがコア数より多い場合は注意する。(流れているのか滞っているのか?)

memory

  • swpd swapの使用量
  • free 空きメモリ
  • inact ページキャッシュや無名ページのうち、最後にアクセスされてからある程度時間がたち、ストレージとの同期も完了していて、すぐに捨てられるページ
  • active ページキャッシュや無名ページのうち、最近利用したり、まだストレージとの同期が取れていない「捨てられない」ページ

swap

  • si: ディスクからスワップイン(※1)されているメモリの量 (/s)。
  • so: ディスクにスワップアウト(※2)しているメモリの量 (/s)。

Swap関連のアラートが出た際freeでは静的な情報しか得られない。
Swapがどう動いているかかを確認するためにはこちらが有効。
またロードが高いけどtopとかのCPU使用率の特に高いプロセスがなく、
IO待ちプロセスが多いみたいな状況の場合この値を見ると頻繁にSwap in/outが発生していたりする。

※1 スワップイン:スワップ領域から実メモリにデータを差し戻す(メモリにはいる)
※2 スワップアウト:実メモリからスワップ領域にデータを退避させる(メモリから出る)

IO

  • bi: ブロックデバイスから受け取ったブロック (blocks/s)。
  • bo: ブロックデバイスに送られたブロック (blocks/s)。

CPU

  • us カーネルコード以外の実行に使用した時間 (ユーザー時間、nice 時間を含む=アプリケーションにCPUが食われている)。
  • sy カーネルコードの実行に使用した時間 (システム時間)。
  • id アイドル時間。Linux 2.5.41 以前では、IO 待ち時間を含んでいる。
  • wa IO 待ち時間。一定時間のうちでシステムがI/Oの処理待ちに費やしたCPU時間の比率を表す。

top

リアルタイムに情報を確認する。
/proc/statを読んでいる。

top d1

1でCPU毎のデータが見れる。

Shift + mでメモリ使用率順にソート

Shift + pでCPU使用率順にソート

Shift + tで実行時間順にソート

Shift + fで項目を増やせる

top -p <プロセスID>

で指定したプロセスIDのみ監視できる。
アラートに応じてメモリを食っているプロセス、CPUを食っているプロセスを把握してあたりをつける。
fでSWAPも表示できるのでSWAPのアラートが出ているとき、swapin/outが発生しているときなどなど確認するとよい。

CPU(s)の項目
us : ユーザプロセスの使用時間
sy : システムプロセスの使用時間
ni : 実行優先度を変更したユーザプロセスの使用時間
id : アイドル状態の時間
wa : I/O待ちをしている時間
hi : ハードウェア割込み要求での使用時間
si : ソフトウェア割込み要求での使用時間
st : 仮想化環境で他の OS に消費された時間

stの値

スティール。通常は0。
この値が高いと基盤障害の可能性がある。
AWSのt系インスタンスでこの値が常に高いとかの場合スペック不足の可能性
(CPUクレジットの枯渇)

sar

サーバの情報を収集していて過去にさかのぼって表示できる
(コンソール版cactiみたいなイメージ?)
入っていないサーバもある(のほうが多い?)

CPUの情報

topっぽい感じ。
実行待ちかIOかあたりをつけるのに有効?

sar -u

Disk I/O

リードライトあたりが有効そう。

sar -b

SWAP

以下。

sar -W

Load average

過去にさかのぼってロードアベレージ確認ができる。

sar -q

ip

ip a

がよくつかう。自分のipを確認したりなど。

firewall-cmd

最近はiptablesではなくこちらをつかうようになった。

systemctl

systemdでプロセスの制御をする。

    systemctl status <サービス名>
    systemctl enable <サービス名>
    systemctl start <サービス名>
    systemctl stop <サービス名>
    systemctl restart <サービス名>

ぐらいしっておけばよい。

ipvsadm

ロードバランサ関係

digの見方

DNSサーバから情報収集をするためのツール。
基本的な書式は

dig @server domain query-type query-class

のようになる。
ここで@serverは利用するネームサーバで省略した場合/etc/resolv.confから取ってこられる。
resolv.confのmanによれば

複数のサーバが指定された場合、リゾルバライブラリは リストされた順に問い合わせを行う。

とある、
のでこの場合も一番上のものから試されていく。

また、domainには調査したいドメインを入れる。

query-typeには取得したいリソースレコードなどを指定する。

  • a A レコードでホストのアドレスを取得する
  • any 取得できるすべての情報を取得する
  • axfr ゾーン転送情報を取得する(よくわかってない...)
  • mx そのドメインのメールサーバの優先度を取得する
  • ns NSレコード(登録されているネームサーバ一覧)を取得できる
  • soa ゾーン情報の管理パラメータでDNSサーバの基本的な情報(名前、タイプ、クラス,TTL、RD)を取得できる
  • hinfo ホストの情報を取得できる
  • txt 任意に設定されているtxtレコードのデータを取得できる

query-classは基本的にinで問題ない。

また、オプションは特に指定しなければ

dig @server @server domain a in

と等価になり@serverで指定したDNSを用いてdomainを名前解決を行う。
また、かかった時間はQuery timeで、実際に使ったDNSサーバはSERVERの項目で確認可能

mpstat

マルチコアなCPUの調査を行うためのコマンド。

mpstat i n

でi秒ごとにn回繰り返す。

集計に使えるコマンド

ionice,nice

ionice -c2 -n7 nice -n19

優先度を下げる。

cut

cut [-f field-list] [-d "デリミタ"]

という感じで-dで指定したデリミタで-fで指定したフィールドリストの部分を標準出力に書き出す。
field-listは0からではなく1からはじまるので注意

基本的に後述のawkのほうが高性能だと思われる。

grep

正規表現で検索して対象行を標準出力に書き出す。

オプション

  • -v 選択されなかった行となる。(結果反転
  • -i 大文字、小文字を区別しない

sort

  • -n 数値が小さい順にソート
  • -nr 数値が大きい順にソート

uniq

ユニークな行のみを出力するコマンド。
入力データはソートされていなければならないので注意!

  • -c 現れた回数とともに出力

awk

awk '{print $n}'

nカラム目にあるものを表示する。
0からではなく1からはじまるので注意
cutより柔軟に区切りを判定してくれる。
これだけでなくマッチングで処理とかもあるのでかなり使える。

lsof

どのプロセスがどのファイルをつかんでいるかを確認できる。
dfでみると容量ギリギリなのに、
duだとなぜか全然問題ないみたいな場合、
プロセスがなくなったファイルをopenし続けていることもあるのでしっとくとよい。

lsof -i:<ポート>

なぜかポートが専有されてて、起動できない>< だけどnetstatでぷろせすが出ないみたいな場合に

gzip

タイムスタンプを更新せずに圧縮する。
ログローテートの実装などで便利だが、
一方で最近圧縮したファイルを探したいなどでfindかけるときなど知らないと困りそう。

tai64nlocal

TAI64N形式の日時を人間が読見やすい形式に変換するコマンド。
TAI64Nは精度が高いらしい?

nc(netcat)

nc -zv <ホスト名> <ポート>

でポートが開いているかを確認できる。(ポートスキャン)

ミドルウェア

MySQLのコマンド

show procsslist;
show full procsslist\G
show variables;
show slave status\G
system <command>;

whereとかできるshow processlist的な

show processlistで条件検索とかソートとかしたいときに(MySQL5以降)

select * from information_schema.PROCESSLIST;

例えば実行時間順にソートして上位10件を取り出す場合

select * from information_schema.PROCESSLIST order by TIME desc limit 10;

など。SQLでできることは何でもできる(がこわい...)

レプリケーションについて

スレーブサーバではIOスレッドとSQLスレッドの2つを動かして、レプリケーションを実現している。
IOスレッドはマスターサーバからのアップデートの読み取り、
SQLスレッドはその読み取ったものをスレーブサーバ上で実行する役割を担っている。

PostgreSQL

$ psql -U username
$ select * from pg_stat_activity;//show procsslistと同等

Flare

分散型メモリキャッシュシステム(memcachedのようなもの)

pgpool

PostgreSQL専用のミドルウェアで、
PostgreSQLのデータベースクライアントとPostgreSQLサーバの間に割り込む形で動作し、
PostgreSQLに

  • 負荷分散 レプリケーション

などの機能を提供する。

iptables

特定IP,ポートからの接続を拒否↓

iptables -I INPUT -p tcp --dport "ポート番号" -s "拒否するIP" -j DROP

どこにインサートすべきか気をつけること!

postfix

postqueue

-pオプションでメールキューを確認

IPVS(ロードバランサ)

cacti

トラフィック

inbound:外部からデータを受信すること。
outbound:内部からデータを送信すること。