カイワレの大冒険 Third

技術的なことや他愛もないことをたまに書いてます

便利だと思うコマンド・ワザを思いつくままに挙げてみた

日々作業してると、できるだけ作業の負担を減らしたり、デバッグしやすくしたり、工夫したりすることも多いかと思います。

そういうもののうち、こういうのよく使うかもなーというモノたちを、思いつくまま書いてみる。したがって、既出だったり、よく使われてるものもあるかと思われますが、遠慮なく。カテゴリ分けとか完全に挫折してるけど…

SQLの整形

これは社内の人が使っててすごいなーと思ったもの。例えば、以下のようなすっごく汚いというか、読みにくい一行もののSQLがあったとします。SQL自体の妥当性とかは置いておいてくだしあ。

SELECT id,id2,id3,id4,id5,id6,kana,company,name,tel,created_at,updated_at FROM customer AS cs INNER JOIN order AS od ON(cs.id = od.id) WHERE cs.id IN(23,5,6,6622,1) GROUP BY od.id ORDER BY od.id

秀丸にSQLを貼り付けた状態。この状態でSQL整形マクロのマクロを実行します。

結果はこんな感じ。

綺麗に並べてくれます。改行を入れたかったり、もっと区別させたい箇所はまとめて自分でインデントすればいいし、かなり楽になるので、クエリを眺めて切り分けを行う際は使えるかと。

SQLの抽出

またSQLネタですが、現在流れているSQLを実際に見たかったりすることがあるでしょう。そういうときはtcpdumpがよいですが、もうちょっとカスタマイズ。MySQLのサーバが3306ポートで動いてるとして。

/usr/sbin/tcpdump -l -i eth0 -A -n -s 0 dst port 3306 | fgrep 'SELECT'

こういう感じで指定してもいいのですが、どうも余分な文字が入ったり、綺麗に見せてくれなかったりする。ので、それを修正するために以下のように変更。

/usr/sbin/tcpdump -i eth0 -s 0 -l -w - dst port 3306 | strings | perl -e '
while(<>) { chomp; next if /^[^ ]+[ ]*$/;
  if(/^(SELECT|UPDATE|DELETE|INSERT|SET|COMMIT|ROLLBACK|CREATE|DROP|ALTER)/i) {
    if (defined $q) { print "$q\n"; }
    $q=$_;
  } else {
    $_ =~ s/^[ \t]+//; $q.=" $_";
  }
}'

こっちはスマートだなという印象を受けるぐらいすごいなーと。@riywoさんに教えて頂いたのですが、最初見たときの衝撃は忘れないですなぁ。今でもなんかあの感覚残ってます。とりあえず、すごいの一言。

データ流し込み

forやパイプの駆使とか。forは、「for i in {1..50};」という書き方もできますな。この辺はあまり頼りすぎてもいけない気がして、めちゃ長いスクリプトになったらダメな気がするけど、ある程度は思うように書けたほうがいい気がする。

for i in `seq 1 50`;do _DROPTABLE=log_`date '+%Y%m%d' -d "-$i day"`; echo "DROP TABLE IF EXISTS $_DROPTABLE" | mysql -u user -p -D log; done

ほんとは、こんなんじゃなくてちゃんとcronなりで自動処理させましょう。手動はよろしくないっす。awkとかcut,sedも使えたほうがよいのは間違いない。んだけど、わりとはまって時間食ったりするので、適切なものをすぐ書けるようにしないと、意外に言うこと聞かなかったりするときがある…

データ取得。他にも

コマンド

まぁ、サーバ・サービスにまつわるデータなんていっぱい取れるので、取れる方法をひたすら書く。

ps aux, free, vmstat 1, top(M), show full processlist, show innodb status これらは言うまでもなさそう。 あとはsar。Scientific Linux6.0使ってみたら、デフォルトでsysstatが最小構成でもインストール&自動起動になってて、いい時代だなと思った。未だにオプション覚え切れないコマンドのうちの一つ。

$ sar -u -f FILENAME -P ALL //CPU
$ sar -b -f FILENAME //disk
$ sar -B -f FILENAME //paging
$ sar -r -f FILENAME //memory, swap
$ sar -c -f FILENAME //process
$ sar -W -f FILENAME //swap in/out
$ sar -n DEV -f FILENAME //packet
$ sar -n EDEV -f FILENAME //network error
$ sar -n SOCK -f FILENAME //socket

まぁ、こういうコマンドでデータは取っておきつつ、SNMP使って、基本的には、Munin, Cacti, CloudForecastなどで定期的描画できるものを取得しといたほうがよいかな。まぁ、両方大事でしょう。

ネットワーク周り

http_ping, iperf, /sbin/netstat -sとか。 ここら辺も使いますなぁ。

取得するだけじゃなく、更にもう一歩

上述したような方法含め、色々データ取れるわけですが、どうせならプロファイル、解析レベルもできたほうがよいでしょう。

上述した方法でとれたデータでも傾向見ていけば分かる部分は多いけど、それでもまだまだ分からない部分って多い。というか、これだけとっても、ほんと分からんってほうが多いかもしれない。

ということで、トレースするための技術ネタも。ここはもう少し色々書きたい。

MySQL

