2009年05月
2009年05月28日
Gitを使い始めた
「Wakame」でGitを使い始めたのがきっかけ。
今までに実行したgitコマンド。
- git clone
- git add
- git diff
- git commit
- git status
- git log
- git checkout
- git branch
- git pull
- git push
タイミング良くWEB+DB PressにGit特集が載ってたので読んでみた。
分散管理の「ぶ」をちょっとだけ分かった気がする程度。
兎にも角にも、使い慣れるしかないと感じた。
本格的な戦いはこれからだ。
技術評論社
売り上げランキング: 1014
2009年05月27日
何人かの常連さんと仲良くなった
時間があればボルダリング(フリークライミング)。
今ではすっかり自分の習慣になった。少なくても週2ペース。
ジムへ通っていれば見慣れた顔が出来始め、自然と会話生まれる。
最近、面白い傾向に気付いた。
職業を聞いた常連の男性客の業種は「IT系」
登りたくなる業種なのだろうか?
ゴールした時の小さな達成感の積み重ね。
それがエンジニアを夢中にさせる要因なのかも知れない。
一緒にクライミングやりませんか?
売り上げランキング: 8425
スキージャーナル
売り上げランキング: 125031
2009年05月26日
[Wakame] PostgreSQLもスケール対象へ (3/n)の続編
予告通り、今回はオンラインリカバリを実行してみる。
- node1(PostgreSQL)
- オンラインリカバリ用にnode1の鍵作成
- オンラインリカバリ用にnode2に鍵登録
- リカバリスクリプト配置
- pgpool-II
- 対象ノードを登録
- pgpool-IIを再起動
- node2をノードから外す
- node2に対してリカバリを実行
- pgbenchしてみる?
作業内容: node1(PostgreSQL)
▼作業が面倒なので、あらかじめUNIXアカウントpostgresになっておく
node1$ sudo su postgres
▼node1の鍵作成
node1$ ssh-keygen -t dsa -N "" 鍵のファイル名を問われるので、デフォルトファイル名で問題なければEnter
▼node2に鍵を登録
node1$ cat /var/lib/postgresql/.ssh/id_dsa.pub | ssh (node2) "cat >> /var/lib/postgresql/.ssh/authorized_keys"
▼リカバリスクリプト配置
pgpool-IIによるレプリケーションとオンラインリカバリからスクリプトを拝借。
node1$ cd /usr/local/pgsql/data node1$ chmod +x recovery_1st_stage.sh node1$ chmod +x recovery_2nd_stage.sh node1$ chmod +x pgpool_remote_start
作業内容: pgpool-II
pgpool-II$ cd /usr/local/pgpool2/etc pgpool-II$ sudo vi pgpool.conf listen_addresses = '*' port = 9999 pcp_port = 9898 # for debian socket_dir = '/var/run/postgresql' pcp_socket_dir = '/var/run/postgresql' backend_socket_dir = '/var/run/postgresql' # Logging directory logdir = '/tmp' # pid file name pid_file_name = '/var/run/postgresql/pgpool.pid' # Replication mode replication_mode = true # Health check user health_check_user = 'nobody' # node1 backend_hostname0 = '192.168.1.123' backend_port0 = 5432 backend_weight0 = 1 backend_data_directory0 = '/usr/local/pgsql/data' # node2 backend_hostname1 = '192.168.1.124' backend_port1 = 5432 backend_weight1 = 1 backend_data_directory1 = '/usr/local/pgsql/data' recovery_user = 'postgres' recovery_1st_stage_command = 'recovery_1st_stage.sh' recovery_2nd_stage_command = 'recovery_2nd_stage.sh'
▼pgpoolを起動
pgpool-II$ sudo -u postgres /usr/local/pgpool2/bin/pgpool -n &
▼pcp_node_infoでノード情報を確認
pgpool-II$ /usr/local/pgpool2/bin/pcp_node_info 100 192.168.1.122 9898 postgres postgres 0 192.168.1.123 5432 1 1073741823.500000 pgpool-II$ /usr/local/pgpool2/bin/pcp_node_info 100 192.168.1.122 9898 postgres postgres 1 192.168.1.124 5432 1 1073741823.500000
pgpoolのノード対象となっている事を確認。
この時、node2のPostgreSQLは停止状態にあるにも関わらず、pcp_node_infoではステータスが「1」となっている。
一度pgpoolへ接続すると状態に変化が現れた。
pgpool-II$ psql -h localhost -p 9999 pgpool-II$ /usr/local/pgpool2/bin/pcp_node_info 100 192.168.1.122 9898 postgres postgres 0 192.168.1.123 5432 2 1073741823.500000 pgpool-II$ /usr/local/pgpool2/bin/pcp_node_info 100 192.168.1.122 9898 postgres postgres 1 192.168.1.124 5432 3 1073741823.500000
ノードの状態がそれぞれ、node1は「2」、node2は「3」となった。
▼node2をクラスタから切り離す
pgpool-II$ /usr/local/pgpool2/bin/pcp_detach_node 100 192.168.1.122 9898 postgres postgres 1
出力が無いので、無事に切り離されたのかが良く分からない。
pgpool-II$ /usr/local/pgpool2/bin/pcp_node_info 100 192.168.1.122 9898 postgres postgres 1 192.168.1.124 5432 3 1073741823.500000
pcp_node_infoで確認してみると、状態は「3」のまま。
▼オンラインリカバリを実行
pgpool-II$ pcp_recovery_node 100 192.168.1.122 9898 postgres postgres 1
メッセージが出力されないので、成功したのか失敗したのかが分かりづらい。
pgpool-II$ ./pcp_node_info 100 192.168.1.122 9898 postgres postgres 1 192.168.1.124 5432 1 1073741823.500000
どうやら成功したようだ。
pgpool-recoveryを使うと簡単にノードを追加出来るね。
今後の予定
- 図を使ってpgpool-recoveryを使ったオンラインリカバリのまとめ
- AWS(Amazon EC2, Amazon EBS)を使ってノード増殖検証
関連エントリ
- [Wakame] PostgreSQLもスケール対象へ (1/n)
- [Wakame] PostgreSQLもスケール対象へ (2/n)
- [Wakame] PostgreSQLもスケール対象へ (3/n)
[Wakame] PostgreSQLもスケール対象へ (2/n)の続編
前回の予定を変更し、今回はpgpool-IIの追加設定。
オンラインリカバリ検証は次回予定。
今回の前提条件として、pgpool-IIがインストールされている事。
作業内容は前回のエントリを参照。
作業の流れ
作業対象サーバは2台で、pgpool-IIとノード(PostgreSQL)。
重要なのはアーカイブログの有効化とpgpool-recoveryの組み込み。
- pgpool-II
- pcpアカウント作成
- pgpool-recoveryビルド
- ノード(PostgreSQL)
- pgpool-recoveryを配置
- initdbコマンドでdataディレクトリ作成
- アーカイブログ用ディレクトリ作成
- configを変更しアーカイブログを有効化
- pgpool-recoveryをPostgreSQLに組み込む
作業内容: pgpool-II
▼PCP コマンドの設定より
pgpool-II では PCP コマンドと呼ばれるインタフェースを通して pgpool-II の停止やデータベースノードに関する情報の表示を行います。
PCP コマンドを使用するにはユーザ認証が必要になるので、ユーザ名とパスワードを pcp.conf ファイルに設定します。
pcp.conf ファイルの書式は以下のように 1 行ごとにユーザ名と MD5 ハッシュに変換されたパスワードを : で区切ったものです。
pcp用アカウントを設定して行く
▼pcpアカウント用パスフレーズ生成
$ /usr/local/pgpool2/bin/pg_md5 postgres e8a48653851e28c69d0506508fb27fc5
md5sumコマンドと何が違うのか…
$ echo -n postgres | md5sum e8a48653851e28c69d0506508fb27fc5 -
当たり前だけど、ハッシュ値は同じだ。
echoだと「-n」をつけ忘れる可能性があるので、pg_md5を使うのがベター。
▼pcp用アカウント追加
$ cd /usr/local/pgpool2/etc/; pwd /usr/local/pgpool2/etc $ sudo cp -pi pcp.conf.sample pcp.conf $ sudo vi pcp.conf $ diff pcp.conf.sample pcp.conf 28a29 > postgres:e8a48653851e28c69d0506508fb27fc5
▼pgpool-recoveryをビルドするための準備
$ sudo apt-get install postgresql-server-dev-8.3
▼pgpool-recoveryをビルド
$ cd sql/pgpool-recovery/ $ make
▼pgpool-recoveryのインストール先ディレクトリ作成
$ sudo mkdir /usr/local/pgsql $ sudo mkdir /usr/local/pgsql/lib $ sudo mkdir /usr/local/pgsql/share
▼pgpool-recoveryのインストール先ディレクトリを変更したので、パス変更
$ perl -pi -e 's,\$libdir,/usr/local/pgsql/lib,' pgpool-recovery.sql
▼pgpool-recoveryをインストール
$ sudo cp -pi pgpool-recovery.so /usr/local/pgsql/lib/. $ sudo cp -pi pgpool-recovery.sql /usr/local/pgsql/share/.
作業内容: ノード(PostgreSQL)
▼PostgreSQL用ディレクトリ準備
$ sudo mkdir /usr/local/pgsql $ sudo chown postgres:postgres /usr/local/pgsql
psqlコマンドなどはDebianパッケージでインストールされている物とする
▼pgpool-IIからノードへpgpool-recoveryを配置
$ cd /usr/local/pgsql $ sudo mkdir lib $ sudo mkdir share $ scp (pgpool-II):/usr/local/pgsql/lib/pgpool-recovery.so ./lib/pgpool-recovery.so $ scp (pgpool-II):/usr/local/pgsql/share/pgpool-recovery.sql ./share/pgpool-recovery.sql
▼initdbコマンドでdataディレクトリ作成
$ sudo -u postgres /usr/lib/postgresql/8.3/bin/initdb -D /usr/local/pgsql/data
▼archive_logの準備
$ sudo -u postgres mkdir /usr/local/pgsql/data/archive_log/ $ sudo -u postgres chmod 700 /usr/local/pgsql/data/archive_log/
▼postgresql.conf変更 アーカイブログを有効化
$ sudo vi /usr/local/pgsql/data/postgresql.conf listen_addresses = '*' archive_mode = on archive_command = 'cp %p /usr/local/pgsql/data/archive_log/%f'
▼pg_hba.conf変更
$ sudo vi /usr/local/pgsql/data/pg_hba.conf local all all trust host all all 127.0.0.1/32 trust host all all 192.168.1.0/24 trust host all all ::1/128 trust
pgpool-IIからの接続を許可する
▼PostgreSQLを起動
$ sudo -u postgres /usr/lib/postgresql/8.3/bin/pg_ctl -D /usr/local/pgsql/data start
▼pgpool-recoveryをpostgresに組み込む
$ sudo -u postgres psql -c "\i /usr/local/pgsql/share/pgpool-recovery.sql" template1 CREATE FUNCTION CREATE FUNCTION
オンラインリカバリを検証する為の受け皿は整った。
今後の予定
- オンラインリカバリ検証
関連エントリ
翔泳社
売り上げランキング: 34255
2009年05月22日
何気なくスポーツニュースを見ていた
TV: 「スレッジが○○」
自分:「す・・・すれっじ?!」
背中の選手名を見ると…なんと、SLEDGE!!。
調べてみると「ターメル・スレッジ」と言う選手が2008年から「日ハム」に所属している。
去年から居たのに、今頃気づいた。
個人的にSledgeと言うと「Sledge」
何故Sledgeに反応したかと言うと、
その理由は、whois.hansode.orgでSledgeを使っている事。
Sledgeを開発したのは「livedoor」。
livedoorポータルサイトの構築でSledgeが多く使われている。
livedoorが日ハムのスポンサーだったら面白いのに。
頑張れSledge選手!
2009年05月21日
LDR 購読者数を XPath Graph で可視化するより
「刺身さん」に教えて頂いた「XPath Graph」。
刺身さんのアドバイス通りに設定してみた。
▼半袖blog 読者数(LDR)
今はまだ取得期間が少ない。
今後、増減すると面白い状態になるはず。
刺身さん、ありがとう!
2009/05/18(月) ホワイトボードナイト
あくしゅ事務所にて「ホワイトボードナイト vol.1」が開催された。
▼開催までの流れ
- 2009/04/11(土)、あくしゅ事務所が新宿へ移転した
- livedoor時代の元同僚と、新宿移転&ホワイトボード有無の話となる
- ホワイトボードの話題からsasakillさんの「ホワイトボードナイトやりたい」エントリの存在を教えてもらう
- 元同僚に、sasakillさんのblogエントリに「懇親会を兼ね、うちでやりませんか?」とコメント
- sasakillさんからメールで連絡が入る
- →ホワイトボードナイトの開催が決定
▼全てが手探り。まずは自己紹介。
- 横軸に「文系」「理系」
- 縦軸に「営業」「技術」
各自自由に自分のポジションを紹介。
トップバッターが5分以上かかったからか「これは時間がかかる」と思ったのか、途中から「持ち時間1分ルール」が適用される。更に、次の人は指名制が適用された。
- 持ち時間1分
- 次の人を指名
▼「聞きたい事」と「話したい事」
聞きたい事をリクエスト。
とても興味深い会話が交わされた。
結局、ホワイトボードナイトとは…
sasakillさんも書かれている通り、
自分もまた参加メンバーに何度も趣旨を聞かれた。そして「コレ」と言う答えもなく…
今回の参加メンバーにも何度も何度も会の趣旨を聞かれましたが、
やってみてわかりました。どうやら単なる飲み会ですw
そう。単なる飲み会!
しかし、単なる飲み会と違うのは「ホワイトボード」の存在。
- ホワイトボードがあるおかげで、話題が分散しない
- 10人程度(今回の参加者数)なら1つの話題に集中出来る
- 参加者が注目するのは、ホワイトボード
ホワイトボード居酒屋の需要はありそうだと実感した。
壁に貼るタイプのホワイトボードシートが存在するので、それを居酒屋へ持ち込んでみると面白いかも知れない。
まとめ
- 用意した物
- ホワイトボード
- ビール (人数x3本程度)
- ツマミ (ペンを手が汚れにくいと良いのかも)
- 参加者の持ち物
- 名刺
- デジカメ or カメラ付き携帯
- 自己紹介
- 持ち時間は1分
- 次の人を指名
- 「聞きたい事」「話したい事」
- 結局は飲み会なので、基本的に自由
- blogエントリ
- 必須ではないけど書いた方が良い
参加者のみなさん、ありがとうございました。
またやりましょう!
おまけ
「ホワイトボードナイト」は翌朝までが「ホワイトボードナイト」です。
翌朝の片付けは、
いつも早めに出社する取締役2人(1人は自分)で30分…かかったのであった。
参加者エントリ(投稿時間順)
2009年05月20日
[Wakame] PostgreSQLもスケール対象へ (1/n) の続編
前回の予告通り、今回はpgpool-II 2.1以降をインストールする。
http://pgfoundry.org/projects/pgpoolを確認すると、2009/05/20現在「2.2.2」が最新版。
今回はpgpool-II 2.2.2をインストールする。
作業記録
▼事前準備
$ sudo apt-get install libpq-dev
pgpool-IIをビルドするにはpg_configコマンドが必要なので、libpq-devをインストールしておく必要がある。
$ which pg_config /usr/bin/pg_config
pg_configコマンドの存在を確認。
▼pgpool-IIのソースパッケージをダウンロード
$ wget http://pgfoundry.org/frs/download.php/2191/pgpool-II-2.2.2.tar.gz
▼tar ballを伸長
$ tar zxvf pgpool-II-2.2.2.tar.gz
▼ビルドとインストール
$ cd pgpool-II-2.2.2/; pwd /home/axsh/work/pgpool-II-2.2.2 $ ./configure --prefix=/usr/local/pgpool2 $ make $ sudo make install
▼config用意
$ cd /usr/local/pgpool2/etc/; pwd /usr/local/pgpool2/etc $ sudo cp -pi pgpool.conf.sample pgpool.conf $ sudo vi pgpool.conf $ diff pgpool.conf.sample pgpool.conf 17c17,18 < socket_dir = '/tmp' --- > #socket_dir = '/tmp' > socket_dir = '/var/run/postgresql' 21c22,23 < pcp_socket_dir = '/tmp' --- > #pcp_socket_dir = '/tmp' > pcp_socket_dir = '/var/run/postgresql' 24c26,27 < backend_socket_dir = '/tmp' --- > #backend_socket_dir = '/tmp' > backend_socket_dir = '/var/run/postgresql' 60c63,64 < pid_file_name = '/var/run/pgpool/pgpool.pid' --- > #pid_file_name = '/var/run/pgpool/pgpool.pid' > pid_file_name = '/var/run/postgresql/pgpool.pid' 177a182,185 > backend_hostname0 = '127.0.0.1' > backend_port0 = 5432 > backend_weight0 = 1 >
configのコメントには「Debianではこの設定値」と書かれていて、
Debianユーザーには優しいコメントとなっている。
▼pgpool-IIを起動
$ sudo -u postgres /usr/local/pgpool2/bin/pgpool -n
pgpoolコマンドに「-n」を付けるとforegroundで起動する。
「daemontools」でプロセス管理させる事も検討したい。
▼postgresへの接続テスト
$ psql -p 9999 -d postgres
Password:
Welcome to psql 8.3.7, the PostgreSQL interactive terminal.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
postgres=# \q
問題なくpgpoolへ接続出来た。
課題
- pgpool-IIの起動管理
- 個人的にはdaemontoolsで管理したい所だ
- オンラインリカバリとの相性がどうなのか分からないので
- →とりあえず保留
今後の予定
- オンラインリカバリ検証
- 作ったスクリプトがあればそのスクリプト
関連エントリ
翔泳社
売り上げランキング: 6803
「Wakame」で「PostgreSQL」を使えるようにしたい
WakameでPostgreSQLを使えるなら使ってみたい
Wakameに興味を持って下さった方々から、
こう言った声を少なからずとも、いや、意外と多く聞く様になった。
だったら、PostgreSQLもどうにかしよう。
個人的には久しぶりにPostgreSQLに触れる機会となった。
PostgreSQLでレプリケーション構成を構築するには「pgpool-II」を使うと良いらしいよ
噂の真相を突き止めるべく、検証してみる事にした。
作業記録
作業環境
| ディストリビューション | Debian GNU/Linux 5.0.1 |
| カーネル | 2.6.18-6-xen-amd64 |
| postgresql | 8.3.7-0lenny1 |
| pgpool2 | 1.3-2 |
PostgreSQLをインストール
$ sudo apt-get install postgresql
PostgreSQLアカウント作成
$ sudo -u postgres createuser -P axsh Enter password for new role: Enter it again: Shall the new role be a superuser? (y/n) y
psqlでpostgresに接続テスト
$ psql -d postgres
Welcome to psql 8.3.7, the PostgreSQL interactive terminal.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
postgres=# \q
pgpool-IIをインストール
$ sudo apt-get install pgpool2
pgpool-IIにノードを追加
$ cd /etc; pwd /etc $ sudo cp -pi pgpool.conf pgpool.conf.0 $ sudo vi pgpool.conf $ diff pgpool.conf.0 pgpool.conf 149a150,153 > backend_hostname0 = '127.0.0.1' > backend_port0 = 5432 > backend_weight0 = 1 >
pgpool-IIを再起動
$ sudo /etc/init.d/pgpool2 restart
pgpool-IIへ接続テスト
$ psql -d postgres -p 5433
Password:
Welcome to psql 8.3.7, the PostgreSQL interactive terminal.
Type: \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
postgres=# \q
繋がった
LISTENポートを調べてみる
$ sudo netstat -nap |grep -w LISTEN tcp 0 0 0.0.0.0:9898 0.0.0.0:* LISTEN 8378/pgpool tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 1069/sshd tcp 0 0 127.0.0.1:5432 0.0.0.0:* LISTEN 7613/postgres tcp 0 0 127.0.0.1:5433 0.0.0.0:* LISTEN 8378/pgpool tcp6 0 0 :::22 :::* LISTEN 1069/sshd
| ポート番号 | 内容 |
|---|---|
| 5432 | postgres |
| 5433 | pgpool |
| 9898 | pgpool communication manager |
なるほど
面白機能は pgpool-II 2.1からだった…
pgpool-IIには、1.x系と2.x系が存在していた。
しかも、使いたくなるような機能は2.1から実装されている事が判明。
▼pgpool-IIによるレプリケーションとオンラインリカバリの「pgpoolの歴史」より
| プロダクト | バージョン | リリース時期 | 主な追加機能 |
|---|---|---|---|
| pgpool | ver1 | 2004.4 | コネクションプール機能、(2台による)同期レプリケーション機能 |
| pgpool | ver2 | 2004.6 | 負荷分散機能 |
| pgpool-II | ver1 | 2006.9 | パラレルクエリー、2台以上の同期レプリケーション機能 |
| pgpool-II | ver2 | 2007.11 | オンラインリカバリ |
ノードを新規追加するにはオンラインリカバリが重宝するはずだ。
オンラインリカバリの検証もまた必要となる。
Debianパッケージが古い
Debianパッケージだと、pgpool-IIの1.3が最新となっている。
$ dpkg -l pgpool2 Desired=Unknown/Install/Remove/Purge/Hold | Status=Not/Inst/Cfg-files/Unpacked/Failed-cfg/Half-inst/trig-aWait/Trig-pend |/ Err?=(none)/Hold/Reinst-required/X=both-problems (Status,Err: uppercase=bad) ||/ Name Version Description +++-==============-==============-============================================ ii pgpool2 1.3-2 connection pool server and replication proxy
2007.11にリリースされたのに、Debianにしてはパッケージが古いね。
sidにしてみたらどうなるのか気になったので調べてみても、やはり1.3だ。
→http://packages.debian.org/sid/pgpool2
よって、ソースパッケージからインストールするしかない…訳だ。
今後の予定
- pgpool-II 2.1のインストール
- オンラインリカバリ検証
- 作ったスクリプトがあればそのスクリプト
ゴールはWakameに乗せる事。
ワクワクして来たぞ。
翔泳社
売り上げランキング: 71946
2009年05月16日
愛用しているfeedリーダー「livedoo Reader」
購読者数を確認する事が出来る。
確認方法はこれだけ。
http://reader.livedoor.com/about/あなたのblogのURI
半袖blogの場合は、
http://reader.livedoor.com/about/http://blog.hansode.org/
こうなる。
1つの目標を達成
遂にlivedoor Readerの半袖blog購読者数が100人超えた。

