configureは通ったので、makeしてみたところ、以下のようなエラーで落ちます。。

# make
(略)
../depcomp: line 512: exec: g++: not found
make[2]: *** [my_new.o] エラー 127
make[2]: Leaving directory `/home/maruta/mysql/mysql-5.0.45/mysys'
make[1]: *** [all-recursive] エラー 1
make[1]: Leaving directory `/home/maruta/mysql/mysql-5.0.45'
make: *** [all] エラー 2

g++が見つからないらしい。
g++というのを初めて聞きました。

ぐぐってみたところ、
「g++ は gcc に C++ を解釈するようにするオプションをつけてコールするスクリプトです。」というものらしいです。

ここは、困ったときのyum頼み。

# yum install g++

だめかなぁーと思いながらやったら、やっぱりダメでした。

で、何かが足りなくてg++に相当するものをインストールしなければならないか、もしくはパスを通してあげないといけないとういのはわかるので、
「yum g++」でググッてみたところ、Q&A掲示板っぽいところで、「yum install gcc-c++でインストールとか? 」というのを発見。

yum listで見てみたところ、それらしいパッケージがあります。
さっそく、インストール。

# yum install gcc-c++

再度、make挑戦。

・・・止まってしまいました。今度は違うエラー

# make
(略)
In file included from mysys_priv.h:16,
                 from my_new.cc:21:
../include/my_global.h:982: error: redeclaration of C++ built-in type `bool'
make[2]: *** [my_new.o] エラー 1
make[2]: Leaving directory `/home/maruta/mysql/mysql-5.0.45/mysys'
make[1]: *** [all-recursive] エラー 1
make[1]: Leaving directory `/home/maruta/mysql/mysql-5.0.45'
make: *** [all] エラー 2

まだ調査中。。。

追記
原因判明しました。mirさんありがとうございます!
続き>MySQLのソースを読んでみる[4] 通常インストール完了。ソースとご対面

タイトルが、MySQLのソースとなっているけど、まだまだそこにたどりつけていません。
ま、気長に。マイペースに。

いろいろMySQLのソースを見ていじっていく上で、
ソースを見る->ソースをいじる->動かしてみる という流れになると思います。
まずは、ソースからインストールをしてみないと話になりません。

普段、MySQLはrpmで入れています。
このBlogを動かしているサーバでは、めんどくさいのでyumでいれちゃいました。
ソースで入れたのは、今の会社に入社したときの研修で、ソースで入れようとして挫折し、先輩にrpmでいいよ と言われ、さくっといれた覚えがあります。
あまりソースから入れた記憶がありません。

で、とりあえずぐぐって、以下のドキュメントを参考にします。
MySQL4系だけど、5系でも一緒かなーということでやってみます。トライアンドエラーです。

http://dev.mysql.com/doc/refman/4.1/ja/quick-install.html

 MySQL ソースディストリビューションをインストールするために実行する必要のある基本的なコマンドは、以下のとおりです。

shell> groupadd mysql
shell> useradd -g mysql mysql
shell> gunzip < mysql-VERSION.tar.gz | tar -xvf -
shell> cd mysql-VERSION
shell> ./configure --prefix=/usr/local/mysql
shell> make
shell> make install
shell> scripts/mysql_install_db
shell> chown -R root  /usr/local/mysql
shell> chown -R mysql /usr/local/mysql/var
shell> chgrp -R mysql /usr/local/mysql
shell> cp support-files/my-medium.cnf /etc/my.cnf
shell> /usr/local/mysql/bin/mysqld_safe --user=mysql &

グループとユーザを作るのは問題ありません。
解凍も出来ています。
configureを動かしてみたところ、以下のようなエラーで止まってしまいます。

configure: error: no acceptable C compiler found in $PATH
See `config.log' for more details.

まぁエラーを見ればわかりますが、Cのコンパイラが見つからんと言っています。
インストール時に開発ツールとかのチェックを忘れたのかもしれません。

で、これではなんにも出来ないので、gccを入れてみます。
まずは、存在確認

# which gcc
/usr/bin/which: no gcc in (/usr/kerberos/sbin:略)

やはり見つかりません。
なので、インストールしなければなりません。
落としてきて というのはめんどくさいので yumで入れちゃいます。

yum install gcc

yumって便利ー
でも、こういうのを裏を知らずに使ってると、スキルが伸び無そうな気がします。。

gccを入れてからconfigureしたら無事通りました。
なので、次はmake。

