takami_hirokiの日記

2010-11-08

プロセス確認に便利なコマンド

プロセス確認する時、こんな感じでgrepしたりしますよね。でも若干面倒ですね。

[root]# ps -aef | grep httpd | grep -v grep

そこで、「pgrep」コマンドを使います。

[root]# pgrep -lf httpd
1890 /usr/local/apache2/bin/httpd -f /usr/local/apache2/conf/httpd.conf -k start
1912 /usr/local/apache2/bin/httpd -f /usr/local/apache2/conf/httpd.conf -k start
1913 /usr/local/apache2/bin/httpd -f /usr/local/apache2/conf/httpd.conf -k start
1914 /usr/local/apache2/bin/httpd -f /usr/local/apache2/conf/httpd.conf -k start
1915 /usr/local/apache2/bin/httpd -f /usr/local/apache2/conf/httpd.conf -k start
1924 /usr/local/apache2/bin/httpd -f /usr/local/apache2/conf/httpd.conf -k start
16275 /usr/local/apache2/bin/httpd -f /usr/local/apache2/conf/httpd.conf -k start
17307 /usr/local/apache2/bin/httpd -f /usr/local/apache2/conf/httpd.conf -k start
19698 /usr/local/apache2/bin/httpd -f /usr/local/apache2/conf/httpd.conf -k start
25100 /usr/local/apache2/bin/httpd -f /usr/local/apache2/conf/httpd.conf -k start

以上です。

参考URL:no title

2010-10-27

MySQLに重いSQLを投げて、帰って来ない時は

重い集計SQLなんかを実行したけど、いつまでたっても帰ってこない時の対処についてです。

まずは、topコマンドで確認します。大抵、以下の例のように、mysqldがリソースを使い切っています。

[root]# top
top - 16:20:17 up 15 days,  6:50,  1 user,  load average: 5.39, 5.14, 5.04
Tasks: 177 total,   2 running, 175 sleeping,   0 stopped,   0 zombie
Cpu(s): 33.7%us, 66.0%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.3%st
Mem:   1048752k total,   826136k used,   222616k free,   194584k buffers
Swap:   562264k total,     4492k used,   557772k free,   277856k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
 2640 mysql     15   0 85704  42m 3664 S 398.6  4.1   2120:30 mysqld
    1 root      15   0  2084  656  560 S  0.0  0.1   0:00.03 init
    2 root      RT  -5     0    0    0 S  0.0  0.0   0:00.44 migration/0

そこで、まず、MySQLに接続し「SHOW PROCESSLIST」コマンド結果を確認します。


[root]# mysql --defaults-file=/db/mysql/data/my.cnf -uroot -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 22802
Server version: 5.1.34-community-log MySQL Community Server (GPL)

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SHOW PROCESSLIST;
 +----+------+-----------------+------+---------+-------+----------------------+----------------------------------+
 | Id | User | Host            | db   | Command | Time  | State                | Info                             |
 +----+------+-----------------+------+---------+-------+----------------------+----------------------------------+
 | 10 | root | localhost:46214 | test | Query   | 23852 | Copying to tmp table | SELECT COUNT(*) FROM `accesslog` |
 | 12 | root | localhost:60469 | test | Query   | 20332 | Waiting for table    | TRUNCATE TABLE `accesslog`       |

これは、一つ目の重いSQLが抜けないために、その後のTRUNCATE文がずっと待たされている状態と言えます。なので、この重いSQLをkillします。killコマンドは、「kill (対象SQLの)Id」の構文で実行します。

mysql> kill 10;
Query OK, 0 rows affected (0.00 sec)

mysql> SHOW PROCESSLIST;
 +----+------+-----------+------+---------+-------+-------+------------------+
 | Id | User | Host      | db   | Command | Time  | State | Info             |
 +----+------+-----------+------+---------+-------+-------+------------------+
 | 10 | root | localhost | test | Query   | 23852 | NULL  | SHOW PROCESSLIST |

そうすると、おそらく、待たされていた後続のSQLも流れて、PROCESSLISTには何も出なくなったりすると思います。


(補足)SHOW PROCESSLISTコマンドについて

詳しくは、MySQL :: Page Not Found を参照してください。

出力カラムは次の意味を持っています。

  • Id : 接続識別子。
  • User : ステートメントを発行した MySQL ユーザ
  • Host : ステートメントを発行しているクライアントのホスト名
  • db : デフォルトデータベース
  • Command : スレッドが実行しているコマンドのタイプ
  • 時刻 : スレッドが現在の状態になってからの秒数
  • State : スレッドの状態*1
  • Info : スレッドが実行中のステートメント
FULL オプションについて