atomや旧URLを合算すると、とっくに100人超えしてたようだ。
2009年05月15日
[Wakame] Amazon EC2 API Toolsを使ってMySQL Slaveを作る (2/n) の続編
前回予告した通り、今回はMySQLのdatadirにAmazon EBS Volumeをマウントした設定。
今回の作業前提条件は、
- MySQL Master
- master用my.cnfが存在する
- datadir = /home/wakame/mysql/data/
- server-id = 1
- log_bin
- master用my.cnfが存在する
- MySQL Slave
- slave用my.cnfが存在する
- datadir = /home/wakame/mysql/data-slave/
- server-id = 2
- slave用my.cnfが存在する
6つのファイル
今回使うのは6つのファイル。
- _wakame-common.sh
- 共通設定
- wakame-ebs-mysql-master-create-volume.sh
- Amazon EBS Volume作成
- wakame-ebs-mysql-master-init.sh
- MySQLのdatadirを初期化
- ※今回初登場
- wakame-ebs-mysql-master-add-repl-user.sh
- MySQLのレプリケーション用MySQLアカウント作成
- ※今回初登場
- wakame-ebs-mysql-master-make-snapshot.sh
- Master datadirからAmazon EBS Snapshot作成
- ※今回初登場
- wakame-ebs-mysql-slave-restore.sh
- Amazon EBS Snapshotからslave用datadir作成
- ※今回初登場
前回登場しているファイルは省略。
▼wakame-ebs-mysql-master-init.sh
#!/bin/sh
#
# http://blog.hansode.org/
# 2009.05.12
#
##
## variables
##
# common
pwd=$(cd $(dirname $0) && pwd)
[ -f ${pwd}/_wakame-common.sh ] && . ${pwd}/_wakame-common.sh
df ${ebs_master_dev} || exit 1
[ -d ${ebs_master_mnt} ] || exit 1
chown mysql:mysql ${mysqld_master_dir}
mysql_install_db --datadir=${mysqld_master_dir}
exit 0
▼wakame-ebs-mysql-master-add-repl-user.sh
#!/bin/sh
#
# http://blog.hansode.org/
# 2009.05.12
#
##
## variables
##
# common
pwd=$(cd $(dirname $0) && pwd)
[ -f ${pwd}/_wakame-common.sh ] && . ${pwd}/_wakame-common.sh
[ -z "${mysqld_master_acl}" ] && { echo "please set mysqld_master_acl"; exit 1; }
echo "GRANT REPLICATION SLAVE, REPLICATION CLIENT, RELOAD ON *.* TO '${mysqld_master_info_user}'@'${mysqld_master_acl}' IDENTIFIED BY '${mysqld_master_info_pass}';" | mysql_command
echo "FLUSH PRIVILEGES;" | mysql_command
exit 0
▼wakame-ebs-mysql-master-make-snapshot.sh
#!/bin/sh
#
# http://blog.hansode.org/
# 2009.05.12
#
##
## variables
##
# common
pwd=$(cd $(dirname $0) && pwd)
[ -f ${pwd}/_wakame-common.sh ] && . ${pwd}/_wakame-common.sh
# ebs_master_volume=
ebs_master_volume=$(ec2-describe-volumes | grep ${ec2_instance_id} | grep ${ebs_master_dev} | grep attached | awk '{print $2}')
[ -z "${ebs_master_volume}" ] && { echo not mounted: ${ebs_master_dev}; exit 1; }
echo ${ebs_master_volume}
echo
# connect test
echo "SHOW MASTER STATUS" | mysql_command >/dev/null || {exit 1;}
#
echo "... flush tables with read lock;";
echo "FLUSH TABLES WITH READ LOCK;" | mysql_command
#
echo "... show master status;";
mysqld_master_status=$(echo "SHOW MASTER STATUS;" | mysql_command)
set ${mysqld_master_status}
mysqld_master_binlog_file=$1
mysqld_master_binlog_pos=$2
#
echo "... make master.info"
cat <<EOS > ${mysqld_master_dir}/master.info
14
${mysqld_master_binlog_file}
${mysqld_master_binlog_pos}
${mysqld_master_info_host}
${mysqld_master_info_user}
${mysqld_master_info_pass}
${mysqld_master_info_port}
60
0
EOS
#
chmod 0644 ${mysqld_master_dir}/master.info
chown mysql:mysql ${mysqld_master_dir}/master.info
#
echo "$ ec2-create-snapshot ${ebs_master_volume}"
#
ebs_master_snapshot_id=$(ec2-create-snapshot ${ebs_master_volume} | awk '{print $2}')
[ -z "${ebs_master_snapshot_id}" ] && { exit 1; }
#
for i in 1 2 3 4 5 6 7 8 9 10; do
echo -n ". "
ec2-describe-snapshots | grep ${ebs_master_snapshot_id} | grep completed -q && break
sleep 1
done
echo
#
echo "... unlock tables;";
echo "UNLOCK TABLES;" | mysql_command
echo ">>> snapshot_id = ${ebs_master_snapshot_id}"
exit 0
▼wakame-ebs-mysql-slave-restore.sh
#!/bin/sh
#
# http://blog.hansode.org/
# 2009.05.12
#
##
## variables
##
# local
ebs_master_snapshot_id=$1
[ -z "${ebs_master_snapshot_id}" ] && { echo "usage: $0 [snapshot-id]"; exit 1; }
# common
pwd=$(cd $(dirname $0) && pwd)
[ -f ${pwd}/_wakame-common.sh ] && . ${pwd}/_wakame-common.sh
## check phase
[ -b "${ebs_slave_dev}" ] && { echo "already attached: ${ebs_slave_dev}"; exit 1; }
df ${ebs_slave_dev} >/dev/null 2>&1 && { echo "already mounted: ${ebs_slave_dev}"; exit 1; }
## EC2 instance
# create volume
ebs_slave_volume=$(ec2-create-volume --snapshot ${ebs_master_snapshot_id} -z ${ec2_zone} | awk '{print $2}')
[ -z "${ebs_slave_volume}" ] && { echo "can't create volume"; exit 1; }
for i in 1 2 3 4 5 6 7 8 9 10; do
echo -n ". "
ec2-describe-snapshots | grep ${ebs_master_snapshot_id} | grep completed -q && break
sleep 1
done
echo
# attache volume
ec2-attach-volume -d ${ebs_slave_dev} -i ${ec2_instance_id} ${ebs_slave_volume}
for i in 1 2 3 4 5 6 7 8 9 10; do
echo -n ". "
sync
[ -b ${ebs_slave_dev} ] && break
sleep 1
done
# mount ...
[ -z "${ebs_slave_mnt}" ] && { echo "please set ebs_slave_mnt"; exit 1; }
[ -d "${ebs_slave_mnt}" ] || mkdir ${ebs_slave_mnt}
mount ${ebs_slave_dev} ${ebs_slave_mnt} >/dev/null 2>&1
mount | grep ${ebs_slave_dev}
df ${ebs_slave_dev} >/dev/null 2>&1 || { echo "not available: ${ebs_slave_dev}"; exit 1; }
echo
# current volume?
ec2-describe-volumes ${ebs_slave_volume}
# done
exit 0
スクリプトの準備
前回同様の作業ディレクトリへ移動
# cd work/wakame
初登場スクリプト2つをそれぞれコピー&ペースト
# cat > wakame-ebs-mysql-master-init.sh (コピー&ペースト) ^D # cat > wakame-ebs-mysql-master-add-repl-user.sh (コピー&ペースト) ^D # cat > wakame-ebs-mysql-master-make-snapshot.sh (コピー&ペースト) ^D # cat > wakame-ebs-mysql-slave-restore.sh (コピー&ペースト) ^D
実行可能状態にしておく
# chmod +x ./wakame-ebs-mysql-master-init.sh # chmod +x ./wakame-ebs-mysql-master-add-repl-user.sh # chmod +x ./wakame-ebs-mysql-master-make-snapshot.sh # chmod +x ./wakame-ebs-mysql-slave-restore.sh
動作実行例
MySQL Masterのdatadir用にAmazon EBS Volumeを作成
master# ./wakame-ebs-mysql-master-create-volume.sh $ ec2-create-volume -z us-east-1b -s 1 ebs_master_volume:vol-e058ba89 $ ec2-attach-volume -d /dev/sdm -i i-f9047990 vol-e058ba89 ATTACHMENT vol-e058ba89 i-f9047990 /dev/sdm attaching 2009-05-15T03:37:49+0000 . . $ yes | mkfs -t ext3 /dev/sdm >/dev/null 2>&1 /dev/sdm on /home/wakame/mysql/data type ext3 (rw)
MySQL Masterのdatadir用を初期化
master# ./wakame-ebs-mysql-master-init.sh
レプリケーション用MySQLアカウントを追加
master# ./wakame-ebs-mysql-master-add-repl-user.sh
MySQL Masterのmysqldを起動
master# mysql start
MySQL MasterのdatadirからAmazon EBS Snapshotを作成
master# ./wakame-ebs-mysql-master-make-snapshot.sh vol-e058ba89 ... flush tables with read lock; ... show master status; ... make master.info $ ec2-create-snapshot vol-e058ba89 ... unlock tables; . >>> snapshot_id = snap-50c73f39
例では、snapshotのIDが「snap-50c73f39」となった。
先に生成したAmazon EBS Snapshotからslave用datadir作成。
この時、snapshot IDが必要となる。
slave# ./wakame-ebs-mysql-slave-restore.sh snap-50c73f39 . ATTACHMENT vol-3e5ebc57 i-1344387a /dev/sdn attaching 2009-05-15T07:19:14+0000 . . /dev/sdn on /home/wakame/mysql/data-slave type ext3 (rw) VOLUME vol-3e5ebc57 1 snap-50c73f39 us-east-1b in-use 2009-05-15T07:19:01+0000 ATTACHMENT vol-3e5ebc57 i-1344387a /dev/sdn attached 2009-05-15T07:19:14+0000
MySQL Slaveのmysqldを起動
slave# mysql start
レプリケーションの確認
ここはざっくり省略。
- MySQL Master
- 「SHOW MASTER STATUS」で状態を確認
- MySQL Slave
- 「SHOW SLAVE STATUS」で状態を確認
- IOスレッド、SQLスレッドが「YES」である事
- Masterのbinlogポジションと同値である事
本シリーズは3回で終わり
AWSを使ったMySQLレプリケーション作成と設定は今回で終わり。
- [Wakame] Amazon EC2 API Toolsを使ってMySQL Slaveを作る (1/n)
- [Wakame] Amazon EC2 API Toolsを使ってMySQL Slaveを作る (2/n)
- [Wakame] Amazon EC2 API Toolsを使ってMySQL Slaveを作る (3/3)
シリーズを振り返る
Wakameに組み込む為の手順の確認で作り始めたスクリプト。
このスクリプト単体でも意外と便利なのでアウトプットしてみた。
1人でも良いので、誰かの役に立てればアウトプットした意味がある。
AWS(Amazon Web Service)を使うと、いろいろな事が簡単に出来る事を実感した。
今回の様に、一度スクリプトを作ってしまえば、その後の作業は物凄く単純化される。
AWSに惚れ直した。
今後、色々なデベロッパーによって面白い使い方がされて行くだろう。
その面白い使い方の1つが「Wakame」になるはずだ!
オライリージャパン
売り上げランキング: 137177
オライリージャパン
売り上げランキング: 101715
Pragma
売り上げランキング: 6573
「スタジオFIX 丸子さん」のAWSエントリが熱い
先日、AWS関連で分からない事がありGoogleで検索してたら、丸子さんのエントリがヒットした。
そして、AWS関連エントリがたくさんある事に驚かされた。
- まず、丸子さんはWebデザイナーである事
- エンジニアであっても、AWSをここまで使っている人は少ないだろう
- 例えば自分の場合、CloudFrontまでは使った事が無い
- EC2でさえ未着手エンジニアは多々いるはずだ
- 説明が丁寧
- 管理画面のキャプチャ付き
- 説明対象を分かりやすくハイライト
- 流石Webデザイナー!
第1回目「こんなにスゴイぞ、Amazon EC2」から始まり、約20エントリの連載。
ありがたいことに、第19回「Amazon EC2上でインスタンスをオートスケールできる「Wakame」」では「Wakame」に触れてくれている。
2009/05/15時点で計19エントリ。
今後のエントリにも注目したい。
丸子さんとは以前一度だけお会いしたことがある。
もう、かれこれ、1年前の事。
お元気ですか〜?
空いたリソース
長い目で観察し、問題点を洗い出し、
パフォーマンスチューニングしたらサーバリソースに余裕が生まれた。
空いたリソースをどうするか…。
そうだ、5文字.com、5文字.netを調べよう。
5文字の組み合わせ
その組み合わせは…
$ echo $((26 ** 5)) 11881376
- 26 → アルファベット26文字
.comと.netなので、更に倍。
$ echo $((26 ** 5 * 2)) 23762752
23,762,752通り…。
(2千3百万)
もしも数字とハイフンを考慮したらとんでもない数値になる。
$ echo $((36 ** 5 * 2)) 120932352
120,932,352通り。
(1億2千万)
目標は1000万越え
目標が1000万エントリなので、
今回のクロール対象はアルファベットの組み合わせ(2千3百万通り) としておこう。
さて、いつクロールし終わるんだろうか…
2009年05月14日
[Wakame] Amazon EC2 API Toolsを使ってMySQL Slaveを作る (1/n) の続編
前回予告した通り、今回はAmazon EBSのVolume操作するシェルスクリプト。
今回の作業前提条件は、
- Amazon EC2 API Toolsがインストールされ、動作する事
- さらに、rootアカウントでAmazon EC2 API Toolsが動作する事
※前回はUNIXアカウント「ubuntu」で作業を行っていたので、rootにて同じ作業をするだけ。
3つのファイル
今回使うのは3つのファイル。
- _wakame-common.sh
- 共通設定
- wakame-ebs-mysql-master-create-volume.sh
- Amazon EBS Volume作成
- wakame-ebs-mysql-master-delete-volume.sh
- Amazon EBS Volume削除
▼_wakame-common.sh
# Amazon EBS
ebs_master_size=1 # 1G
ebs_master_fstype=ext3 # filesystem
ebs_master_dev=/dev/sdm # device name
ebs_master_mnt=/home/wakame/mysql/data # mount point
ebs_slave_dev=/dev/sdn # device name
ebs_slave_mnt=/home/wakame/mysql/data-slave # mount point
# Amazon EC2
ec2_instance_id=$(curl -s -f --retry 3 http://169.254.169.254/2008-02-01/meta-data/instance-id/)
ec2_zone=$(curl -s -f --retry 3 http://169.254.169.254/2008-02-01/meta-data/placement/availability-zone/)
ec2_local_ipv4=$(curl -s -f --retry 3 http://169.254.169.254/2008-02-01/meta-data/local-ipv4)
# mysqld master
mysqld_master_mnt=${ebs_master_mnt}
mysqld_master_dir=${mysqld_master_mnt} # datadir
mysqld_master_admin_host=127.0.0.1 # MySQL Masterのホスト名(or IPアドレス)
mysqld_master_admin_user=root # MySQL Masterの管理ユーザー名
mysqld_master_acl='%' # MySQL Masterへの接続元制限
# master.info
mysqld_master_info_host=${ec2_local_ipv4} # Slaveから見たMasterのホスト名(or IPアドレス)
mysqld_master_info_user=wakame-repl # レプリケーション用ユーザー名
mysqld_master_info_pass=wakame-slave # レプリケーション用パスワード
mysqld_master_info_port=3306 # Slaveから見たMasterのポート番号
# この例では、ホスト名とユーザー名の指定のみ行っている
# 必要に応じて -p などを追加して下さい
mysql_command() {
cat | mysql \
-h${mysqld_master_admin_host} \
-u${mysqld_master_admin_user} \
-s
# -p${mysqld_master_admin_pass} \
# -P${mysqld_master_admin_port} \
}
▼wakame-ebs-mysql-master-create-volume.sh
#!/bin/sh
#
# http://blog.hansode.org/
# 2009.05.12
#
##
## variables
##
# common
pwd=$(cd $(dirname $0) && pwd)
[ -f ${pwd}/_wakame-common.sh ] && . ${pwd}/_wakame-common.sh
##
## check phase
##
[ -b "${ebs_master_dev}" ] && { echo "already attached: ${ebs_master_dev}"; exit 1; }
df ${ebs_master_dev} >/dev/null 2>&1 && { echo "already mounted: ${ebs_master_dev}"; exit 1; }
# create volume ...
[ -z "${ebs_master_size}" ] && { echo "plese set ebs_master_size"; exit 1; }
echo "$ ec2-create-volume -z ${ec2_zone} -s ${ebs_master_size}"
ebs_master_volume=$(ec2-create-volume -z ${ec2_zone} -s ${ebs_master_size} | awk '{print $2}')
sleep 1
[ -z "${ebs_master_volume}" ] && { echo "can't get ebs_master_volume"; exit 1; }
echo ebs_master_volume:${ebs_master_volume}
echo
# attach ebs_master_volume ...
[ -z "${ebs_master_dev}" ] && { echo "please set ebs_master_dev"; exit 1; }
[ -z "${ebs_master_fstype}" ] && { echo "please set ebs_master_fstype"; exit 1; }
mount | grep -q ${ebs_master_dev} && { echo "not mounted: ${ebs_master_dev}"; exit 1; }
echo "$ ec2-attach-volume -d ${ebs_master_dev} -i ${ec2_instance_id} ${ebs_master_volume}"
ec2-attach-volume -d ${ebs_master_dev} -i ${ec2_instance_id} ${ebs_master_volume}
echo
for i in 1 2 3 4 5 6 7 8 9 10; do
echo -n ". "
sync
[ -b "${ebs_master_dev}" ] && break
sleep 1
done
echo
[ -b "${ebs_master_dev}" ] || { echo "not available: ${ebs_master_dev}"; exit 1; }
# format ...
echo "$ yes | mkfs -t ${ebs_master_fstype} ${ebs_master_dev} >/dev/null 2>&1"
yes | mkfs -t ${ebs_master_fstype} ${ebs_master_dev} >/dev/null 2>&1
sync
echo
# mount ...
[ -z "${ebs_master_mnt}" ] && { echo "please set ebs_master_mnt"; exit 1; }
[ -d "${ebs_master_mnt}" ] || mkdir ${ebs_master_mnt}
mount ${ebs_master_dev} ${ebs_master_mnt} >/dev/null 2>&1
mount | grep ${ebs_master_dev}
df ${ebs_master_dev} >/dev/null 2>&1 || { echo "not available: ${ebs_master_dev}"; exit 1; }
echo
# done
exit 0
▼wakame-ebs-mysql-master-delete-volume.sh
#!/bin/sh
#
# http://blog.hansode.org/
# 2009.05.12
#
##
## variables
##
# common
pwd=$(cd $(dirname $0) && pwd)
[ -f ${pwd}/_wakame-common.sh ] && . ${pwd}/_wakame-common.sh
##
## check phase
##
[ -b "${ebs_master_dev}" ] || { echo "not found: ${ebs_master_dev}"; exit 1; }
df ${ebs_master_dev} >/dev/null 2>&1 || { echo "not found: ${ebs_master_dev}"; exit 1; }
# ebs_master_volume=
ebs_master_volume=$(ec2-describe-volumes | grep ${ec2_instance_id} | grep ${ebs_master_dev} | grep attached | awk '{print $2}')
[ -z "${ebs_master_volume}" ] && { echo not found: ${ebs_master_dev}; exit 1; }
echo ${ebs_master_volume}
echo
# unmount...
echo "$ umount ${ebs_master_mnt}"
umount ${ebs_master_mnt}
for i in 1 2 3 4 5 6 7 8 9 10; do
echo -n ". "
sync
sleep 1
mount | grep ${ebs_master_dev} -q || break
done
echo
# detach volume...
echo "$ ec2-detach-volume ${ebs_master_volume}"
ec2-detach-volume ${ebs_master_volume}
for i in 1 2 3 4 5 6 7 8 9 10; do
echo -n ". "
sync
sleep 1
ec2-describe-volumes | grep ${ec2_instance_id} | grep ${ebs_master_dev} | grep attached -q || break
done
echo
# delete volume...
echo "$ ec2-delete-volume ${ebs_master_volume}"
ec2-delete-volume ${ebs_master_volume}
for i in 1 2 3 4 5 6 7 8 9 10; do
echo -n ". "
sync
sleep 1
ec2-describe-volumes | grep ${ec2_instance_id} | grep ${ebs_master_dev} | grep deleting -q || break
done
echo
# done
echo "$ ec2-describe-volumes"
ec2-describe-volumes
exit 0
スクリプトの準備
適当な作業ディレクトリを作成し、そのディレクトリにファイルを保存する。
# mkdir -p work/wakame # cd work/wakame
3つのスクリプトをそれぞれコピー&ペースト
# cat > _wakame-common.sh (コピー&ペースト) ^D # cat > wakame-ebs-mysql-master-create-volume.sh (コピー&ペースト) ^D # cat > wakame-ebs-mysql-master-delete-volume.sh (コピー&ペースト) ^D
実行可能状態にしておく
# chmod +x ./wakame-ebs-mysql-master-create-volume.sh # chmod +x ./wakame-ebs-mysql-master-delete-volume.sh
動作実行例
# ./wakame-ebs-mysql-master-create-volume.sh $ ec2-create-volume -z us-east-1b -s 1 ebs_master_volume:vol-d656b4bf $ ec2-attach-volume -d /dev/sdm -i i-f9047990 vol-d656b4bf ATTACHMENT vol-d656b4bf i-f9047990 /dev/sdm attaching 2009-05-14T05:11:46+0000 . . $ yes | mkfs -t ext3 /dev/sdm >/dev/null 2>&1
# ./wakame-ebs-mysql-master-delete-volume.sh vol-d656b4bf $ umount /home/wakame/mysql/data umount: /home/wakame/mysql/data is not mounted (according to mtab) . $ ec2-detach-volume vol-d656b4bf ATTACHMENT vol-d656b4bf i-f9047990 /dev/sdm detaching 2009-05-14T05:11:46+0000 . $ ec2-delete-volume vol-d656b4bf VOLUME vol-d656b4bf . $ ec2-describe-volumes VOLUME vol-d656b4bf 1 us-east-1b deleting 2009-05-14T05:11:38+0000
Amazon EBS Volumeの追加削除までが行える事を確認出来た。
Amazon EBSで困った事、気付いた事
いくつかハメられたポイントがあった
- 見た目はローカルデバイスである為、ネットワーク越しである事を忘れがち
- →その次の操作をして良い状態に遷移してない事が多い!!
確実性を持たせる為に、
- create直後にattachしない事
- attach直後にmkfsしない事
- detach直後にdeleteしない事
- →適度にsleepとsyncを入れ、Amazon EBS Volumeの状態が遷移した事を確認してから次の作業を行う事
これに気付くまでに、何度も同じ過ちを犯してしまった…。
スクリプト内にsleepとsyncが登場しているのは、これらを考慮している為だ。
次回は
MySQLのdatadirにAmazon EBS Volumeをマウントした設定。
- MySQL Master
- datadirにAmazon EBSを使う
- MySQL Masterのdatadirのsnapshot生成
- MySQL Slave
- 生成したsnapshotからMySQL Slave用のdatadirを作成
変更履歴
- 2009/05/15 16:30
- _wakame-common.shの内容修正
- ec2_local_ipv4を追加
- mysqld_master_info_hostの値を${ec2_local_ipv4}へ
オライリージャパン
売り上げランキング: 117000
適度に食べて適度に運動
身近に体調を崩す人達が続出。
居ないなら居ないで、進まない事はある。
改めて「体調管理も仕事のうち」を実感。
自分は絶好調
軽く運動することに体が慣れた様で、体重減少傾向は落ち着いた。
- 体重: 71kg〜73kg
- 体脂肪率: 8%〜9%
体脂肪率一桁とは言え、意外と余分な肉がまだ事に気づく。
適度な運動を続けて行けばもう少し落ちるのかな?
決して無理はしない事。
ストレッチメソッドが体を楽にする
以前にも紹介した「ストレッチメソッド」。
体にとって良い刺激なので、ずっと続けてる。
疲れた部位の筋肉をほぐすにはどうしたら良いのかの説明が分かりやすい。
オススメの一冊。
高橋書店
売り上げランキング: 227
2009年05月11日
ミッション: WakameにMySQL Slave自動追加機能を実装
自分がRubyを使い慣れてないので、手慣れているシェルスクリプトで動作を確認する。
動作確認後、Wakameコードに手を入れて行く。
まずは環境構築
必要な物は下記の通り。
EC2関連の利用までの手順は、今回省略する。
- Javaのランタイムパッケージ
- Amazon EC2 API Tools
- AWSの証明書(pk.pemとcert.pem)
ec2-api-toolsの環境設定
UbuntuであればJavaのランタイムパッケージをapt-getするだけ。
もしもUbuntu9.04以降であればec2-api-toolsもapt-getでインストール可能。
- パッケージインストール
- default-jre-handless
- ec2-api-tools
- 環境変数設定
- JAVA_HOME
- EC2_HOME
$ sudo apt-get install default-jre-headless $ export JAVA_HOME=/usr $ wget http://s3.amazonaws.com/ec2-downloads/ec2-api-tools-1.3-30349.zip $ unzip ec2-api-tools-1.3-30349.zip $ sudo mv -i ec2-api-tools-1.3-30349 /usr/local/ $ sudo ln -s /usr/local/ec2-api-tools-1.3-30349 /usr/local/ec2-api-tools $ export EC2_HOME=/usr/local $ /usr/local/ec2-api-tools/bin/ec2-version 1.3-30349 2008-12-01
次に、環境変数の設定。
pk.pemとcert.pemの保存先を指定する。
- 環境変数設定
- EC2_PRIVATE_KEY
- EC2_CERT
ダウンロード時のpk.pemとcert.pemのファイル名はもっと長い。
pk-********.pemとcert-********.pemと言ったファイル名だ。
今回は汎用性を持たせる為、pk.pemとcert.pemとした。
$ cd ~/ $ mkdir .ec2 $ chmod 700 .ec2 $ cd .ec2 $ cat > pk.pem 内容をコピー&ペースト ^D $ cat > cert.pem 内容をコピー&ペースト ^D $ export EC2_PRIVATE_KEY=$HOME/.ec2/pk.pem $ export EC2_CERT=$HOME/.ec2/cert.pem $ env | egrep ^EC2_ EC2_HOME=/usr/local/ec2-api-tools EC2_PRIVATE_KEY=/home/ubuntu/.ec2/pk.pem EC2_CERT=/home/ubuntu/.ec2/cert.pem
これで準備完了。
$ /usr/local/ec2-api-tools/bin/ec2-describe-instances RESERVATION r-4042d229 650811885664 wakame-default INSTANCE i-93ed9dfa ami-c25eb9ab ec2-75-101-199-66.compute-1.amazonaws.com domU-12-31-39-00-64-68.compute-1.internal running hansode0m1.small 2009-05-11T05:15:30+0000 us-east-1b aki-714daa18 ari-7e4daa17
動作確認としてec2-describe-instancesを実行。
Amazon EC2 API Toolsの動作を確認出来た。
次回は
今回は数多くblogで触れられている内容なので、面白く無い…
次回はMySQLのdatadirとして利用するAmazon EBS。
volumeの作成・削除をするシェルスクリプトを紹介予定。
オライリージャパン
売り上げランキング: 114475
2009/05/09(土) 武道館
去年の武道館ライブでの約束通り、今年も武道館ライブ。
会場入りするまでに長時間待ったので、
今年は会場予定時間17:00を過ぎてから武道館へ足を運んだ。
今年は赤。
去年は青だった。
2枚とも去年とほぼ同じ位置から撮影。
1階スタンド 西A 1列目
去年はアリーナ席だったけど、今年はスタンド席。
スタンドはステージ全体が見える。
後ろの席との段差があるので、
自分の頭が邪魔をして後ろの人が見えない事は避けられた…はず。
メンバーからお客さんへのプレゼント
ライブ翌日が「母の日」だったので、カーネーションが配られた。
母がまだ生きていたら直接渡せたのに。
20周年までは毎年武道館
デビュー20周年までは毎年武道館ライブを行うそうだ。
毎年恒例イベントとなりそうだ。
20周年まで突っ走れ!
BMG JAPAN Inc.(BMG)(M) (2009-04-29)
売り上げランキング: 362
売り上げランキング: 2368
BMG JAPAN Inc.(BMG)(M) (2008-12-10)
売り上げランキング: 9495
2009年05月10日
40日サイクル
髪の毛がまとまらなくなって来たと思ったら散髪の時期。
ざっくり髪をすいてもらった。
涼しい。
何やら海藻のトリートメントがあるそうで、頼んでみた。
たっぷり頭のマッサージをしてもらった。
とても気持ち良い。
- 名前
- AIM PLUS-ONE 下北沢店
- 住所
- 〒155-0031 東京都世田谷区北沢2-30-3 サンセルボンビル2F
- 電話
- 03-3469-8505
- 営業時間
- 10:00〜20:00/定休日(火)
2009年05月08日
手軽にスナップショット取得し、手軽にスレーブをセットアップしたい
複数のMySQL Slaveを作る際の手順が、どうも面倒臭い。
手軽に作成する方法を模索していたら、master.infoをあらかじめ作成する方法に辿り着いた。
- masterに「server-id」と「log_bin」の設定し、mysqld起動(または再起動)
- レプリケーション用MySQLアカウント作成
- masterのテーブルロック
- masterのデータ領域のスナップショット作成
- 「SHOW MASTER STATUS」を実行し、ログファイルとポジションをメモ
- slaveにスナップショットを伸長
- slaveに「server-id」の設定し、mysqld起動
- slaveにて「CHANGE MASTER TO」を実行すると、master.infoが生成される
- master.infoの情報を基に、レプリケーションが行われ、更新されて行く
- →だったら、master.infoを先に作っておいても良いんじゃないか?
master.infoを先に作る
先の手順でも触れた様に、「CHANGE MASTER TO」をすると、master.infoが生成される。
と言う事は、master.infoを作っておけば「CHANGE MASTER TO」を実行しなくて済むはずだ。
その仮説のもとに、master.infoをあらかじめ作ってみたら「CHANGE MASTER TO」を実行しなくても見事同期に成功した。
▼master.infoのフォーマットは下記ページより
http://dev.mysql.com/doc/refman/5.1/ja/slave-logs-status.html
| 行 | 説明 |
|---|---|
| 1: | ファイル内のライン番号 |
| 2: | マスタのバイナリログ名 |
| 3: | マスタのバイナリログ内の現在位置 |
| 4: | マスタのホスト名 |
| 5: | マスタに接続するためのユーザ名 |
| 6: | マスタに接続するためのパスワード |
| 7: | マスタに接続するためのネットワークポート |
| 8: | インターバル時間(秒) |
| 9: | サーバがSSL接続をサポートするかどうかを示す |
| 10: | 証明機関(CA)に使用したファイル |
| 11: | 証明機関(CA)へのパス |
| 12: | SSL証明書のファイル名 |
| 13: | SSL節夫z国使用している暗号法名 |
| 14: | SSLキーファイル名 |
▼サンプルmaster.info
1: 14 2: mysql-bin.000002 3: 98 4: 192.0.2.10 5: repl 6: password 7: 3306 8: 60 9: 0 10: 11: 12: 13: 14:
1行目は14で固定。
2行目〜7行目は「CHANGE MASTER TO」指定項目で見慣れたもの。
8行目〜14行目も固定。(SSL使用時は必要に応じて変更)
一撃スナップショット生成スクリプト「make-mysql-repl-snapshot.sh」
ここまでのスナップショット生成手順をまとめると、下記の通り。
- mysql> FLUSH TABLES WITH READ LOCK;
- datadir/master.infoを生成
- スナップショット作成
- mysql> UNLOCK TABLES;
- ※必要に応じてmaster.infoは削除。しなくても良い。
手順が分かればスクリプトを書ける。
一撃でスナップショットを生成するスクリプトを作成してみた。
#!/bin/sh
#
# http://blog.hansode.org/
#
export PATH=/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin
# mysqld masterの管理項目
mysqld_master_dir=/var/lib/mysql # datadirのパス
mysqld_master_admin_host=127.0.0.1 # MySQL Masterのホスト名(or IPアドレス)
mysqld_master_admin_user=root # MySQL Masterの管理ユーザー名
# master.info生成用設定項目
mysqld_master_info_host=192.0.2.1 # Slaveから見たMasterのホスト名(or IPアドレス)
mysqld_master_info_user=repl # レプリケーション用ユーザー名
mysqld_master_info_pass=password # レプリケーション用パスワード
mysqld_master_info_port=3306 # Slaveから見たMasterのポート番号
# この例では、ホスト名とユーザー名の指定のみ行っている
# 必要に応じて -p などを追加して下さい
mysql_command() {
cat | mysql \
-h${mysqld_master_admin_host} \
-u${mysqld_master_admin_user} \
-s
# -p${mysqld_master_admin_pass} \
# -P${mysqld_master_admin_port} \
}
# connect test
echo "SHOW MASTER STATUS" | mysql_command >/dev/null || {exit 1;}
#
echo "... flush tables with read lock;";
echo "FLUSH TABLES WITH READ LOCK;" | mysql_command
#
echo "... show master status;";
mysqld_master_status=$(echo "SHOW MASTER STATUS;" | mysql_command)
set ${mysqld_master_status}
mysqld_master_binlog_file=$1
mysqld_master_binlog_pos=$2
#
echo "... make master.info"
cat <<EOS > ${mysqld_master_dir}/master.info
14
${mysqld_master_binlog_file}
${mysqld_master_binlog_pos}
${mysqld_master_info_host}
${mysqld_master_info_user}
${mysqld_master_info_pass}
${mysqld_master_info_port}
60
0
EOS
#
chmod 0644 ${mysqld_master_dir}/master.info
chown mysql:mysql ${mysqld_master_dir}/master.info
#
snapshot_id=$(date +%Y%m%d%H%M%S)
snapshot_file=/tmp/mysqld-${snapshot_id}.tar.gz
echo "... make snapshot: ${snapshot_file}"
cd ${mysqld_master_dir}/../
tar zcpf ${snapshot_file} $(basename ${mysqld_master_dir})
#
echo "... unlock tables;";
echo "UNLOCK TABLES;" | mysql_command
#
rm -f ${mysqld_master_dir}/master.info
exit 0
実行例
$ ./make-mysql-repl-snapshot.sh ... flush tables with read lock; ... show master status; ... make master.info ... make snapshot: /tmp/mysqld-20090508081942.tar.gz ... unlock tables;
あとはスナップショットをSalveのdatadirに伸長するだけ。
作業まとめ
master$ sudo vi /etc/my.cnf + [mysqld] + server-id = 1 + log_bin master$ sudo /etc/init.d/mysql restart master$ ./make-mysql-repl-snapshot.sh master$ scp /tmp/mysqld-%Y%m%d%H%M%S.tar.gz slave:/tmp/
slave$ sudo vi /etc/my.cnf + [mysqld] + server-id = 2 slave$ sudo /etc/init.d/msyql stop slave$ cd /var/lib slave$ sudo mv -i mysql _mysql slave$ sudo tar zxvpf /tmp/mysqld-%Y%m%d%H%M%S.tar.gz slave$ sudo /etc/init.d/msyql start
大分簡略化されたけど、これでもまだ手順が多い。
master.info生成法は「簡易量産型」
2台以上のスレーブを作成する時、特に重宝する。
master.info生成法のメリットをまとめてみると、
- スナップショットをdatadirに伸長した後、mysqldを起動するだけでslaveになる
- master.info生成時に「SHOW MASTER STATUS」の情報を一度メモするだけで良い
- slave設定時に「CHANGE MASTER TO」を実行せずに済む
Wakameに組み込む為の検証
今回の内容はWakameに組み込む為の検証の1つ。
次回はAmazon EC2/S3/EBSを使ったレプリケーション設定をご紹介予定。
オライリージャパン
売り上げランキング: 63543
Pragma
売り上げランキング: 27866
2009年05月07日
Xen関連パッケージをholdする
Eucalyptus環境を構築するためにUbuntuを9.04にしたい。
単にupgradeしてしまうとXen関連パッケージまでアップグレードされてしまう。
それを避けるべく、Xen関連パッケージはholdしておく。
対象パッケージを確認
$ dpkg -l | egrep 'xen|python' | awk '{print $2}'
libxen3
linux-image-2.6.24-23-xen
linux-restricted-modules-2.6.24-23-xen
linux-ubuntu-modules-2.6.24-23-xen
python
python-central
python-dev
python-minimal
python-support
python-xen-3.2
python2.5
python2.5-dev
python2.5-minimal
xen-hypervisor-3.2
xen-shell
xen-tools
xen-utils-3.2
holdする
$ sudo dpkg --get-selections | egrep xen | awk '{print $1, " hold"}' | dpkg --set-selections
「hold」になった事を確認
$ dpkg --get-selections | egrep 'xen|python' libxen3 hold linux-image-2.6.24-23-xen hold linux-restricted-modules-2.6.24-23-xen hold linux-ubuntu-modules-2.6.24-23-xen hold python hold python-central hold python-dev hold python-minimal hold python-support hold python-xen-3.2 hold python2.5 hold python2.5-dev hold python2.5-minimal hold xen-hypervisor-3.2 hold xen-shell hold xen-tools hold xen-utils-3.2 hold
これでアップグレード対象から除外される。
/etc/apt/sources.listを変更し、hardyをjauntyにする。
$ sudo cp -pi /etc/apt/sources.list /etc/apt/sources.list-hardy $ sudo perl -pi -e 's,hardy,jaunty,g' /etc/apt/sources.list $ sudo apt-get update $ sudo apt-get dist-upgrade
$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=9.04 DISTRIB_CODENAME=jaunty DISTRIB_DESCRIPTION="Ubuntu 9.04"
無事、Ubuntu 9.04になった。
Debianパッケージは素敵です。
さあ、今度はEucalyptus環境を構築して行く。
2009年05月05日
何ともデリケートな構成
PhenomにXen環境構築(7/n) 少し寝かせよう… から10か月も経過していた。
他の作業が落ち着き、久しぶりに眠ったままのサーバを起動させてみた。
試行錯誤を繰り返しながらも、何とか動いてくれた。
簡単にまとめると、
- Ubuntu 8.04
- Linux 2.6.24
- Xen 3.2
重要視したパッケージ一覧
- libxen3
- linux-image-2.6.24-23-xen
- linux-restricted-modules-2.6.24-23-xen
- linux-ubuntu-modules-2.6.24-23-xen
- python
- python-central
- python-dev
- python-minimal
- python-support
- python-xen-3.2
- python2.5
- python2.5-dev
- python2.5-minimal
- xen-hypervisor-3.2
- xen-shell
- xen-tools
- xen-utils-3.2
作業手順
Xenが動くようにするまでに、かなり強引な作業を続けたので、
下記手順で正しいかどうかに疑問が残る。
- Ubuntu 8.04 Serverをインストール
- apt-get update
- python2.5系をインストール
- xen3.2系をインストール
- linux-image-2.6.24-23-xenをインストール
1年近く経過してようやく動いた。
最新最速マシンに手を出すのはもうやめよう…
その先は
これで終わりではない。
今後はEucalyptus環境を構築していく。
毎日コミュニケーションズ
売り上げランキング: 125284
/etc/logrotate.d/mysql-serverを見たら発見した
とあるサーバにてMySQLのログがローテートされてなかったのでDebianのlogrotate設定を参考にしてみた。
そこには見慣れないpsのオプションがあった。
$ cat /etc/logrotate.d/mysql-server
...(省略)...
if ps cax | grep -q mysqld; then
exit 1
fi
...(省略)...
「ps cax」?何だこれは。
axを指定する事はあっても、cを指定した事がなかった。
$ man ps
...(省略)...
c Show the true command name. This is derived from the
name of the executable file, rather than from the argv
value. Command arguments and any modifications to them
(see setproctitle(3)) are thus not shown. This option
effectively turns the args format keyword into the comm
format keyword; it is useful with the -f format option
and with the various BSD-style format options, which
all normally display the command arguments. See the -f
option, the format keyword args, and the format keyword
comm.
...(省略)...
実際にやってみよう。
cなし
$ ps ax | grep mysqld 3033 ? S 0:00 /bin/sh /usr/bin/mysqld_safe --skip-character-set-client-handshake 3073 ? Sl 0:50 /usr/sbin/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --pid-file=/var/run/mysqld/mysqld.pid --skip-external-locking --port=3306 --socket=/var/run/mysqld/mysqld.sock --skip-character-set-client-handshake 3074 ? S 0:00 logger -p daemon.err -t mysqld_safe -i -t mysqld 17052 pts/9 S+ 0:00 grep mysqld
cあり
$ ps cax | grep mysqld 3033 ? S 0:00 mysqld_safe 3073 ? Sl 0:50 mysqld
なるほど。そう言う事か。
これは便利だ。
cを知らなかった頃
今まで無駄な事をやっていた事に気づかされる。
- $ ps ax | grep mysqld | grep -v grep
-
- 「grep mysqld」がpsの一覧に表れてしまう
- grepコマンドを一覧から除外するために「grep -v grep」
- $ ps ax | egrep '[m]ysqld'
-
- psの一覧からgrepを除外したい
- 「egrep '[m]ysqld'」と正規表現を書く事により、
psの結果には「egrep '[m]ysqld'」が存在し、
「egrep '[m]ysqld'」の条件にはマッチしなくなる - ※grepではなくegrep
いずれの方法でも欠点があった。
mysqldのプロセスとは関係のないプロセス、たとえばファイル名に「mysqld」が含まれるファイルを編集しているプロセスがあった場合にマッチしてしまう。
これをすっきり解決する方法が「cオプション」だった。
オライリージャパン
売り上げランキング: 79971
2009年05月04日
インスタンスのメタデータを出力したい
WakameにMySQLのレプリケーション設定を組み込むための調査で書いたシェルスクリプトをblogにアウトプット。
Instance Metadataに書かれている通り、
http://169.254.169.254/2008-02-01/meta-data/からメタデータを取得出来る。
具体的に何が出て来るのかざっくり見たかったので、シェルスクリプトを書いた。
dump-meta-data.sh
root@ip-10-251-91-3:~/.ec2# cat dump-meta-data.sh
#!/bin/sh
api_base_uri=http://169.254.169.254/2008-02-01/meta-data/
retrieve_meta_data() {
curl -s -f --retry 3 ${api_base_uri}$1
}
meta_data() {
local param=$1
echo ${param} | egrep '/$' -q && {
for i in $(retrieve_meta_data ${param}); do
meta_data ${param}${i}
done
} || {
echo -n "${param} = "
echo $(retrieve_meta_data ${param})
}
}
meta_data /
exit 0
実行結果
root@ip-10-251-91-3:~/.ec2# ./dump-meta-data.sh /ami-id = ami-3c7f9855 /ami-launch-index = 0 /ami-manifest-path = unakatsuo-ami/wakame-0.2-snapshot20090409.manifest.xml /ancestor-ami-ids = ami-9225c0fb ami-4d24c124 ami-be3adfd7 ami-bd1cf9d4 ami-f51aff9c ami-1c5db975 ami-75b0571c ami-8f9176e6 ami-e29f788b ami-59e30430 ami-59ea0d30 ami-bbe80fd2 ami-cef413a7 ami-94f215fd ami-f3ff189a ami-e6fd1a8f ami-bfc720d6 ami-67c4230e ami-72c4231b ami-a9c423c0 ami-bac92ed3 ami-19d43370 ami-81df38e8 ami-b7dd3ade ami-85dd3aec ami-76dc3b1f ami-35dc3b5c ami-0adc3b63 ami-17d93e7e ami-3327c05a ami-3626c15f ami-8c0cebe5 ami-ae1ff8c7 ami-b91ff8d0 ami-6d1ef904 ami-0f668166 ami-2365824a ami-2b6a8d42 ami-de7295b7 /block-device-mapping/ami = sda1 /block-device-mapping/ephemeral0 = sda2 /block-device-mapping/root = /dev/sda1 /block-device-mapping/swap = sda3 /hostname = ip-10-251-91-3.ec2.internal /instance-id = i-cf9ee9a6 /instance-type = m1.small /kernel-id = aki-873bdcee /local-hostname = ip-10-251-91-3.ec2.internal /local-ipv4 = 10.251.91.3 /placement/availability-zone = us-east-1a /public-hostname = ec2-75-101-215-22.compute-1.amazonaws.com /public-ipv4 = 75.101.215.22 /public-keys/0=hansode = /ramdisk-id = ari-853bdcec /reservation-id = r-3bfa6c52 /security-groups = wakame-default
なるほど。
今回使う事になったのは下記2つ。
EBSのボリューム作成時に使う。
- /instance-id
- /placement/availability-zone

![The Cliff(ザ クリフ) 尾川智子 ボルダリングトライアル [DVD]](http://ecx.images-amazon.com/images/I/51RVF9UKoEL._SL160_.jpg)







![DEEN at 武道館 “NO CUT”~15th Anniversary Perfect Singles Live~ [DVD]](http://ecx.images-amazon.com/images/I/417%2BGCgO7zL._SL160_.jpg)

