MySQL スレーブを便利に作るためのスクリプト

April 15th, 2009 by naoya | Filed under day.

MySQL スレーブを増やすには、/var/lib/mysql ディレクトリをコピーする方法が一般的かもしれないけれど、個人的には毎日 mysqldump している SQL を流したい。そこで、次のようなスクリプトを作ってみた。このスクリプトは、「データベース名_mysql-bin.ログファイル名_ログポジション.sql」という名前の mysqldump した SQL ファイルを流して Slave を作るだけの簡単なシェルスクリプト。(puppet template なので一部おかしいですが、最初の変数定義だけです)

#!/bin/sh

DATABASE=<%= mysql_database_name %>
MASTER_HOST=<%= mysql_master_host %>
MASTER_USER=<%= mysql_repl_user %>
MASTER_PASSWORD=<%= mysql_repl_password %>

function create_slave()
{
SQL_FILE=$1
if [ ! -f $SQL_FILE ]; then
echo Could not found sql file – $SQL_FILE
exit -1
fi

LOG_FILE=`echo $SQL_FILE | cut -d ‘.’ -f 2 | cut -d ‘_’ -f 1`
if [ -z $LOG_FILE ]; then
echo Log file name is empty
exit -1
fi
LOG_POS=`echo $SQL_FILE | cut -d ‘.’ -f 2 | cut -d ‘_’ -f 2`
if [ -z $LOG_POS ]; then
echo Log position is empty
exit -1
fi

mysql -u root $DATABASE < $1
mysql -u root -e “CHANGE MASTER TO MASTER_HOST=’$MASTER_HOST’, MASTER_USER=’$MASTER_USER’, MASTER_PASSWORD=’$MASTER_PASSWORD’, MASTER_LOG_FILE=’mysql-bin.$LOG_FILE’,
MASTER_LOG_POS=$LOG_POS”
mysql -u root -e “START SLAVE”
}

echo -n “Are you sure want to create mysql slave server? [y/N] ”
read INPUT
if [ -z $INPUT ]; then

INPUT=n
fi

if [ $INPUT == 'y' ]; then
if [ ! -f $1 ]; then
echo Usage: `basename $0` \”SQL file\”:
exit -1
fi

if [ ! -f /var/lock/subsys/mysqld ]; then
echo MySQL is not running
exit -1
fi

create_slave $1
exit 0
else
exit -1
fi

近々の予定では、結果を IRC に通知したい。puppet でがんばって自動的に Slave を作ろうとしたけれどけっこう無理があったし、それほど Slave を増やすことはないので手っ取り早くシェルスクリプトにした。

それで、この SQL ファイルを mysqldump するシェルスクリプトも必要なのであわせて作った。これは引数に対象のデータベース名を指定するだけ。

#!/bin/sh

if [ x"$1" = "x" ]; then
echo Usage: `basename $0` \”Database name\”
exit -1
fi
DATABASE=$1

MYSQLDUMP=/usr/bin/mysqldump
if [ ! -x $MYSQLDUMP ]; then
exit -1
fi

if [ ! -f /var/lock/subsys/mysqld ]; then
echo “MySQL server is not running.”
exit -1
fi

LOG_FILE=`echo ’show slave status\G’ | mysql -u root | egrep ‘Relay_Master_Log_File:’
| tr -d ‘ ‘ | cut -d ‘:’ -f 2`
LOG_POS=`echo ’show slave status\G’ | mysql -u root | egrep ‘Read_Master_Log_Pos:’ |
tr -d ‘ ‘ | cut -d ‘:’ -f 2`
if [ -z $LOG_FILE ]; then
echo “Log file name is empty.”
exit -1
fi
if [ -z $LOG_POS ]; then
echo “Log position is empty.”
exit -1
fi

mysqldump -u root –databases ${DATABASE} > ${DATABASE}_${LOG_FILE}_${LOG_POS}.sql

もっとも効率的な MySQL Slave サーバの作り方を知りたいところ。

# 追伸

最近、知ったけれど mysqldump すると、あたりまえだけれど次のクエリーがスローログとして報告されることがあるので、定期的に mysqldump してバックアップしているサーバではスローログを監視しないように注意しましょう。

# Time: 090415  4:35:30
# User@Host: root[root] @ localhost []
# Query_time: 27  Lock_time: 0  Rows_sent: 2234711  Rows_examined: 2234711
SELECT /*!40001 SQL_NO_CACHE */ * FROM `hoge_hoges`;

Tags:

Leave a Reply

Get Adobe Flash playerPlugin by wpburn.com wordpress themes