通常、Info 列に表示されるクエリは100文字を越えると省略されますが、FULL オプションを指定すると、省略せずクエリの全文が表示されます。その際、表示が崩れるようであれば\G オプションでクエリ結果を垂直表示すると見やすくなります。

mysql> SHOW FULL PROCESSLIST \G;

*1:参考URL:MySQL :: Page Not Found

2010-10-25

PHPで一意な値を生成する

MySQLレプリケーションのように、ステートメントベースのレプリケーションの場合には、auto_incrementなどの実行時に値が不定な関数は利用が推奨されません。従って、プログラム側で、一意となる値を生成する必要があります。そのような場合、PHPでは、以下のような「uniqid」という関数が利用できます。

string uniqid ([ string $prefix = "" [, bool $more_entropy = false )

マイクロ秒単位の現在時刻にもとづいた、接頭辞つきの一意な ID を取得します。

404 Not Found

uniqid関数の利用例

以下のように書くことで、$prefixの後に、マイクロ秒単位の現在時刻に基づいた文字列が生成されます。

[root]# php -r 'echo uniqid("PRIMARY_");'
PRIMARY_4cc4f4844c2ed

より一意な値とするために

上記の書き方は、あくまで、マイクロ秒単位の違いしかないため、同じ値になる可能性はゼロではありません。

従って、より一意性を高めるために「$prefixを固定文字列ではなく乱数とする」ことを考えます。

[root]# php -r 'echo uniqid(mt_rand());'
5770971284cc4f4b946722

さらに、一意性を高めるために、「第二引数の$more_entropy」を利用します。

TRUE にすると、uniqid() は 返り値の最後にさらに別のエントロピーを (線形合同法を使用して) 追加します。これにより、結果がより一意になります。

404 Not Found
[root]# php -r 'echo uniqid(mt_rand(), true);'
6929848604cc4f53f3ec374.52375463

DBPK生成に利用する場合

Modelの層で、以下のような関数を用意して利用するとよいかもしれません。

ここでは、md5関数を通しています。難読化と、桁数揃えを同時にできて便利かと思います。

public function getPrimaryKey() {
    return md5( uniqid(mt_rand(), true) );
}

よく使うPHPのコマンドラインオプション

個人的によく使う、PHPのコマンドラインオプションをまとめておきます。

参考URL:PHP をコマンドラインから使用する (機能) - PHPプロ!マニュアル


PHPのバージョンを確認 (php -v, php --version)

[実行例]
[root]# php -v
PHP 5.2.9 (cli) (built: May 14 2009 20:58:31)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2009 Zend Technologies
    with eAccelerator v0.9.5.3, Copyright (c) 2004-2006 eAccelerator, by eAccelerator

PHPの設定情報の確認 (php -i, php --info)

phpinfo()の実行結果が表示されます。表示される量が多いので、grepで欲しい情報の部分のみ抜き出すなどの使い方が多いと思います。

[実行例]
[root]# php -i | head
phpinfo()
PHP Version => 5.2.9
 ・
 ・

コマンドラインのみで PHP を実行 (php -r, php --run)

PHP の開始および終了タグ () を書かずに、実行できます。PHPの関数を簡単に試してみることができます。

[実行例]
[root]# php -r 'echo mt_rand();'

指定したPHPファイルを実行 (php -f, php --file)

任意のPHPファイルを指定して、実行することができます。

[実行例]
[root]# php -f index.php

任意場所のphp.iniを指定して実行 (php -c)

PHPでバッチアプリケーションなんかを作る時に、WEBアプリとは別のphp.iniを読み込みたいことがありますが、その場合は、このオプションを利用します。

[実行例]
[root]# php -c ./config/php.ini

2010-10-20

画像の上に自由に文字を配置する

こちら 「画像上の自由な位置に文字を重ねる方法 [ホームページ作成] All About」 を参考にまとめてみます。

実現方法のポイント

  • スタイルシートの positionプロパティを利用
  • 画像には、「position: relative;」を指定*1
  • 文字には、「position: absolute;」を指定し、画像内での上下左右の位置を定義*2

具体例(サンプル)

以下のように、ホワイトボードの画像の上に、文字を配置することを考えてみます。

ホワイトボード

ホワイトボードの内側に表示する文章です。これは画像ではなくテキストです。

このように複数箇所に表示することも可能です。

このサンプルのソースは、以下のようなものです。

<div style="position: relative;">
   <img src="http://f.hatena.ne.jp/images/fotolife/t/takami_hiroki/20101020/20101020111731.gif" 
        width="500" height="500" alt="ホワイトボード"><br>
   <div style="position: absolute; top: 50px; left: 70px; width: 335px;">
      ホワイトボードの内側に表示する文章です。これは画像ではなくテキストです。
   </div>
   <div style="position: absolute; top: 150px; left: 150px; width: 200px;">
      このように複数箇所に表示することも可能です。
   </div>
</div>

解説1.一番外側のdiv要素について

内側のdiv要素(ホワイトボードの中の文字)に対する基準ボックスです。

そのために、このdiv要素のpositionプロパティの値は、relative にしています。移動距離は指定していないので、本来表示されるべき位置のまま表示されます。


解説2.内側のdiv要素について

このdiv要素のpositionプロパティの値は、absolute にしています。

absolute は「positionプロパティがstatic以外の最も近いボックス」からの表示位置を指定することになります。 その「最も近いボックス」とは、ここでは「position: relative;」を指定している「一番外側のdiv要素」となります。

まとめ

今回のこの例は「文字=あるオブジェクト」、「画像の上=任意の好きな場所」と捉えると、「あるオブジェクトを任意の好きな位置に配置したい」という要求に対する解決策を考えたことになります。

それには、「position:absoluteには必ず「親」がいて、その親からの絶対位置を指定する」という特性が利用できるわけです。

任意の場所には「position:relative;」を指定することで親に任命し、あるオブジェクトに「position:absolute」を指定することで子として扱います。その結果、任意の場所(親)に対して、あるオブジェクト(子)の位置を好きに指定できるようになるというわけです。

どんなときに使うと効果的か
  • 写真を並べた上にタイトル文字を置きたい(※今回の例)
  • float以外で複数のボックスを並べたい
  • レイアウト的には上の方にしたいが、重要度は低いのでHTMLでは下の方に置きたい*3

参考URL  グラフィックデザイナーのためのCSSレイアウトメモTIPS「position : absoluteについて」

*1:relative は「本来の表示位置から、相対的に指定ピクセルだけ移動できます

*2:absolute は「static以外が指定されたボックスの内、最も近いボックスの端から、指定ピクセルだけ移動できます

*3:ヘッダー部のサブメニューは、サイト最上部にあるが、内容の重要度は低い。にも関わらずHTML上部にあると、音声読み上げソフトで煩わしく、HTMLの編集時にも邪魔。

2010-10-19

wgetコマンドの使い方

基本

wget の構文は以下のようになっています。

wget -コマンドオプション (オプション引数) URL

基本の使い方はとても簡単で、wgetの後にURLを書けばいいだけです。以下のコマンドで、カレントディレクトリに index.html というファイルがダウンロードされます。

[root]# wget http://www.example.com/index.html

コマンドオプション

wgetコマンドのオプションについては、ここ(このURLのページは表示することが出来ませんでした。 IP分散サーバーならIQサーバー|クラスCの完全分散が月額139円?)が分かりやすいので詳細はこちらを参照してください。

ここでは、個人的に便利だと思うもののみ抜粋して書いておきます。

-i, --input-file=FILE FILE の中に指定された URL をダウンロードする
[root]# cat list.txt
http://www.example.com/hoge.html
http://www.example.com/hoge.jpg

[root]# wget -i list.txt

とすると上記list.txtの中身のファイルをダウンロードできます。

設定ファイル

設定ファイルに、固定的な設定を書き込んでおけば、毎回オプション指定する必要が無くて楽です。

wgetコマンドは、以下の順で、設定を読み込むので、自分のホームディレクトリに.wgetrcファイルを用意しておくとよいです。

  1. /usr/local/etc/wgetrc または、/etc/wgetrc
  2. $HOME/.wgetrc

詳細はこちらを(wget の使い方)の「≫wgetrc」の項を参照してみてください。

プロキシ経由でのアクセス

プロキシ経由でのアクセスで利用する、プロキシサーバ情報については、コマンドオプションでは設定できず、以下の方法で行います。

  • 設定ファイル(~/.wgetrc)に記述
  • 環境変数に設定

つまり、設定ファイルに指定がない場合、環境変数に定義されていれば、それを利用するということです。

設定ファイルによる指定
[root]# vi ~/.wgetrc
# httpのproxyサーバを指定する。
http_proxy = http://www.example.com:8080/
環境変数による指定
[root]# export http_proxy="http://www.example.com:8080/"

viで行番号を表示

vi 実行中に以下の設定を行うと、行番号が表示されるようになります。

:set number

以下、実行結果の例です。

 1 #
 2 # This is the main Apache HTTP server configuration file.  It contains the
 3 # configuration directives that give the server its instructions.
 4 # See <URL:http://httpd.apache.org/docs/2.2> for detailed information.
 5 # In particular, see
 6 # <URL:http://httpd.apache.org/docs/2.2/mod/directives.html>
 7 # for a discussion of each configuration directive.
 8 #
 9 # Do NOT simply read the instructions in here without understanding
10 # what they do.  They're here only as hints or reminders.  If you are unsure