続き>MySQLのソースを読んでみる[3] makeがこける

MySQLのソースを読んでみるのしょっぱなとして、まずは環境が必要です。
手元に以下のような環境があったのでここで進めてみます。

Windows上のVMwareに CentOS4.4の以下をインストール。
CentOS-4.4.ServerCD-i386.iso
インストール時にMySQL、Apacheなどは除外しそれ以外は基本的にインストール。
Apacheが除かれているのは、仕事での環境が、Apache、phpはソースインストールなので、という理由です。

まずは、MySQLのソースを落としてきてみる。
MySQLの公式サイトからソースのリンクを探す。これが意外とわかりにくい。。
http://dev.mysql.com/downloads/mysql/5.0.html#source
Compressed GNU TAR archive (tar.gz) というtarボールを落としてきました。

で、それを解凍。
tarのオプションってなぜかいつもごっちゃになっちゃうんですよね~
helpして調べてから解凍。

$ tar -xzf mysql-5.0.45.tar.gz

わらわらディレクトリがあります。。。
まずは、普通にソースインストールしてみて、それからいろいろ見ていこうと思います。

あと、ソースを見るのに便利ということで、cscopeというソフトを教えてもらいました。
操作しているところを見せてもらったのですが、emacsと連動させてたので、真似してみようということで、emacs挑戦も同時にやってみます。
初期インストールで入っていなかったので、rootにsuしてから、yumでインストール。

# yum install emacs
# yum install cscope

で。。
emacsの使い方がわかりません。
終了方法もわからない。ま、気長に勉強します。

続き>MySQLのソースを読んでみる[2] gccが入ってない。。

昨日、会社にmir the tritonnの中の人が来てくれて、いろいろSennaやTritonnの話を聞きました。
wikipedia Senna
Tritonnプロジェクト

Tritonnとは、MySQLに全文検索エンジンSennaを利用可能にし、日本語の全文検索が出来るようにしようというプロジェクトです。
こちらの「Tritonnとは」を見ると、なぜMySQLで日本語の全文検索をするときに、組み込みのフルテキストインデックスではなく改造が必要なのかがよくわかります。
http://qwik.jp/tritonn/about.html

現在は、ソースで落とすことが出来ますが、rpm版もちょうど出来立てほやほやのを見せてもらいました。
rpm版のリリースは近々とのことなので楽しみです!

他にもMySQLのソースを読む方法などを教えてもらいました。
少しずつですが、ながめてみようと思い、VMwareにソースを落とそうとしたのですが、何を落としたらよくわからないので、とりあえず、Linux (non RPM packages) Linux (x86, glibc-2.2, “standard” is static) ってのを落としてみた。

http://dev.mysql.com/downloads/mysql/5.0.html#linux

追記。
解凍したらコンパイル済のファイルでした(笑)
下の方にSource downloadsってあった。

2007/10/09に、SoftBankのゲートウェイIP帯域に追加があったようだ。
運営中のサイトや他のサイトの情報から、どうやら今日の午前3時ぐらいから追加されていたっぽい。

携帯サイトを作成する場合、PCから閲覧できないようにGWのIPアドレスのみ通すような閲覧制限をする場合がある。
これにより、UserAgentなどをある程度信用し、UIDやEZ番号といったヘッダの情報もIP制限範囲内では信用できるだろうということになる。

SoftBankにも一般ユーザ向けの情報の中に、IPアドレス帯域の情報がある。
SoftBank Developers Support Site IPアドレス
http://developers.softbankmobile.co.jp/dp/tech_svc/web/ip.php

しかし、今回の帯域追加はこちらには載っていない。
更新日時も古いままだ。「2006年11月17日現在(赤字は12月20日に追加されるIPアドレス帯域)」
その時点のキャプチャ>SoftBank IPアドレス一覧 2007/10/09 15時時点

公式サイト関連には、事前に連絡が来ているのに、こちらのサイトが更新されていない。
ここに追加されたIP帯域を書きたいが、情報元がコンフィデンシャルなので残念ながら書くことが出来ない。

最低限の情報更新ぐらいして欲しい。


これを書きかけで、仕事とかしてたら、SoftBank Developers Support Siteの方に追記されたようです。
追加された帯域

  • 123.108.236.0/24
  • 123.108.237.0/27
  • 202.253.96.224/27
  • 210.169.130.112/28 <帯域変更