//プロファイルを開始
mysql> SET profiling=1;
mysql> 診断したいクエリを実行;
mysql> SHOW PROFILE;
mysql> SHOW PROFILE SOURCE;
//状況把握。tmp_table作成に時間かかっているとか、どこにどれだけ時間がかかっているか分かる。
mysql> SET tmp_table_size=64*1024*1024;
mysql> SHOW PROFILE SOURCE;
//比較。SET GLOBAL key_buffer_size=67108864とかしてみてもよいかもしれない。
mysql> SHOW PROFILES;
//今まで実行したプロファイル時のクエリ
mysql> SHOW PROFILE SOURCE FOR QUERY 1;
//番号指定

これでプロファイルをした上で、パラメータはいじったほうがどこで詰まってるかはわかりやすいし、ピンポイントになる。プロファイルはそのセッションのみ有効で、シェルに戻ったらプロファイルはしなくなります。

Memcache解析。tcpdumpの便利なとこ。

# まずtcpdumpでパケットキャプチャする。数秒で数百MBいくので、すぐやめること。
#/usr/sbin/tcpdump -s 65535 -x -n -q -tttt -i eth0 port 11211 > memcached_tcpdump.log

# 圧縮。
# gzip memcached_tcpdump.log

# scpは遅いので、ncで送る。
# 受け取る方で、
$ nc -l 1234 > test (-l は listenモードオプション)

# 送る方で、
$ nc 転送先IP 1234 < memcached_tcpdump.log

# これで高速転送ができる。そしたら、dumpデータをmaatkitに食わせて解析。
$ mk-query-digest --type memcached memcached_tcpdump.log

あと、Memcacheに近い存在として、Redisがあるけど、Redisは食わせる先が今のところ思いつかない。

Redisの場合はリアルタイムに近いとなると、「KEYS」コマンドで見て、定期的だとクライアントでスクリプト書いて、cronでログにCSV出力とかになってる。その辺はまだ詰められそうな気がしないでもないけど、こういうのは負荷が高くなると怖いので、ムズカシイ。

あと、tcpdumpで履かせたものはmaatkitだけじゃなくて、Wiresharkに食わせて、グラフとして描画するのもいいかな。ACK番号進んでないんじゃねとか。

その他

PHPだったらXdebugとかあるし、Apacheだったらstatusがあるし、まだまだある…
Preforkの設定やkeepaliveもあるし、TCPのセッションの状態・タイマーとか、うーむ終わりがない。

ツール

以前僕が「Console2」を使う2つの理由 - カイワレの大冒険 Thirdという記事でも紹介したけど、ツールは色々いじってみるとおしゃれになったり、使いやすくなったりするので、オススメだったり。そんななかで使ってるものでも思うがままに。

ランチャー

僕が今使ってるのは、「Alfred(Mac)」「Launchy(Windows)」。少し前までは「fenrir」使ってたけど、色々変遷してる気がする。いずれにしても、ないと探すのめんどくさくなって、発狂したくなると思う。

基本的に、使いたくなって展開した実行ファイル&ディレクトリは、D直下やどこかわかりやすいところに、特定のappフォルダを作って、そこに収納。ショートカットだけを、デスクトップなどのフォルダにコピーして、そのショートカットフォルダをランチャーの検索対象にしている。こういう整理していかないと、どうもダウンロードフォルダとかがカオスになる気がして辛いので。

ファイラ

Mac版は未だこれってもの見つかってない。Windowsは「CLaunch」使ってる。業務上よくアクセスする深めのディレクトリとかは登録しておく。Mac版オススメあれば是非コメントを!

仮想デスクトップ

思考切り替えやすくするために仮想デスクトップとか。「Dexpot」が今のとこ一番いいかなぁ。Macの場合はSpaces以外になにかあるのかしらん。F9とAlt+TabでMacはわりといけちゃう気がする…

Excel

ツールのところに加えるべきか迷うけど、自分にとっては便利なものかな。意外に活躍してくれるのがExcel。ピボットテーブルやグラフ描いたりするのもいいけど、TSVなどに定形フォーマットで出力したファイルを元に調査をしたいときはすごく活躍してくれる。

  • 該当列に該当セルの値があるかどうか。A列からB2の値を調べたい場合は、こんな感じ。
=IF(COUNTIF(A:A,B2)>1,"重複してるよー","ないよー")
  • セルの値ではなく、文字列が含まれるかどうかの関数はcountifにifを加える。
=IF(COUNTIF(L3,"*php*"),"php","shell")

まぁ、キリがない。とりあえず、Excelの関数って意外に便利なことしてくれると思うのだと。

終わりに

なんかいくらでも出てきそうだけど、ぱっと思いついた・メモに残ってたものを抽出してみた。こういうのをどんどんやっていっても、万全体制になるわけじゃないし、ずっと継続して磨いていくものだと思うので、またそのうち振り返って、改めたいところ。

というか、ほんとどれだけやったら、すぐ解決できるようになれるのか、それぐらい原因分からないことが多いと思うので、ご参考までにというレベルで。

他のエンジニアがどういう方法をすぐ思いついたり、どういうツール使ってるか、めちゃ気になるので、誰かー他にもーーーーー。