mirror of
https://github.com/MariaDB/server.git
synced 2026-05-15 11:27:39 +02:00
Merge 10.0 to galera-10.0
This commit is contained in:
commit
ba3ff50ab2
3269 changed files with 158427 additions and 57354 deletions
481
scripts/wsrep_sst_xtrabackup.sh
Normal file
481
scripts/wsrep_sst_xtrabackup.sh
Normal file
|
|
@ -0,0 +1,481 @@
|
|||
#!/bin/bash -ue
|
||||
# Copyright (C) 2013 Percona Inc
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; version 2 of the License.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; see the file COPYING. If not, write to the
|
||||
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston
|
||||
# MA 02110-1301 USA.
|
||||
|
||||
#############################################################################################################
|
||||
# This is a reference script for Percona XtraBackup-based state snapshot transfer #
|
||||
# Dependencies: (depending on configuration) #
|
||||
# xbcrypt for encryption/decryption. #
|
||||
# qpress for decompression. Download from http://www.quicklz.com/qpress-11-linux-x64.tar till #
|
||||
# https://blueprints.launchpad.net/percona-xtrabackup/+spec/package-qpress is fixed. #
|
||||
# my_print_defaults to extract values from my.cnf. #
|
||||
# netcat for transfer. #
|
||||
# xbstream/tar for streaming. (and xtrabackup ofc) #
|
||||
# #
|
||||
# Currently only option in cnf is read specifically for SST #
|
||||
# [sst] #
|
||||
# streamfmt=tar|xbstream #
|
||||
# #
|
||||
# Default is tar till lp:1193240 is fixed #
|
||||
# You need to use xbstream for encryption, compression etc., however, #
|
||||
# lp:1193240 requires you to manually cleanup the directory prior to SST #
|
||||
# #
|
||||
#############################################################################################################
|
||||
|
||||
. $(dirname $0)/wsrep_sst_common
|
||||
|
||||
ealgo=""
|
||||
ekey=""
|
||||
ekeyfile=""
|
||||
encrypt=0
|
||||
nproc=1
|
||||
ecode=0
|
||||
XTRABACKUP_PID=""
|
||||
|
||||
sfmt="tar"
|
||||
strmcmd=""
|
||||
declare -a RC
|
||||
|
||||
get_keys()
|
||||
{
|
||||
# There is no metadata in the stream to indicate that it is encrypted
|
||||
# So, if the cnf file on joiner contains 'encrypt' under [xtrabackup] section then
|
||||
# it means encryption is being used
|
||||
if ! my_print_defaults -c $WSREP_SST_OPT_CONF xtrabackup | grep -q encrypt; then
|
||||
return
|
||||
fi
|
||||
if [[ $sfmt == 'tar' ]];then
|
||||
wsrep_log_info "NOTE: Encryption cannot be enabled with tar format"
|
||||
return
|
||||
fi
|
||||
|
||||
wsrep_log_info "Encryption enabled in my.cnf - not supported at the moment - Bug in Xtrabackup - lp:1190343"
|
||||
ealgo=$(my_print_defaults -c $WSREP_SST_OPT_CONF xtrabackup | grep -- '--encrypt=' | cut -d= -f2)
|
||||
ekey=$(my_print_defaults -c $WSREP_SST_OPT_CONF xtrabackup | grep -- '--encrypt-key=' | cut -d= -f2)
|
||||
ekeyfile=$(my_print_defaults -c $WSREP_SST_OPT_CONF xtrabackup | grep -- '--encrypt-key-file=' | cut -d= -f2)
|
||||
|
||||
if [[ -z $ealgo ]];then
|
||||
wsrep_log_error "FATAL: Encryption algorithm empty from my.cnf, bailing out"
|
||||
exit 3
|
||||
fi
|
||||
|
||||
if [[ -z $ekey && ! -r $ekeyfile ]];then
|
||||
wsrep_log_error "FATAL: Either key or keyfile must be readable"
|
||||
exit 3
|
||||
fi
|
||||
encrypt=1
|
||||
}
|
||||
|
||||
read_cnf()
|
||||
{
|
||||
sfmt=$(my_print_defaults -c $WSREP_SST_OPT_CONF sst | grep -- '--streamfmt' | cut -d= -f2)
|
||||
if [[ $sfmt == 'xbstream' ]];then
|
||||
wsrep_log_info "Streaming with xbstream"
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
wsrep_log_info "xbstream requires manual cleanup of data directory before SST - lp:1193240"
|
||||
strmcmd="xbstream -x -C ${DATA}"
|
||||
elif [[ "$WSREP_SST_OPT_ROLE" == "donor" ]];then
|
||||
strmcmd="xbstream -c ${INFO_FILE} ${IST_FILE}"
|
||||
else
|
||||
wsrep_log_error "Invalid role: $WSREP_SST_OPT_ROLE"
|
||||
exit 22
|
||||
fi
|
||||
else
|
||||
sfmt="tar"
|
||||
wsrep_log_info "Streaming with tar"
|
||||
wsrep_log_info "Note: Advanced xtrabackup features - encryption,compression etc. not available with tar."
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
wsrep_log_info "However, xbstream requires manual cleanup of data directory before SST - lp:1193240."
|
||||
strmcmd="tar xfi - -C ${DATA}"
|
||||
elif [[ "$WSREP_SST_OPT_ROLE" == "donor" ]];then
|
||||
strmcmd="tar cf - ${INFO_FILE} ${IST_FILE}"
|
||||
else
|
||||
wsrep_log_error "Invalid role: $WSREP_SST_OPT_ROLE"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
get_proc()
|
||||
{
|
||||
set +e
|
||||
nproc=$(grep -c processor /proc/cpuinfo)
|
||||
[[ -z $nproc || $nproc -eq 0 ]] && nproc=1
|
||||
set -e
|
||||
}
|
||||
|
||||
cleanup_joiner()
|
||||
{
|
||||
# Since this is invoked just after exit NNN
|
||||
local estatus=$?
|
||||
if [[ $estatus -ne 0 ]];then
|
||||
wsrep_log_error "Cleanup after exit with status:$estatus"
|
||||
fi
|
||||
local PID=$(ps -aef |grep nc| grep $NC_PORT | awk '{ print $2 }')
|
||||
if [[ $estatus -ne 0 ]];then
|
||||
wsrep_log_error "Killing nc pid $PID"
|
||||
else
|
||||
wsrep_log_info "Killing nc pid $PID"
|
||||
fi
|
||||
[ -n "$PID" -a "0" != "$PID" ] && kill $PID && (kill $PID && kill -9 $PID) || :
|
||||
rm -f "$MAGIC_FILE"
|
||||
if [ "${WSREP_SST_OPT_ROLE}" = "joiner" ];then
|
||||
wsrep_log_info "Removing the sst_in_progress file"
|
||||
wsrep_cleanup_progress_file
|
||||
fi
|
||||
}
|
||||
|
||||
check_pid()
|
||||
{
|
||||
local pid_file="$1"
|
||||
[ -r "$pid_file" ] && ps -p $(cat "$pid_file") >/dev/null 2>&1
|
||||
}
|
||||
|
||||
cleanup_donor()
|
||||
{
|
||||
# Since this is invoked just after exit NNN
|
||||
local estatus=$?
|
||||
if [[ $estatus -ne 0 ]];then
|
||||
wsrep_log_error "Cleanup after exit with status:$estatus"
|
||||
fi
|
||||
local pid=$XTRABACKUP_PID
|
||||
if check_pid "$pid"
|
||||
then
|
||||
wsrep_log_error "xtrabackup process is still running. Killing... "
|
||||
kill_xtrabackup
|
||||
fi
|
||||
|
||||
rm -f "$pid"
|
||||
rm -f ${DATA}/${IST_FILE}
|
||||
}
|
||||
|
||||
kill_xtrabackup()
|
||||
{
|
||||
#set -x
|
||||
local PID=$(cat $XTRABACKUP_PID)
|
||||
[ -n "$PID" -a "0" != "$PID" ] && kill $PID && (kill $PID && kill -9 $PID) || :
|
||||
rm -f "$XTRABACKUP_PID"
|
||||
#set +x
|
||||
}
|
||||
|
||||
# waits ~10 seconds for nc to open the port and then reports ready
|
||||
# (regardless of timeout)
|
||||
wait_for_nc()
|
||||
{
|
||||
local PORT=$1
|
||||
local ADDR=$2
|
||||
local MODULE=$3
|
||||
for i in $(seq 1 50)
|
||||
do
|
||||
netstat -nptl 2>/dev/null | grep '/nc\s*$' | awk '{ print $4 }' | \
|
||||
sed 's/.*://' | grep \^${PORT}\$ >/dev/null && break
|
||||
sleep 0.2
|
||||
done
|
||||
echo "ready ${ADDR}/${MODULE}"
|
||||
}
|
||||
|
||||
INNOBACKUPEX_BIN=innobackupex
|
||||
INNOBACKUPEX_ARGS=""
|
||||
NC_BIN=nc
|
||||
|
||||
for TOOL_BIN in INNOBACKUPEX_BIN NC_BIN ; do
|
||||
if ! which ${!TOOL_BIN} > /dev/null 2>&1
|
||||
then
|
||||
echo "Can't find ${!TOOL_BIN} in the path"
|
||||
exit 22 # EINVAL
|
||||
fi
|
||||
done
|
||||
|
||||
#ROLE=$1
|
||||
#ADDR=$2
|
||||
readonly AUTH=(${WSREP_SST_OPT_AUTH//:/ })
|
||||
readonly DATA="${WSREP_SST_OPT_DATA}"
|
||||
#CONF=$5
|
||||
|
||||
INFO_FILE="xtrabackup_galera_info"
|
||||
IST_FILE="xtrabackup_ist"
|
||||
|
||||
MAGIC_FILE="${DATA}/${INFO_FILE}"
|
||||
rm -f "${MAGIC_FILE}"
|
||||
|
||||
read_cnf
|
||||
|
||||
if [ "$WSREP_SST_OPT_ROLE" = "donor" ]
|
||||
then
|
||||
trap cleanup_donor EXIT
|
||||
|
||||
NC_PORT=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $2 }')
|
||||
REMOTEIP=$(echo $WSREP_SST_OPT_ADDR | awk -F ':' '{ print $1 }')
|
||||
|
||||
if [ $WSREP_SST_OPT_BYPASS -eq 0 ]
|
||||
then
|
||||
TMPDIR="/tmp"
|
||||
|
||||
INNOBACKUPEX_ARGS="--galera-info --stream=$sfmt
|
||||
--defaults-file=${WSREP_SST_OPT_CONF}
|
||||
--socket=${WSREP_SST_OPT_SOCKET}"
|
||||
|
||||
if [ "${AUTH[0]}" != "(null)" ]; then
|
||||
INNOBACKUPEX_ARGS="${INNOBACKUPEX_ARGS} --user=${AUTH[0]}"
|
||||
fi
|
||||
|
||||
if [ ${#AUTH[*]} -eq 2 ]; then
|
||||
INNOBACKUPEX_ARGS="${INNOBACKUPEX_ARGS} --password=${AUTH[1]}"
|
||||
else
|
||||
# Empty password, used for testing, debugging etc.
|
||||
INNOBACKUPEX_ARGS="${INNOBACKUPEX_ARGS} --password="
|
||||
fi
|
||||
|
||||
get_keys
|
||||
if [[ $encrypt -eq 1 ]];then
|
||||
if [[ -n $ekey ]];then
|
||||
INNOBACKUPEX_ARGS="${INNOBACKUPEX_ARGS} --encrypt=$ealgo --encrypt-key=$ekey"
|
||||
else
|
||||
INNOBACKUPEX_ARGS="${INNOBACKUPEX_ARGS} --encrypt=$ealgo --encrypt-key-file=$ekeyfile"
|
||||
fi
|
||||
fi
|
||||
|
||||
wsrep_log_info "Streaming the backup to joiner at ${REMOTEIP} ${NC_PORT}"
|
||||
|
||||
set +e
|
||||
${INNOBACKUPEX_BIN} ${INNOBACKUPEX_ARGS} ${TMPDIR} \
|
||||
2> ${DATA}/innobackup.backup.log | \
|
||||
${NC_BIN} ${REMOTEIP} ${NC_PORT}
|
||||
|
||||
RC=( "${PIPESTATUS[@]}" )
|
||||
set -e
|
||||
|
||||
if [ ${RC[0]} -ne 0 ]; then
|
||||
wsrep_log_error "${INNOBACKUPEX_BIN} finished with error: ${RC[0]}. " \
|
||||
"Check ${DATA}/innobackup.backup.log"
|
||||
exit 22
|
||||
elif [ ${RC[1]} -ne 0 ]; then
|
||||
wsrep_log_error "${NC_BIN} finished with error: ${RC[1]}"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
# innobackupex implicitly writes PID to fixed location in ${TMPDIR}
|
||||
XTRABACKUP_PID="${TMPDIR}/xtrabackup_pid"
|
||||
|
||||
|
||||
else # BYPASS
|
||||
wsrep_log_info "Bypassing the SST for IST"
|
||||
STATE="${WSREP_SST_OPT_GTID}"
|
||||
echo "continue" # now server can resume updating data
|
||||
echo "${STATE}" > "${MAGIC_FILE}"
|
||||
echo "1" > "${DATA}/${IST_FILE}"
|
||||
get_keys
|
||||
pushd ${DATA} 1>/dev/null
|
||||
set +e
|
||||
if [[ $encrypt -eq 1 ]];then
|
||||
if [[ -n $ekey ]];then
|
||||
xbstream -c ${INFO_FILE} ${IST_FILE} | xbcrypt --encrypt-algo=$ealgo --encrypt-key=$ekey | ${NC_BIN} ${REMOTEIP} ${NC_PORT}
|
||||
else
|
||||
xbstream -c ${INFO_FILE} ${IST_FILE} | xbcrypt --encrypt-algo=$ealgo --encrypt-key-file=$ekeyfile | ${NC_BIN} ${REMOTEIP} ${NC_PORT}
|
||||
fi
|
||||
else
|
||||
$strmcmd | ${NC_BIN} ${REMOTEIP} ${NC_PORT}
|
||||
fi
|
||||
RC=( "${PIPESTATUS[@]}" )
|
||||
set -e
|
||||
popd 1>/dev/null
|
||||
|
||||
for ecode in "${RC[@]}";do
|
||||
if [[ $ecode -ne 0 ]];then
|
||||
wsrep_log_error "Error while streaming data to joiner node: " \
|
||||
"exit codes: ${RC[@]}"
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
#rm -f ${DATA}/${IST_FILE}
|
||||
fi
|
||||
|
||||
echo "done ${WSREP_SST_OPT_GTID}"
|
||||
|
||||
elif [ "${WSREP_SST_OPT_ROLE}" = "joiner" ]
|
||||
then
|
||||
[[ -e $SST_PROGRESS_FILE ]] && wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE"
|
||||
touch $SST_PROGRESS_FILE
|
||||
|
||||
sencrypted=1
|
||||
nthreads=1
|
||||
|
||||
MODULE="xtrabackup_sst"
|
||||
|
||||
rm -f ${DATA}/xtrabackup_*
|
||||
|
||||
ADDR=${WSREP_SST_OPT_ADDR}
|
||||
NC_PORT=$(echo ${ADDR} | awk -F ':' '{ print $2 }')
|
||||
if [ -z "${NC_PORT}" ]
|
||||
then
|
||||
NC_PORT=4444
|
||||
ADDR="$(echo ${ADDR} | awk -F ':' '{ print $1 }'):${NC_PORT}"
|
||||
fi
|
||||
|
||||
wait_for_nc ${NC_PORT} ${ADDR} ${MODULE} &
|
||||
|
||||
trap "exit 32" HUP PIPE
|
||||
trap "exit 3" INT TERM
|
||||
trap cleanup_joiner EXIT
|
||||
|
||||
get_keys
|
||||
set +e
|
||||
if [[ $encrypt -eq 1 && $sencrypted -eq 1 ]];then
|
||||
if [[ -n $ekey ]];then
|
||||
${NC_BIN} -dl ${NC_PORT} | xbcrypt -d --encrypt-algo=$ealgo --encrypt-key=$ekey | xbstream -x -C ${DATA}
|
||||
else
|
||||
${NC_BIN} -dl ${NC_PORT} | xbcrypt -d --encrypt-algo=$ealgo --encrypt-key-file=$ekeyfile | xbstream -x -C ${DATA}
|
||||
fi
|
||||
else
|
||||
${NC_BIN} -dl ${NC_PORT} | $strmcmd
|
||||
fi
|
||||
RC=( "${PIPESTATUS[@]}" )
|
||||
set -e
|
||||
|
||||
if [[ $sfmt == 'xbstream' ]];then
|
||||
# Special handling till lp:1193240 is fixed"
|
||||
if [[ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]];then
|
||||
wsrep_log_error "Xbstream failed"
|
||||
wsrep_log_error "Data directory ${DATA} needs to be empty for SST: lp:1193240" \
|
||||
"Manual intervention required in that case"
|
||||
exit 32
|
||||
fi
|
||||
fi
|
||||
|
||||
wait %% # join wait_for_nc thread
|
||||
|
||||
for ecode in "${RC[@]}";do
|
||||
if [[ $ecode -ne 0 ]];then
|
||||
wsrep_log_error "Error while getting data from donor node: " \
|
||||
"exit codes: ${RC[@]}"
|
||||
wsrep_log_error "Data directory ${DATA} needs to be empty for SST:" \
|
||||
"Manual intervention required in that case"
|
||||
exit 32
|
||||
fi
|
||||
done
|
||||
|
||||
if [ ! -r "${MAGIC_FILE}" ]
|
||||
then
|
||||
# this message should cause joiner to abort
|
||||
wsrep_log_error "xtrabackup process ended without creating '${MAGIC_FILE}'"
|
||||
exit 32
|
||||
fi
|
||||
|
||||
if ! ps -p ${WSREP_SST_OPT_PARENT} >/dev/null
|
||||
then
|
||||
wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly."
|
||||
exit 32
|
||||
fi
|
||||
|
||||
if [ ! -r "${IST_FILE}" ]
|
||||
then
|
||||
wsrep_log_info "Proceeding with SST"
|
||||
rebuild=""
|
||||
wsrep_log_info "Removing existing ib_logfile files"
|
||||
rm -f ${DATA}/ib_logfile*
|
||||
|
||||
# Decrypt only if not encrypted in stream.
|
||||
# NOT USED NOW.
|
||||
# Till https://blueprints.launchpad.net/percona-xtrabackup/+spec/add-support-for-rsync-url
|
||||
# is implemented
|
||||
#get_keys
|
||||
if [[ $encrypt -eq 1 && $sencrypted -eq 0 ]];then
|
||||
# Decrypt the files if any
|
||||
find ${DATA} -type f -name '*.xbcrypt' -printf '%p\n' | while read line;do
|
||||
input=$line
|
||||
output=${input%.xbcrypt}
|
||||
|
||||
if [[ -n $ekey ]];then
|
||||
xbcrypt -d --encrypt-algo=$ealgo --encrypt-key=$ekey -i $input > $output
|
||||
else
|
||||
xbcrypt -d --encrypt-algo=$ealgo --encrypt-key-file=$ekeyfile -i $input > $output
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $? = 0 ]];then
|
||||
find ${DATA} -type f -name '*.xbcrypt' -delete
|
||||
fi
|
||||
fi
|
||||
|
||||
get_proc
|
||||
|
||||
# Rebuild indexes for compact backups
|
||||
if grep -q 'compact = 1' ${DATA}/xtrabackup_checkpoints;then
|
||||
wsrep_log_info "Index compaction detected"
|
||||
nthreads=$(my_print_defaults -c $WSREP_SST_OPT_CONF xtrabackup | grep -- '--rebuild-threads' | cut -d= -f2)
|
||||
[[ -z $nthreads ]] && nthreads=$nproc
|
||||
wsrep_log_info "Rebuilding with $nthreads threads"
|
||||
rebuild="--rebuild-indexes --rebuild-threads=$nthreads"
|
||||
fi
|
||||
|
||||
if test -n "$(find ${DATA} -maxdepth 1 -name '*.qp' -print -quit)";then
|
||||
|
||||
wsrep_log_info "Compressed qpress files found"
|
||||
|
||||
if [[ ! -x `which qpress` ]];then
|
||||
wsrep_log_error "qpress not found in PATH"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
set +e
|
||||
|
||||
wsrep_log_info "Removing existing ibdata1 file"
|
||||
rm -f ${DATA}/ibdata1
|
||||
|
||||
# Decompress the qpress files
|
||||
wsrep_log_info "Decompression with $nproc threads"
|
||||
find ${DATA} -type f -name '*.qp' -printf '%p\n%h\n' | xargs -P $nproc -n 2 qpress -d
|
||||
extcode=$?
|
||||
|
||||
set -e
|
||||
|
||||
if [[ $extcode -eq 0 ]];then
|
||||
wsrep_log_info "Removing qpress files after decompression"
|
||||
find ${DATA} -type f -name '*.qp' -delete
|
||||
if [[ $? -ne 0 ]];then
|
||||
wsrep_log_error "Something went wrong with deletion of qpress files. Investigate"
|
||||
fi
|
||||
else
|
||||
wsrep_log_error "Decompression failed. Exit code: $extcode"
|
||||
exit 22
|
||||
fi
|
||||
fi
|
||||
|
||||
wsrep_log_info "Preparing the backup at ${DATA}"
|
||||
|
||||
${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} --apply-log $rebuild \
|
||||
${DATA} 1>&2 2> ${DATA}/innobackup.prepare.log
|
||||
if [ $? -ne 0 ];
|
||||
then
|
||||
wsrep_log_error "${INNOBACKUPEX_BIN} finished with errors. Check ${DATA}/innobackup.prepare.log"
|
||||
exit 22
|
||||
fi
|
||||
else
|
||||
wsrep_log_info "${IST_FILE} received from donor: Running IST"
|
||||
fi
|
||||
|
||||
cat "${MAGIC_FILE}" # output UUID:seqno
|
||||
|
||||
#Cleanup not required here since EXIT trap should be called
|
||||
#wsrep_cleanup_progress_file
|
||||
|
||||
else
|
||||
wsrep_log_error "Unrecognized role: ${WSREP_SST_OPT_ROLE}"
|
||||
exit 22 # EINVAL
|
||||
fi
|
||||
|
||||
exit 0
|
||||
Loading…
Add table
Add a link
Reference in a new issue