他の大手サービスでも勝手サイトでは同様の問題があったようです。
勝手サイトは、UserAgentで制限でもしとけってことですかね?

DoCoMoで502エラーが出るという件がらみで、いろいろ調査をしていたら、こんなことがありました。

502のエラーとは。
502 Bad Gateway
ゲートウェイあるいはプロキシとして動作しているサーバが、リクエストを実行しようとしてアクセスした上位サーバから不正なレスポンスを受信した。 不正なゲートウェイ経由のアクセスなど。
http://www.asahi-net.or.jp/~AX2S-KMTN/ref/status.html

つまり、DoCoMoのゲートウェイがエラーを返している状態ですので、サービス側サーバが原因かDoCoMo側が原因か、切り分けがしづらいです。
いろいろと現象を追っていったところ、502のエラー発生時に、Apacheの error_log に以下のような記録が残っていました。

[Thu Sep 30 00:01:10 2007] [notice] child pid 13639 exit signal Segmentation fault (11)
[Thu Sep 30 00:01:15 2007] [notice] child pid 32389 exit signal Segmentation fault (11)
[Thu Sep 30 00:01:20 2007] [notice] child pid 13633 exit signal Segmentation fault (11)

Apacheの子プロセスがセグメンテーションフォルトで強制終了したというログです。

そもそもの強制終了の原因がいまだ不明ですが、phpにてセグフォルトを起こすプログラムを紹介してる記事を発見しました。
http://sonic64.com/2002-12-04.html

<?php
$base_str = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">';
$Zspace = '(?:\xA1\xA1)'; // 全角スペース
$ascii = '[\x00-\x7F]'; # 1バイト EUC-JP文字
$twoBytes = '(?:[\x8E\xA1-\xFE][\xA1-\xFE])'; # 2バイト EUC-JP文字
$threeBytes = '(?:\x8F[\xA1-\xFE][\xA1-\xFE])'; # 3バイト EUC-JP文字
$character = "(?:$ascii|$twoBytes|$threeBytes)"; # EUC-JP文字

$count = 1000;
$str = '';
for ($i = 0; $i < $count; $i++) {
  $str .= $base_str;
}

// $str が EUC-JP の場合
$str = preg_replace("/^($character*?)(?:\s|$Zspace)+$/", "$1", $str);

print htmlspecialchars($str);
?>

テストでは、$count を 149ではOKで 150でエラーになっていました。

実際にApacheがSegmentation faultで落ちた場合、の応答を FirefoxのLiveHTTPHeadersで調べてみると次のような感じです。

リクエスト
GET /Segmentation_fault.php HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.8.1.7) Gecko/20070914 Firefox/2.0.0.7
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: ja,en-us;q=0.7,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: Shift_JIS,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cache-Control: max-age=0

レスポンス
HTTP/1.x 200 OK

本来、レスポンスのHTTPステータス・コードに続くヘッダや本文がまったく返されていません。
そのため、DoCoMoのゲートウェイでは、コンテンツの識別が出来ず、502のエラーを返していると想像できます。

phpでApacheを、子プロセスとはいえ、こんな簡単に落とせるなんて。。

今日、仕事でphpのチェンジログやらバグ報告などをいろいろ調べていたのですが、あたりまえですが、全て英語だったりします。
あまり英語に強くないので、何が書いているのだかさっぱりです。

そんなときに、いちいちExciteでWebページ翻訳してたりしたのですが、その作業を簡略化できるようにブックマークレット作ってみました。

javascript:location.href='http://www.excite.co.jp/world/english/web/?wb_dis=3&wb_url='+location.href

こちらをお気に入りやリンクバーに入れてみてください。

ついでに、訳文のみ表示するブックマークレット

たいしたことはしてません。
他のブックマークレット参考にしてURL変えただけみたいなもんです。

Webページ翻訳する場合、exciteでは、ページサイズで翻訳してくれない場合があります。
そんな場合、Infoseekでやった方がちゃんと出る場合もありました。
http://translation.infoseek.co.jp/?ac=Web&lng=en

ブックマークレット、あんまり使ってませんが、ちょっとしたJavaScriptの知識があれば簡単に作れるので、繰り返し作業をしてくるカスタマイズした自分専用のを作ってみるとちょっと幸せになれるかもしれません。

こんなブックマークレットのスクリプト集もありました。
JavaScript::Bookmarklet
http://bookmarklet.daa.jp/
参考になりますね。

