Skip to content

Instantly share code, notes, and snippets.

@GedowFather
Last active April 11, 2024 10:16
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save GedowFather/4670163 to your computer and use it in GitHub Desktop.
Save GedowFather/4670163 to your computer and use it in GitHub Desktop.
Backup & Restore Scripts for Percona XtraBackup
#!/bin/bash
#
# ============================================================
#
# @license This program is free software.
#
# @category Script for Percona Server
# @project Gedow Software
# @package Gedow Percona Utils
# @author GedowFather http://blog.father.gedow.net/
# @copyright gedow.net All Rights Reserved.
# @version v2.2.1
# @since File available since Release 1.0.0
# @depends percona-xtrabackup >= 2.0.3
# @recommended pigz, pbzip2
#
# =============================================================
#
# Percona Server の Xtrabackup を用いたバックアップスクリプトです。
#
# 処理内容は
# - (Debianの場合) debian.cnf の退避
# - バックアップの取得
# - 既存バックアップファイルの間引き
#
# 下記 config を編集 もしくは --help で表示されるオプションを使うことで、
# 設定を上書きして実行することができます。
#
# 例) /usr/local/bin/percona_backup.sh \
# -u root -p password \
# -d /var/mysql_backup --file-prefix SERVICENAME
#
# この場合、指定のディレクトリにサービス名と今日の日付でファイルが作成されます
# もしファイル名を完全に指定したい場合は --file-name を利用してください。
#
# アーカイブ化の並列処理数指定(xbstreamのみ)
# --archive-threads 4
# 最大でも 4 で十分な処理ができます。
# CPUは400%まで利用せず、200%程度までとなります。
#
# 圧縮方法の指定
# --compress-type に圧縮コマンドを指定することができます。指定値は gzip, bzip2 ですが、
# それぞれ pigz, pbzip2 コマンドが存在する場合は並列圧縮を実行します。
# 並列数を指定しない場合は自動的に1スレッド残した最大数になります。
#
# ex) --compress-type gzip --compress-threads 10
# --compress-type bzip2 --compress-threads 10
#
# 圧縮CPUはスレッド数 * 100% が稼働すると仮定して指定してください。
# 基本的に多ければ多いほど処理時間が短くなります。
#
PATH=/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
DATE_FORMAT="+%Y-%m-%d %H:%M:%S"
###########################################################
#
# 設定
#
#
# 定数
#
MYSQL_USER=root # MySQL接続用ユーザ
MYSQL_PASS=password # MySQL接続用パスワード
BACKUP_DIR=/var/mysql_backup # バックアップ保存ディレクトリ
FILE_PREFIX="xtrabackup" # バックアップファイル名の先頭
FILE_TIMESTAMP=`date "+%Y%m%d_%H%M%S"` # バックアップファイル名の日時
FILE_NAME="" # オプションで直指定か無ければ上記3項目の連結
STREAM_TYPE=xbstream # tar or xbstream
ARCHIVE_THREADS=4 # xbstream時のみ、--parallel 並列処理数指定
COMPRESS_TYPE="bzip2" # パイプで渡す圧縮コマンド
COMPRESS_THREADS= # 並列圧縮コマンドを利用する場合のスレッド数
COMPRESS_TYPES=(gzip bzip2) # 利用可能な圧縮コマンドのリスト
COMPRESS_EXTENSIONS=(gz bz2) # 圧縮形式に対応した拡張子のリスト
# 上記2配列は必ずセットの値にすること
COMPRESS_PARALLELS=(pigz pbzip2) # 対応する圧縮形式で、こちらのコマンドが存在する場合は優先して利用する
DEBIAN_CONFIG=/etc/mysql/debian.cnf # DebianのMySQL管理者情報ファイル
DEBIAN_DUMMY_NAME=debian.cnf.CSV # バックアップ一式に含ませるためデータディレクトリに入れる時の名前
LATEST_LINK=LATEST # 保存ディレクトリと同階層に置く最新ファイルへのリンク
FIND_DELETE_CONDITION="-mtime +3 ! -name '*01_*.gz' ! -name '*15_*.gz'"
# find -delete のよる間引き条件。
# 例は3日以上経過だが1日と15日のファイルを除いている
#
# オプション
#
exit_usage() {
echo "Usage: this.sh [-h|--help] [-u|--user MYSQL_USER] [-p|--pass MYSQL_PASS] "
echo " [-d|--backup-dir BACKUP_DIR] [-f|--file-name FILE_NAME] [--file-prefix FILE_PREFIX]"
echo " [--stream-type tar|xbstream] [--archive-threads #]"
echo " [--compress-type gzip|bzip2] [--compress-threads #]"
echo " [--delete-condition FIND_DELETE_CONDITION]"
exit 1
}
OPTSHORT="hu:p:d:f:"
OPTLONG="help,user:,pass:,backup-dir:,file-name:,file-prefix:"
OPTLONG+=",stream-type:,archive-threads:,compress-type:,compress-threads:,delete-condition:"
GETOPT=`getopt -q -o $OPTSHORT -l $OPTLONG -- "$@"`
[ $? != 0 ] && exit_usage
eval set -- "$GETOPT"
while true
do
case $1 in
-h|--help) exit_usage ;;
-u|--user) MYSQL_USER=$2; shift 2;;
-p|--pass) MYSQL_PASS=$2; shift 2;;
-d|--backup-dir) BACKUP_DIR=$2; shift 2;;
-f|--file-name) FILE_NAME=$2; shift 2;;
--file-prefix) FILE_PREFIX=$2; shift 2;;
--stream-type) STREAM_TYPE=$2; shift 2;;
--archive-threads) ARCHIVE_THREADS=$2; shift 2;;
--compress-type) COMPRESS_TYPE=$2; shift 2;;
--compress-threads) COMPRESS_THREADS=$2; shift 2;;
--delete-condition) FIND_DELETE_CONDITION=$2; shift 2;;
--) shift; break ;;
*) exit_usage ;;
esac
done
#
# Validation
#
# STREAM_TYPE
[ "$STREAM_TYPE" != "tar" -a "$STREAM_TYPE" != "xbstream" ] && exit_usage
#
# 圧縮に利用できる最大CPUスレッド数を自動設定
# - ただしオプション指定されていない場合に限る
# - 総スレッド数 から xtrabackupの並列数 と SLAVE用に 1 引いた数値
# - SLAVEは通常2スレッド、Semiで1スレッドだがparallelはMAXまでCPUを使わないので問題ない
if [ -z "$COMPRESS_THREADS" ];
then
os_threads=`grep ^processor /proc/cpuinfo | wc -l`
COMPRESS_THREADS=`expr $os_threads - $ARCHIVE_THREADS - 1`
[ $COMPRESS_THREADS -le 0 ] && COMPRESS_THREADS=1
fi
#
# 圧縮方法の確認と並列処理への切替
#
# 配列もどき作成
count=0
for key in ${COMPRESS_TYPES[@]}
do
eval COMPRESS_EXTENSION_OF_$key=${COMPRESS_EXTENSIONS[$count]}
eval COMPRESS_PARALLEL_OF_$key=${COMPRESS_PARALLELS[$count]}
count=`expr $count + 1`
done
# 拡張子の確定
COMPRESS_EXTENSION=`eval echo "\\$COMPRESS_EXTENSION_OF_$COMPRESS_TYPE"`
if [ -z "$COMPRESS_EXTENSION" ];
then
echo "$COMPRESS_TYPE is invalid command."
echo "Check COMPRESS_TYPES value."
exit 1
fi
# 圧縮コマンドの存在確認
type $COMPRESS_TYPE > /dev/null
if [ $? -ne 0 ];
then
echo "You need '$COMPRESS_TYPE' command."
echo "Retry after installing $COMPRESS_TYPE package."
exit 1
fi
# 対応する並列圧縮コマンドがあれば切り替える
COMPRESS_PARALLEL=`eval echo "\\$COMPRESS_PARALLEL_OF_$COMPRESS_TYPE"`
if [ ! -z "$COMPRESS_PARALLEL" ];
then
type $COMPRESS_PARALLEL > /dev/null
if [ $? -eq 0 ];
then
COMPRESS_TYPE="$COMPRESS_PARALLEL -p$COMPRESS_THREADS"
echo "COMPRESS_TYPE is changed to $COMPRESS_TYPE."
echo
fi
fi
#
# 変数
#
MYSQL_OPTION="--user=$MYSQL_USER --password=$MYSQL_PASS"
FILE_EXTENSION=".$STREAM_TYPE.$COMPRESS_EXTENSION"
FILE_NAME=${FILE_NAME:-"$FILE_PREFIX-$FILE_TIMESTAMP$FILE_EXTENSION"}
##########################################################
#
# 開始表示
#
echo `date "$DATE_FORMAT"`" starting backup."
###########################################################
#
# バックアップ
#
#
# 可動チェック
#
output=`mysqladmin $MYSQL_OPTION ping 2>&1`
result=`echo "$output" | grep alive`
if [ $? != 0 ];
then
echo "$output"
exit 1
fi
#
# Debian専用my.cnfのコピー
# - サーバのシャットダウン時などの管理作業に必要なため
# 無理矢理データディレクトリに入れておき、リストア時に取り出して復旧する
#
if [ -f "$DEBIAN_CONFIG" ];
then
query="SHOW GLOBAL VARIABLES like 'datadir';"
datadir=`echo "$query" | mysql --skip-column-names $MYSQL_OPTION | awk '{ print $2 }'`
dst_file=${datadir}/mysql/${DEBIAN_DUMMY_NAME}
cp $DEBIAN_CONFIG $dst_file
fi
#
# バックアップ取得
#
save_file=$BACKUP_DIR/$FILE_NAME
latest_link=$BACKUP_DIR/$LATEST_LINK
mkdir -p -m 0755 $BACKUP_DIR
innobackupex --user=$MYSQL_USER --password=$MYSQL_PASS \
--slave-info --stream=$STREAM_TYPE --parallel=$ARCHIVE_THREADS \
$BACKUP_DIR | $COMPRESS_TYPE > $save_file
chmod 644 $save_file
ln -nfs $save_file $latest_link
###########################################################
#
# 間引き
#
find $BACKUP_DIR -type f $FIND_DELETE_CONDITION -delete
###########################################################
#
# 終了表示
#
echo
echo `date "$DATE_FORMAT"`" finished backup '$save_file'"
echo
exit 0
#!/bin/bash
#
# ============================================================
#
# @license This program is free software.
#
# @category Script for Percona Server
# @project Gedow Software
# @package Gedow Percona Utils
# @author GedowFather http://blog.father.gedow.net/
# @copyright gedow.net All Rights Reserved.
# @version v2.2.1
# @since File available since Release 1.0.0
# @depends percona-xtrabackup >= 2.0.3
# @recommended pigz, pbzip2
#
# =============================================================
#
# Percona Server の Xtrabackup を用いたリストアスクリプトです
#
# 処理内容は
# - リストア実行可否のチェック
# - バックアップファイルの解凍
# - リストア準備
# - リストア実行
# - レプリケーションの開始
#
# 下記 config を編集 もしくは --help で表示されるオプションを使うことで、
# 設定を上書きして実行することができます。
#
# 例) /usr/local/bin/percona_restore.sh \
# -u root -p password \
# -d /fio/mysql/ -l /fio/mysql_log/ -t /fio/mysql_tmp/ \
# -f /var/tmp/mysql_backup/xtrabackup-20121001_012345.tar.gz \
# --master-host 10.0.0.1 --master-user USER --master-pass PASSWORD
#
# 【ロック】
# 誤実行を防ぐため、既にリストア済み、もしくはレプリケーション開始済みのサーバでは
# エラーを吐いて中止されます。その場合、ロックファイルを削除してから(--unlock)
# 再実行するか、または強制的に実行します(--force)。
#
# 【レプリケーション】
# バックアップにbinlog情報(xtrabackup_binlog_info)が存在した状態で
# オプションに --master-host, --master-user, --master-pass を全てつけると
# 自動的にレプリケーションを開始します。
#
# MASTERのSLAVEなのか、SLAVEのSLAVEなのか、SLAVEと同じMASTERを持つSLAVEなのか
# といった配置についてはログ情報の有無により自動的に判断しますが、
# どちらにもなり得る場合は --slave-position により強制できます(設定コメント参照)
#
# レプリケーションが成功したかは、標準出力の最後の方の
# Slave_IO_Running, Slave_SQL_Running がどちらもYesになることで確認できます。
#
# 【解凍】
# バックアップファイルの拡張子が .gz なら gzip, .bz2 なら bzip2 を使って解凍しますが、
# pigz, pbzip2 コマンドが存在する場合、自動的にこちらを優先して使用します。
# 並列数は自動的に最大まで利用します。
#
PATH=/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
DATE_FORMAT="+%Y-%m-%d %H:%M:%S"
###########################################################
#
# 設定
#
MYSQL_USER=root
MYSQL_PASS=password
BACKUP_FILE=/path/to/xtrabackup.tar.gz # バックアップファイル
DATA_DIR=/fio/mysql/ # データディレクトリ(datadir)
TMP_DIR=/fio/mysql_tmp # tmpディレクトリパス(tmpdir)
LOG_DIR=/fio/mysql_log # ログファイルのトップディレクトリパス
LOCK_FILE=/var/tmp/percona_restore.lock # リストア処理開始済みを表し、重複実行を抑制するロックファイル
FORCE=No # Yesにすると、レプリケーション開始済み・ロック済みなら
# リストアを中止するといった条件を無視して実行する
UNLOCK=No # Yesにすると、ロックを解除して処理を終了します
COMPRESS_TYPES=(gzip bzip2) # 利用可能な圧縮コマンドのリスト
COMPRESS_EXTENSIONS=(gz bz2) # 圧縮形式に対応した拡張子のリスト
# 上記2配列は必ずセットの値にすること
COMPRESS_PARALLELS=(pigz pbzip2) # 対応する圧縮形式で、こちらのコマンドが存在する場合は優先して利用する
MASTER_HOST= # MASTERのホスト
MASTER_PORT=3306 # MASTERのポート
MASTER_USER= # MASTERのレプリケーションユーザ
MASTER_PASS= # MASTERのレプリケーションパスワード
SLAVE_POSITION=serial # serial or parallel
# 取得元サーバでlog-bin,relay-logのどちらが有効だったか、
# またはどちらも有効だったか、によってどこをMASTERとするか決める
#
# log-binの場合は取得元がMASTERとなり(直列 serial)、
# SLAVEのSLAVEを作る場合も同様に、
# [MASTER(Backup)] -> [SLAVE(Restore)]
# relay-logの場合は取得元のMASTERをMASTERとする(並列 parallel)
# [MASTER] -> [SLAVE(Backup)]
# -> [SLAVE(Restore)]
# 両方ある場合はこの設定で強制的に選択する
DEBIAN_CONFIG=/etc/mysql/debian.cnf # DebianのMySQL管理者情報ファイル
DEBIAN_DUMMY_NAME=debian.cnf.CSV # バックアップ一式に含ませるためデータディレクトリに入れる時の名前
DEVICE_USAGE_PERCENGATE_LIMIT=60 # 既にデバイス利用率がこの%を超えている場合エラーとなる
INNODB_LOGFILE_NAME=ib_logfile # move-backでログファイルが移動しないバグ対策用
# innodb_log_group_home_dir は設定せず、DATADIR直下である前提とする
#
# オプション
#
exit_usage() {
echo "Usage: this.sh [-h|--help] [-u|--user USER] [-p|--pass PASS] "
echo " [-f|--file BACKUP_FILE] [-d|--data-dir DATA_DIR]"
echo " [-l|--log-dir LOG_DIR] [-t|--tmp-dir TMP_DIR]"
echo " [--master-host MASTER_HOST] [--master-port MASTER_PORT]"
echo " [--master-user MASTER_USER] [--master-pass MASTER_PASSWORD]"
echo " [--slave-position serial|parallel]"
echo " [--force] [--unlock]"
exit 1
}
OPTSHORT="hu:p:f:d:l:t:"
OPTLONG="help,user:,pass:,file:,data-dir:,log-dir:,tmp-dir:"
OPTLONG+=",master-host:,master-port:,master-user:,master-pass:,slave-position:"
OPTLONG+=",force,unlock,use-memory:"
GETOPT=`getopt -q -o $OPTSHORT -l $OPTLONG -- "$@"`
[ $? != 0 ] && exit_usage
eval set -- "$GETOPT"
while true
do
case $1 in
-h|--help) exit_usage ;;
-u|--user) MYSQL_USER=$2; shift 2;;
-p|--pass) MYSQL_PASS=$2; shift 2;;
-f|--file) BACKUP_FILE=$2; shift 2;;
-d|--data-dir) DATA_DIR=$2; shift 2;;
-l|--log-dir) LOG_DIR=$2; shift 2;;
-t|--tmp-dir) TMP_DIR=$2; shift 2;;
--master-host) MASTER_HOST=$2; shift 2;;
--master-port) MASTER_PORT=$2; shift 2;;
--master-user) MASTER_USER=$2; shift 2;;
--master-pass) MASTER_PASS=$2; shift 2;;
--slave-position) SLAVE_POSITION=$2; shift 2;;
--force) FORCE=Yes; shift;;
--unlock) UNLOCK=Yes; shift;;
--) shift; break ;;
*) exit_usage ;;
esac
done
#
# Validation
#
# SLAVE_POSITION
[ "$SLAVE_POSITION" != "serial" -a "$SLAVE_POSITION" != "parallel" ] && exit_usage
#
# ファイル拡張子から解凍コマンドの選択、そして並列処理への切替
#
# 配列もどき作成
count=0
for key in ${COMPRESS_EXTENSIONS[@]}
do
eval COMPRESS_TYPE_OF_$key=${COMPRESS_TYPES[$count]}
eval COMPRESS_PARALLEL_OF_$key=${COMPRESS_PARALLELS[$count]}
count=`expr $count + 1`
done
# 拡張子から解凍コマンドの確定
COMPRESS_EXTENSION=${BACKUP_FILE##*.}
COMPRESS_TYPE=`eval echo "\\$COMPRESS_TYPE_OF_$COMPRESS_EXTENSION"`
if [ -z "$COMPRESS_TYPE" ];
then
echo "$COMPRESS_EXTENSION is invalid command."
echo "Check COMPRESS_EXTENSIONS value."
exit 1
fi
# 圧縮コマンドの存在確認
type $COMPRESS_TYPE > /dev/null
if [ $? -ne 0 ];
then
echo "You need '$COMPRESS_TYPE' command."
echo "Retry after installing $COMPRESS_TYPE package."
exit 1
fi
# 対応する並列圧縮コマンドがあれば切り替える
COMPRESS_PARALLEL=`eval echo "\\$COMPRESS_PARALLEL_OF_$COMPRESS_EXTENSION"`
if [ ! -z "$COMPRESS_PARALLEL" ];
then
type $COMPRESS_PARALLEL > /dev/null
if [ $? -eq 0 ];
then
COMPRESS_TYPE="$COMPRESS_PARALLEL"
echo "COMPRESS_TYPE is changed to $COMPRESS_TYPE."
echo
fi
fi
#
# アーカイブ形式(tar|xbstream)の取得
#
archive_path=${BACKUP_FILE%.*}
ARCHIVE_TYPE=${archive_path##*.}
if [ "$ARCHIVE_TYPE" != "tar" -a "$ARCHIVE_TYPE" != "xbstream" ];
then
echo "ARCHIVE_TYPE is invalid value."
echo "Backup file name must be .(tar|xbstream).(gz|bzip2)$"
exit 1
fi
#
# 変数
#
WORK_DIR=`dirname $BACKUP_FILE`/work
MYSQL_OPTION="--user=$MYSQL_USER --password=$MYSQL_PASS"
LOG_BIN_DIR=$LOG_DIR/bin # バイナリログの保存ディレクトリ
LOG_RELAY_DIR=$LOG_DIR/relay # リレーログの保存ディレクトリ
LOG_SYSTEM_DIR=$LOG_DIR/system # エラーログやスロークエリの保存ディレクトリ
###########################################################
#
# 関数
#
#
# 第1引数にフィールド名を入力するとSLAVE STATUSの値を返す
#
get_slave_status () {
echo 'SHOW SLAVE STATUS \G' | mysql $MYSQL_OPTION | \
grep "$1:" | sed -e 's/^ *//g' -e 's/: */:/g' | awk -F: '{print $2}'
}
#
# 空きメモリ容量の取得(単位:MB)
#
get_free_memory () {
local MemFree=` cat /proc/meminfo | grep MemFree: | awk '{print $2}'`
local Inactive=`cat /proc/meminfo | grep Inactive: | awk '{print $2}'`
expr \( $MemFree + $Inactive \) / 1024
}
###########################################################
#
# 開始表示
#
echo `date "$DATE_FORMAT"`" starting restore."
###########################################################
#
# --unlock によるロック解除処理
#
#
# ロックファイルの削除だけを行って終了
#
if [ "$UNLOCK" = "Yes" ];
then
if [ -f $LOCK_FILE ];
then
rm $LOCK_FILE
fi
echo "unlock!! you can now restore."
exit 0
fi
###########################################################
#
# リストアの可否をチェック
#
#
# バックアップファイルが存在するか
#
if [ ! -f "$BACKUP_FILE" ];
then
echo "Could not find $BACKUP_FILE"
echo "or no input -f|--file BACKUP_FILE."
exit_usage
exit 1
fi
#
# 自動的にレプリケーションを開始する場合、
# 必須の3つの値が入力されていること
# (条件説明:1つ以上入力されているのに3つ揃っていない)
#
if [ -z "$MASTER_HOST" -o -z "$MASTER_USER" -o -z "$MASTER_PASS" ];
then
if ! [ -z "$MASTER_HOST" -a -z "$MASTER_USER" -a -z "$MASTER_PASS" ];
then
echo "for starting replication, please specify 3 options"
echo " --master-host, --master-user, --master-pass"
echo
exit_usage
fi
fi
#
# リストア済み(ロックファイルが存在する)の場合、エラーとして終了する。
# --force をつけると無視される。
# 主に自動SLAVE化の重複実行回避のため。
#
if [ "$FORCE" = "No" -a -f "$LOCK_FILE" ];
then
echo "On this server, restore have already done."
echo "If you want to restore on this server, add --force option or --unlock once."
echo "aborted restore."
exit 1
fi
#
# 既にレプリケーションが開始していた場合、運用中と判断して終了する
# --force をつけると無視される。
#
ps -C mysqld --no-heading
run_mysql=$?
if [ "$FORCE" = "No" -a $run_mysql -eq 0 ];
then
Slave_IO_Running=` get_slave_status Slave_IO_Running`
Slave_SQL_Running=`get_slave_status Slave_SQL_Running`
if [ "$Slave_IO_Running" = "Yes" -o "$Slave_SQL_Running" = "Yes" ];
then
echo "This server is already starting replication."
echo "aborted restore."
exit 1
fi
fi
#
# データディレクトリのパーティション容量%が設定値を超えているとエラー
#
for row in `df -B1 -P | grep ^/ | awk '{ print $6 ":" $5 }' | sort -r`
do
partition=` echo "$row" | awk -F: '{ print $1 }'`
percentage=`echo "$row" | awk -F: '{ print $2 }' | sed -e 's/%//'`
if expr "$DATA_DIR" : "^$partition" >/dev/null; then
break;
fi
done
if [ $percentage -ge $DEVICE_USAGE_PERCENGATE_LIMIT ];
then
echo "$partition usage percentage is over ${DEVICE_USAGE_PERCENGATE_LIMIT}%."
echo "Please try again to delete unnecessary files."
exit 1
fi
###########################################################
#
# ロックファイルの作成
#
touch $LOCK_FILE
if [ $? != 0 ];
then
echo "Could not create $LOCK_FILE."
exit 1
fi
###########################################################
#
# リストア準備
#
#
# バックアップファイルの解凍
#
echo `date "$DATE_FORMAT"`" uncompress $BACKUP_FILE to $WORK_DIR"
[ -d "$WORK_DIR" ] && rm -R $WORK_DIR
mkdir -p $WORK_DIR
cd $WORK_DIR
case $ARCHIVE_TYPE in
tar)
tar ixf $BACKUP_FILE -C $WORK_DIR --use-compress-program $COMPRESS_TYPE
;;
xbstream)
$COMPRESS_TYPE -cd $BACKUP_FILE | xbstream -x
;;
*)
echo "$file_name is unknown file type."
echo "you can specify .(tar|xbstream).(gz|bzip2)"
exit 1
;;
esac
#
# prepareの実行
#
# 空きメモリの半分を使用する
USE_MEMORY=`eval "expr \`get_free_memory\` / 2"`M
innobackupex --user=$MYSQL_USER --password=$MYSQL_PASS \
--apply-log --use-memory=$USE_MEMORY \
$WORK_DIR
###########################################################
#
# リストア実行
#
#
# MySQLが起動していたら停止し、データディレクトリを退避
#
ps -C mysqld --no-heading && /etc/init.d/mysql stop
if [ -d "$DATA_DIR" ];
then
MV_PATH=`dirname $DATA_DIR`"/_mysql_data~"`date +%Y%m%d_%H%M%S`
mv $DATA_DIR $MV_PATH
echo
echo "moved original datadir to $MV_PATH"
fi
#
# データディレクトリとログディレクトリを作成
#
mkdir -p -m 0700 $DATA_DIR $TMP_DIR
mkdir -p $LOG_BIN_DIR $LOG_RELAY_DIR $LOG_SYSTEM_DIR
chown -R mysql:mysql $DATA_DIR $LOG_DIR $TMP_DIR
#
# データをデータディレクトリに戻す
#
innobackupex --move-back $WORK_DIR
# INNODBログファイルが移動しないバグ対策
if [ -f "${WORK_DIR}/${INNODB_LOGFILE_NAME}0" ];
then
mv ${WORK_DIR}/${INNODB_LOGFILE_NAME}* $DATA_DIR/
fi
# 権限調整
chown -R mysql:mysql $DATA_DIR
find $DATA_DIR -type f -exec chmod 0660 {} \;
find $DATA_DIR -type d -exec chmod 0700 {} \;
#
# バイナリログ情報がある場合はデータディレクトリにコピーしておく
# - xtrabackup_binlog_pos_innodb はCHANGE MASTERには使えないので注意
#
if [ -f "$WORK_DIR/xtrabackup_binlog_info" ];
then
cp $WORK_DIR/xtrabackup_binlog_info $DATA_DIR/
fi
#
# Debianの場合
# debian.cnf を取り出し、設定置き場に戻す
#
debian_dummy_file=$DATA_DIR/mysql/$DEBIAN_DUMMY_NAME
if [ -f "$debian_dummy_file" ];
then
mv $DEBIAN_CONFIG ${DEBIAN_CONFIG}~orig-`date "+%Y%m%d_%H%M%S"`
mv $debian_dummy_file $DEBIAN_CONFIG
fi
#
# MySQLを起動
# InnoDBログファイルができて、DB接続できるまで待機
#
/etc/init.d/mysql start
echo -n "waiting for success connection (esp until making innodb log files)."
count=1
until=60
while [ $count -lt $until ]
do
output=`mysqladmin --connect_timeout=1 $MYSQL_OPTION ping 2> /dev/null`
result=`echo "$output" | grep alive`
if [ $? = 0 ]; then break; fi
count=`expr $count + 1`
echo -n " ."
sleep 1
done
echo " connecting!!"
rm -R $WORK_DIR
###########################################################
#
# レプリケーション開始
#
#
# バイナリログ情報ファイル
#
BINLOG_INFO=${DATA_DIR}/xtrabackup_binlog_info
SLAVE_INFO=${DATA_DIR}/xtrabackup_slave_info
#
# バイナリログ情報の有効無効判断
#
ACTIVE_BINLOG_INFO=0
if [ -f $BINLOG_INFO ];
then
grep "[0-9]" $BINLOG_INFO > /dev/null 2>&1
[ $? -eq 0 ] && ACTIVE_BINLOG_INFO=1
fi
ACTIVE_SLAVE_INFO=0
if [ -f $SLAVE_INFO ];
then
grep "[0-9]" $SLAVE_INFO > /dev/null 2>&1
[ $? -eq 0 ] && ACTIVE_SLAVE_INFO=1
fi
#
# レプリケーションを開始する必要が無ければ終了する
#
OK_LOG_INFO=0
OK_MASTER=0
[ $ACTIVE_BINLOG_INFO -eq 1 -o $ACTIVE_SLAVE_INFO -eq 1 ] && OK_LOG_INFO=1
[ ! -z "$MASTER_HOST" -a ! -z "$MASTER_USER" -a ! -z "$MASTER_PASS" ] && OK_MASTER=1
if [ $OK_LOG_INFO -eq 0 -o $OK_MASTER -eq 0 ];
then
echo
echo "see also MASTER STATUS $BINLOG_INFO"
echo "see also SLAVE STATUS $SLAVE_INFO"
echo
echo `date "$DATE_FORMAT"`" finished restore."
echo
exit 0
fi
#
# バックアップ条件ごとにMASTERデータ取得方法を変更
# - 両方とも有効だった場合はオプションで強制選択
# (指定が無い場合は取得元の下につく直列型とする)
# - log-binのみ有効だった
# - relay-logのみ有効だった
#
if [ $ACTIVE_BINLOG_INFO -eq 1 -a $ACTIVE_SLAVE_INFO -eq 1 ]; then
LOG_TYPE=$SLAVE_POSITION
elif [ $ACTIVE_BINLOG_INFO -eq 1 ]; then
LOG_TYPE=serial
else
LOG_TYPE=parallel
fi
# 条件別にクエリ作成
if [ $LOG_TYPE = "serial" ];
then
# バックアップを取得したサーバのバイナリログ位置を取得
MASTER_LOG_FILE=`eval "basename \`cat $BINLOG_INFO | awk '{print $1'}\`"`
MASTER_LOG_POS=` cat $BINLOG_INFO | awk '{print $2'}`
# SLAVE用に合わせて途中までクエリ作成
query="CHANGE MASTER TO MASTER_LOG_FILE='$MASTER_LOG_FILE', MASTER_LOG_POS=$MASTER_LOG_POS"
else
# SLAVE parallel用
query=`cat $SLAVE_INFO`
fi
# 完成クエリ
query+=", MASTER_HOST='$MASTER_HOST', MASTER_PORT=$MASTER_PORT,
MASTER_USER='$MASTER_USER', MASTER_PASSWORD='$MASTER_PASS';
START SLAVE;"
#
# レプリケーション開始
#
result=`echo "$query" | mysql $MYSQL_OPTION`
sleep 1
# SLAVEステータスをチェック
Slave_IO_Running=` get_slave_status Slave_IO_Running`
Slave_SQL_Running=`get_slave_status Slave_SQL_Running`
echo
echo "START SLAVE ... statuses are"
echo " * Slave_IO_Running : $Slave_IO_Running"
echo " * Slave_SQL_Running: $Slave_SQL_Running"
echo
if [ "$Slave_IO_Running" != "Yes" -o "$Slave_SQL_Running" != "Yes" ];
then
Last_IO_Error=`get_slave_status Last_IO_Error`
echo "Replication failed !! error message is ..."
echo " * $Last_IO_Error"
exit 1
fi
###########################################################
#
# 終了表示
#
echo
echo `date "$DATE_FORMAT"`" finished restore."
echo
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment