2009年05月14日

[Wakame] Amazon EC2 API Toolsを使ってMySQL Slaveを作る (2/n)

livedoorClipに登録 | このエントリーをはてなブックマークに追加 | del.icio.usに登録 | MM/Memoに登録

[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をマウントした設定。

  1. MySQL Master
    • datadirにAmazon EBSを使う
    • MySQL Masterのdatadirのsnapshot生成
  2. MySQL Slave
    • 生成したsnapshotからMySQL Slave用のdatadirを作成

変更履歴

2009/05/15 16:30
_wakame-common.shの内容修正
  • ec2_local_ipv4を追加
  • mysqld_master_info_hostの値を${ec2_local_ipv4}へ



詳解 シェルスクリプト
アーノルド ロビンス ネルソン・H.F. ベーブ
オライリージャパン
売り上げランキング: 117000


半袖 at 16:10│Comments(0)TrackBack(1)Wakame 

トラックバックURL

この記事へのトラックバック

1. [Wakame] Amazon EC2 API Toolsを使ってMySQL Slaveを作る (3/n)  [ 半袖野郎 blog.hansode.org ]   2009年05月15日 20:01
[Wakame] Amazon EC2 API Toolsを使ってMySQL Slaveを作る (2/n) の続編 前回予告した通り、今回はMySQLのdatadirにAmazon EBS Volumeをマウントした設定。 今回の作業前提条件は、 MySQL Master master用my.cnfが存在する datadir = /home/wak...

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