カテゴリー別アーカイブ: LAMP[Linux, Apache, MySQL, PHP]

InnoDBの一行は8KBまで – MySQL InnoDBの制限

 MySQLでは、従来、MyISAMが標準ストレージエンジンだったけど、トランザクション機能が使えるInnoDBのニーズも高く、最近は最適化も進み、InnoDBを利用する場面も増えてきた。
 しかし、InnoDBでは注意しなければならない点がある。
 デフォルトのMySQLでは、InnoDBの1行はデータ量8KB以下にしなければならない(MyISAMでは64KBまで対応していた)
 例えば、VARCHAR(255)のカラムが40個あれば10KBになってしまうので、こういったデータのInsert/Updateを実行すると’Got error 139 from storage engine’と言うエラーメッセージで転ける。
 InnoDBはページサイズの1/2の大きさの行を許容するので、ページサイズをMaxの64KBにすれば32KBまで入る様になる。

 ちなみに、TEXTやBLOBカラムは通常、先頭の768バイトがテーブルに、残りが外部に保存されるので、このような型のカラムは10個までしか使えない。
 が、InnoDB1.1以降では、my.cnfで
[mysqld]
innodb_file_per_table
innodb_file_format=Barracuda
 の設定をしてやることで、TEXT/BLOBは20バイトのポインタが保存されて、実体は外部に保存されるので、このような型のカラムを多くする場合にはBarracudaファイルフォーマットを検討すると良いだろう。

(3169)

カテゴリー: MySQL | コメントをどうぞ

普通のコマンドを定期的に実行して結果を表示する – watch

 例えばログファイルの最新部分を表示するのに

tail /var/log/httpd/access_log

 みたいな事をするけど、これを一定間隔で繰り返して監視したいことがある。
 そんなときに便利なのが watch コマンド。
 使い方は簡単で、

watch -n 30 tail /var/log/httpd/access_log

 みたいな感じで実行すると、30秒ごとにtail /var/log/httpd/access_logの結果を表示し続けてくれる。
 短い間隔で更新したければ30をもっと小さくすればいい。
 単純な機能だけど覚えていると管理で便利だ。

(220)

カテゴリー: LAMP[Linux, Apache, MySQL, PHP] | コメントをどうぞ

ネットワーク経由でファイルを取得して連動に利用する – wget

LinuxコマンドラインでHTTPやFTPのファイルを取得するコマンドにwgetがある。
このコマンドはオプションが豊富で、連動シェルスクリプトを書く場合にも便利に使える。

例えば、私のシステムではこんなスクリプトを毎日走らせている。

TODAY=date '+%Y%m%d'
SITENUM=001
wget -q -r -np -nd –accept=”*$TODAY*.csv” http://hosts-$SITENUM.xn--ockc3f5a.com/export/

1行目はTODAYと言う変数にdateコマンドでYYYYMMDD形式の日付を代入している。
2行目は同様にサイト番号。
で、3行目が本題のwgetで、-qは標準出力にメッセージを出さない(quiet)指定(cronで走らせると、標準出力にメッセージがあればメールで送信するので、黙らせている)
-rは、ページのリンク先をたどる設定。 exportディレクトリはIP制限の上でIndexesを有効にしているので、export/を表示すると直下のファイルリストが表示されるので、このファイルを取得する為の設定。
-npは、指定したディレクトリよりも上位を取得しない設定。 Indexesで表示すると、上位ディレクトリへのリンクが現れるためこれで制限している。
-ndは、ディレクトリを作らない設定。 通常、wget -rはホストの構造と同じ形にディレクトリを作るが、ファイルを作業ディレクトリに全て落としたいのでこの設定を入れている。
–acceptは受け入れるアドレスの形式で、この場合当日の日付が含まれるcsvファイルを受け取るという指定をしている。
最後に取得するアドレスを指定している。

 サイト内のリンクを辿ってくれるので、キャッシュシステムを使っているサイトで、cronで