Subversionでバージョン管理をしている場合、各開発者のローカル環境以外に、実際に公開する環境へ反映する必要がある。

手っ取り早い方法は、個人の開発環境などにチェックアウトしたファイルをSCPやFTPでファイルをアップするという方法ですが、これでは、せっかくのバージョン管理が生かせなくなってしまいます。
必ず、ローカルの環境を最新にし、コミットしてからアップするという運用手順で回避できる規模もあるかもしれませんが、どうしても漏れが出てきてしまうと思います。
せっかくのバージョン管理の利点が半減です。

私の会社では次のような手段で本番環境までの反映をしています。

  1. 各開発者は、自分の修正をSVNにコミット
  2. 実際に確認する本番環境や共通のステージング環境で、svnコマンドを使用し svn update をする
  3. 「.svn」などのSVN用のファイルを除き、公開ドキュメントルートへ rsyncを使用し同期

実際には、そのまま本番へアップということはありえませんので、ステージング環境までを上記方法で反映し、その後、ステージング環境>本番環境への反映もrsyncにて同期することになります。

今回、自分の環境を作成するにあたり、せっかくなので仕事と同じような環境を作ってみました。
仕事では、コミッターが複数いますので、口頭などでSVNへの修正のコミット状況を確認してから、ステージングへの反映シェルバッチを手動にて実行しています。

しかし、ひとりしかコミッターがいない自分の環境では、そこまでする必要がありません。
なので、SVNにコミットしたと同時に開発環境までの反映をされるようにしてみました。

まずは、反映スクリプトを書いてみます。
SVN_DIRと TO_DIRは適宜自分の環境にあわせてください。

#!/bin/sh
SVN_DIR=/var/svn/repos/
FROM_DIR=$SVN_DIR
TO_DIR=/home/www/htdocs/

## svn update
cd $SVN_DIR
/usr/bin/svn update
cd -

/usr/bin/rsync \
        --dry-run \
        --delete \
        --checksum \
        --archive \
        --recursive \
        --verbose \
        --exclude '.svn' \
        $FROM_DIR \
        $TO_DIR

answer=$1

if [ $answer = "-y" ];
then
    answer="y"
else
    echo -n "rsync ok? [y/n]"
    read answer
fi

if [ $answer = "y" ];
then

/usr/bin/rsync \
        --checksum \
        --archive \
        --recursive \
        --verbose \
        --exclude '.svn' \
        $FROM_DIR \
        $TO_DIR

fi

ステージング環境への反映ということで「stg_release.sh」というファイルで作成してみます。
手動で実行した場合には、[y/n]で反映確認が出来るようにしておきました。

あとは、これを手動で動かしてみて実際に反映できるかを確認します。
実際の環境では、–exclude等で除外するファイルをもっと指定する必要があるかもしれません。

次に、SVNのコミット時に自動実行するように設定してみます。

リポジトリのフォルダ内に以下のようなフォルダがあります。

README.txt  conf  dav  db  format  hooks  locks

この hooksフォルダの中に、各イベント時に実行される処理のテンプレートファイルがあります。
今回使用するのは、コミット後なので「post-commit.tmpl」を使用します。

$ cd /path/to/repos/hooks
$ cp post-commit.tmpl post-commit
$ chmod +x post-commit

実行権限まで付けてあげる必要があります。

コミット時にこのファイルが実行されますので、ここで先ほど作成した、反映用のバッチを呼び出してあげればOKです。

$ cat post-commit
#!/bin/sh

# POST-COMMIT HOOK
# ...コメントがいっぱい書いてありますが 略。

#REPOS="$1"
#REV="$2"

#commit-email.pl "$REPOS" "$REV" commit-watchers@example.org
#log-commit.py --repository "$REPOS" --revision "$REV"

##auto update
/bin/sh /path/to/stg_release.sh -y > /dev/null 2>&1

元から書かれているコミット後実行のサンプルはとりあえずコメントアウトし、自分が必要な処理だけ実行するようにしました。

あとは、同じ要領で、svn updateを除いたシェルバッチを書いてあげて、パスをステージング>本番にすれば、本番反映バッチも完了です。

もうちょっと工夫して、ブラウザ上から本番反映を動くようにすれば、いちいちシェルログインしなくても作業が出来て楽チンですね。

この方法はあくまで、私が便利になると思ってやったことですが、SVNから本番反映までの流れを一本にしておくと、余計なトラブルが防げると思います。