Backup & Restore Scripts for Percona XtraBackup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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