cd /tmp
rm /tmp/site-cache/*
wget -r -q http://wp.xn--ockc3f5a.com/
rm -rf wp.xn--ockc3f5a.com

みたいなのを組んでおくと、1時間経過したキャッシュデータを削除して、サイトを巡ってキャッシュを生成させたりするのにも使える。

HTTPの認証にも対応しているので、お手軽にサイト間でデータ転送をさせたい場合に便利なコマンドだ。

(180)

カテゴリー: サーバ設定 | コメントをどうぞ

テーブル本体を隠しておいて、必要に応じて表示させる – jQuery

$(“.conditions”).children().each(function(){ if(!$(this).is(‘caption’)){
$(this).hide();
}
});

$(“.conditions > caption”).click( function(){
$(this).parent().children().each(function(){
if(!$(this).is(‘caption’)){
$(this).toggle();
}
});
});

 こんなコードを書いて

<table class=’conditions’ border=’3′>
<caption>条件グループ1</caption>
<tr><th>条件1</th><td>hoge</td></tr>
<tr><th>条件2</th><td>piyo</td></tr>
</table>

<table class=’conditions’ border=’3′>
<caption>条件グループ2</caption>
<tr><th>条件A</th><td>hoge</td></tr>
<tr><th>条件B</th><td>piyo</td></tr>
</table>

 みたいなテーブル郡を用意しておくと、初期状態ではキャプションだけ表示されていて、キャプションをクリックする度にテーブル本体が開いたり閉じたりする。
 設定画面が縦に長くなっちゃう時などに、あまり利用しない部分を隠しておくのに便利。
 captionタグにスタイルをつけてcursor:pointer; color:blue;あたりを設定しておくとわかりやすい。

(164)

カテゴリー: jQuery | コメントをどうぞ

複数のアドレス宛メールを送信しようとするとエラーになる – sendmail設定 sendmail.cf

 開発環境で、エラーメールをPHPで同時複数宛に送信しようとするとエラーになる。
 普通に複数宛だと、To:フィールドに列挙するが、sendmailがスパム対策でこれをはじく。 オプション指定でCCやBCCにすればいいのだが、今回は単純にToでの列挙を許可する。

ServersMan@VPSデフォルトのcf(/etc/mail/sendmail.cf)では

#maximum number of recipients per SMTP envelope
#O MaxRecipientsPerMessage=0

というコメントアウトがある。
 MaxRecipientsPerMessageの値がToに設定できるアドレス数の上限値なので、コメントアウトをはずして

O MaxRecipientsPerMessage=8

のように、必要な任意のアドレス数を指定してやればよい。

(1742)

カテゴリー: サーバ設定 | コメントをどうぞ

デフォルトのTOMCAT5

 ServersMan@VPSのサーバ内でTOMCAT5とLAMP環境を同居させていたのだけど、メモリ使用率が結構高いのがちょっと気になっていた。
 けど、特に問題もないのでそのままにしていたのだが、先日、連動処理のバッチを回そうとしたらメモリ不足で転けたのでメモリの設定を見直すことにした。

 どのプロセスがどのくらいメモリを使っているかというのを知るのには、psコマンドにalxオプションを付けるとわかりやすい。
 VSZ項目がバーチャル、RSSがリアルのメモリ消費。

 今回かけたら、タイトルのTOMCAT5がバーチャルで1.2GB程消費していた。
 他のプロセスが500MBほど消費しているので、合計で1.7GB消費している状態。 うちの環境ではMax4GBだが、通常時は2GBくらいが使える領域であるので、余裕は300MBと言うことだ。
 しかし、見かけ上は4GBメモリがあるので、TOMCATが自動的にワーク用に1GB確保していて、本体の200MB+1GBで1.2GBになっている状態だった。
 Javaサイトの占有メモリは1接続で50MBもあれば十分なので、メモリの確保超過。
 /etc/sysconfig/tomcat5ファイルにCATALINA_OPTS=”-Xmx384M”として、384MB上限設定としてTOMCATをリスタートしてやると、TOMCATプロセスは600MB程度に収まって、全体で1.1GB消費で余裕が900Mになって、問題解消。

 ServersMan@VPSのようにMax割り当てできないけど見た目だけメモリ量が多い場合、自動割り当てをするプログラムには注意が必要だ(VMware ESXiの仮想マシンで多めにメモリ指定している場合なども)

(513)

カテゴリー: サーバ設定 | コメントをどうぞ

使用するインデックスを明示する – MySQL インデックスヒントで最適化

 MySQLでクエリをExplainした時にpossible_keysに、IDX_IMPORT, IDX_FSEARCH, IDX_STAT等と複数の候補が存在してkeyにIDX_STATが選択されている時、実際にはIDX_IMPORTの方が高速だったり、他のインデックスよりIDX_STATが低速だったりする時、このインデックスを利用すると高速・低速であるというのをオプティマイザへ知らせる方法としてインデックスヒントがある。

インデックスヒントは

SELECT * FROM estimates USE INDEX(IDX_IMPORT, IDX_FSEARCH) WHERE total>=10000 AND type=1

のように、テーブルに対してUSE/IGNORE/FORCEにより指定する。

USE INDEXはその名の通り指定したインデックスを使用することを推奨するので、インデックス候補中で速い物を指定する。
FORCE INDEXはフルスキャンが非常に重いことを知らせた上で、指定したインデックスを使用することを推奨する。
※特定の条件ではインデックススキャンよりもフルスキャンの方が高速となるパターンがあるので、USEでインデックスを知らせてもそれを使用しないことがあるが、FORCE指定するとフルスキャンを回避してインデックスを使う様になる。 FORCE指定した場合、フルスキャンよりも低速になる可能性もあるので、実データで検証した上で指定した方が良い。
IGNORE INDEXは、逆に使用しないインデックスを指定するので、インデックス候補中で明らかに低速なインデックスがある場合にそれを除外するために使う。

USEとFORCEを比較

EXPLAIN SELECT id FROM estimates USE INDEX (PRIMARY) WHERE type=1 ORDER BY id

possible_keys:NULL key:NULL

EXPLAIN SELECT id FROM estimates FORCE INDEX (PRIMARY) WHERE type=1 ORDER BY id

possible_keys:NULL key:PRIMARY
 ちなみに、ヒントを与えない場合は、possible_keys:NULL key:NULLである。 このクエリを実際に発行すると、USEで0.25秒、FORCEで0.33秒と言うことで、インデックスを使っているけど逆に遅くなった。
 インデックスは何でも張って何でも使えばいいと言う物ではないと言うことだ。
 なお、このようにインデックスを使用すると遅くなる状況でオプティマイザがインデックスを使用するのを防ぐために、USE INDEX ()として、インデックスを使用しないことを明示することも出来る。

(22254)

カテゴリー: MySQL | コメントをどうぞ