mirror of
https://github.com/MariaDB/server.git
synced 2026-05-16 20:07:13 +02:00
Merge lp:codership-mysql/5.5 -r3961..3980.
This commit is contained in:
parent
150e88e8c9
commit
fa18dc3944
22 changed files with 2380 additions and 223 deletions
|
|
@ -18,7 +18,7 @@
|
|||
# so WSREP_VERSION is produced regardless
|
||||
|
||||
# Set the patch version
|
||||
SET(WSREP_PATCH_VERSION "9")
|
||||
SET(WSREP_PATCH_VERSION "10")
|
||||
|
||||
# MariaDB addition: Revision number of the last revision merged from
|
||||
# codership branch visible in @@visible_comment.
|
||||
|
|
|
|||
|
|
@ -328,7 +328,13 @@ IF(WIN32)
|
|||
ENDFOREACH()
|
||||
ELSE()
|
||||
IF(WITH_WSREP)
|
||||
SET(WSREP_BINARIES wsrep_sst_common wsrep_sst_mysqldump wsrep_sst_rsync wsrep_sst_xtrabackup)
|
||||
SET(WSREP_BINARIES
|
||||
wsrep_sst_common
|
||||
wsrep_sst_mysqldump
|
||||
wsrep_sst_rsync
|
||||
wsrep_sst_xtrabackup
|
||||
wsrep_sst_xtrabackup-v2
|
||||
)
|
||||
ENDIF()
|
||||
|
||||
# Configure this one, for testing, but do not install it.
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ case "$1" in
|
|||
shift
|
||||
;;
|
||||
'--auth')
|
||||
readonly WSREP_SST_OPT_AUTH="$2"
|
||||
WSREP_SST_OPT_AUTH="$2"
|
||||
shift
|
||||
;;
|
||||
'--bypass')
|
||||
|
|
@ -87,13 +87,21 @@ shift
|
|||
done
|
||||
readonly WSREP_SST_OPT_BYPASS
|
||||
|
||||
if [ -n "$WSREP_SST_OPT_DATA" ]
|
||||
# For Bug:1200727
|
||||
if my_print_defaults -c $WSREP_SST_OPT_CONF sst | grep -q "wsrep_sst_auth";then
|
||||
if [ -z $WSREP_SST_OPT_AUTH -o $WSREP_SST_OPT_AUTH = "(null)" ];then
|
||||
WSREP_SST_OPT_AUTH=$(my_print_defaults -c $WSREP_SST_OPT_CONF sst | grep -- "--wsrep_sst_auth" | cut -d= -f2)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "${WSREP_SST_OPT_DATA:-}" ]
|
||||
then
|
||||
SST_PROGRESS_FILE="$WSREP_SST_OPT_DATA/sst_in_progress"
|
||||
else
|
||||
SST_PROGRESS_FILE=""
|
||||
fi
|
||||
|
||||
|
||||
wsrep_log()
|
||||
{
|
||||
# echo everything to stderr so that it gets into common error log
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ case "$1" in
|
|||
shift
|
||||
;;
|
||||
'--auth')
|
||||
readonly WSREP_SST_OPT_AUTH="$2"
|
||||
WSREP_SST_OPT_AUTH="$2"
|
||||
shift
|
||||
;;
|
||||
'--bypass')
|
||||
|
|
@ -87,13 +87,21 @@ shift
|
|||
done
|
||||
readonly WSREP_SST_OPT_BYPASS
|
||||
|
||||
if [ -n "$WSREP_SST_OPT_DATA" ]
|
||||
# For Bug:1200727
|
||||
if my_print_defaults -c $WSREP_SST_OPT_CONF sst | grep -q "wsrep_sst_auth";then
|
||||
if [ -z $WSREP_SST_OPT_AUTH -o $WSREP_SST_OPT_AUTH = "(null)" ];then
|
||||
WSREP_SST_OPT_AUTH=$(my_print_defaults -c $WSREP_SST_OPT_CONF sst | grep -- "--wsrep_sst_auth" | cut -d= -f2)
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "${WSREP_SST_OPT_DATA:-}" ]
|
||||
then
|
||||
SST_PROGRESS_FILE="$WSREP_SST_OPT_DATA/sst_in_progress"
|
||||
else
|
||||
SST_PROGRESS_FILE=""
|
||||
fi
|
||||
|
||||
|
||||
wsrep_log()
|
||||
{
|
||||
# echo everything to stderr so that it gets into common error log
|
||||
|
|
|
|||
|
|
@ -49,19 +49,21 @@ check_pid()
|
|||
check_pid_and_port()
|
||||
{
|
||||
local pid_file=$1
|
||||
local rsync_pid=$(cat $pid_file)
|
||||
local rsync_port=$2
|
||||
local rsync_pid=$2
|
||||
local rsync_port=$3
|
||||
|
||||
if [ "$OS" == "Darwin" -o "$OS" == "FreeBSD" ]; then
|
||||
# no netstat --program(-p) option in Darwin and FreeBSD
|
||||
check_pid $pid_file && \
|
||||
lsof -i -Pn 2>/dev/null | \
|
||||
grep "(LISTEN)" | grep ":$rsync_port" | grep -w '^rsync[[:space:]]\+'"$rsync_pid" >/dev/null
|
||||
else
|
||||
check_pid $pid_file && \
|
||||
netstat -lnpt 2>/dev/null | \
|
||||
grep LISTEN | grep \:$rsync_port | grep $rsync_pid/rsync >/dev/null
|
||||
local port_info=$(lsof -i :$rsync_port -Pn 2>/dev/null | \
|
||||
grep "(LISTEN)")
|
||||
local is_rsync=$(echo $port_info | \
|
||||
grep -w '^rsync[[:space:]]\+'"$rsync_pid" 2>/dev/null)
|
||||
|
||||
if [ -n "$port_info" -a -z "$is_rsync" ]; then
|
||||
wsrep_log_error "rsync daemon port '$rsync_port' has been taken"
|
||||
exit 16 # EBUSY
|
||||
fi
|
||||
check_pid $pid_file && \
|
||||
[ -n "$port_info" ] && [ -n "$is_rsync" ] && \
|
||||
[ $(cat $pid_file) -eq $rsync_pid ]
|
||||
}
|
||||
|
||||
MAGIC_FILE="$WSREP_SST_OPT_DATA/rsync_sst_complete"
|
||||
|
|
@ -234,9 +236,10 @@ EOF
|
|||
# rm -rf "$DATA"/ib_logfile* # we don't want old logs around
|
||||
|
||||
# listen at all interfaces (for firewalled setups)
|
||||
rsync --daemon --port $RSYNC_PORT --config "$RSYNC_CONF"
|
||||
rsync --daemon --no-detach --port $RSYNC_PORT --config "$RSYNC_CONF" &
|
||||
RSYNC_REAL_PID=$!
|
||||
|
||||
until check_pid_and_port $RSYNC_PID $RSYNC_PORT
|
||||
until check_pid_and_port $RSYNC_PID $RSYNC_REAL_PID $RSYNC_PORT
|
||||
do
|
||||
sleep 0.2
|
||||
done
|
||||
|
|
|
|||
879
scripts/wsrep_sst_xtrabackup-v2
Executable file
879
scripts/wsrep_sst_xtrabackup-v2
Executable file
|
|
@ -0,0 +1,879 @@
|
|||
#!/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.
|
||||
|
||||
# Documentation: http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html
|
||||
# Make sure to read that before proceeding!
|
||||
|
||||
|
||||
|
||||
|
||||
. $(dirname $0)/wsrep_sst_common
|
||||
|
||||
ealgo=""
|
||||
ekey=""
|
||||
ekeyfile=""
|
||||
encrypt=0
|
||||
nproc=1
|
||||
ecode=0
|
||||
XTRABACKUP_PID=""
|
||||
SST_PORT=""
|
||||
REMOTEIP=""
|
||||
tcert=""
|
||||
tpem=""
|
||||
tkey=""
|
||||
sockopt=""
|
||||
progress=""
|
||||
ttime=0
|
||||
totime=0
|
||||
lsn=""
|
||||
incremental=0
|
||||
ecmd=""
|
||||
rlimit=""
|
||||
# Initially
|
||||
stagemsg="${WSREP_SST_OPT_ROLE}"
|
||||
cpat=""
|
||||
speciald=0
|
||||
ib_home_dir=""
|
||||
ib_log_dir=""
|
||||
|
||||
sfmt="tar"
|
||||
strmcmd=""
|
||||
tfmt=""
|
||||
tcmd=""
|
||||
rebuild=0
|
||||
rebuildcmd=""
|
||||
payload=0
|
||||
pvformat="-F '%N => Rate:%r Avg:%a Elapsed:%t %e Bytes: %b %p' "
|
||||
pvopts="-f -i 10 -N $WSREP_SST_OPT_ROLE "
|
||||
STATDIR=""
|
||||
uextra=0
|
||||
disver=""
|
||||
|
||||
scomp=""
|
||||
sdecomp=""
|
||||
|
||||
if which pv &>/dev/null && pv --help | grep -q FORMAT;then
|
||||
pvopts+=$pvformat
|
||||
fi
|
||||
pcmd="pv $pvopts"
|
||||
declare -a RC
|
||||
|
||||
INNOBACKUPEX_BIN=innobackupex
|
||||
readonly AUTH=(${WSREP_SST_OPT_AUTH//:/ })
|
||||
DATA="${WSREP_SST_OPT_DATA}"
|
||||
INFO_FILE="xtrabackup_galera_info"
|
||||
IST_FILE="xtrabackup_ist"
|
||||
MAGIC_FILE="${DATA}/${INFO_FILE}"
|
||||
|
||||
# Setting the path for ss and ip
|
||||
export PATH="/usr/sbin:/sbin:$PATH"
|
||||
|
||||
timeit(){
|
||||
local stage=$1
|
||||
shift
|
||||
local cmd="$@"
|
||||
local x1 x2 took extcode
|
||||
|
||||
if [[ $ttime -eq 1 ]];then
|
||||
x1=$(date +%s)
|
||||
wsrep_log_info "Evaluating $cmd"
|
||||
eval "$cmd"
|
||||
extcode=$?
|
||||
x2=$(date +%s)
|
||||
took=$(( x2-x1 ))
|
||||
wsrep_log_info "NOTE: $stage took $took seconds"
|
||||
totime=$(( totime+took ))
|
||||
else
|
||||
wsrep_log_info "Evaluating $cmd"
|
||||
eval "$cmd"
|
||||
extcode=$?
|
||||
fi
|
||||
return $extcode
|
||||
}
|
||||
|
||||
get_keys()
|
||||
{
|
||||
# $encrypt -eq 1 is for internal purposes only
|
||||
if [[ $encrypt -ge 2 || $encrypt -eq -1 ]];then
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ $encrypt -eq 0 ]];then
|
||||
if my_print_defaults -c $WSREP_SST_OPT_CONF xtrabackup | grep -q encrypt;then
|
||||
wsrep_log_error "Unexpected option combination. SST may fail. Refer to http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html "
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ $sfmt == 'tar' ]];then
|
||||
wsrep_log_info "NOTE: Xtrabackup-based encryption - encrypt=1 - cannot be enabled with tar format"
|
||||
encrypt=-1
|
||||
return
|
||||
fi
|
||||
|
||||
wsrep_log_info "Xtrabackup based encryption enabled in my.cnf - Supported only from Xtrabackup 2.1.4"
|
||||
|
||||
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
|
||||
|
||||
if [[ -z $ekey ]];then
|
||||
ecmd="xbcrypt --encrypt-algo=$ealgo --encrypt-key-file=$ekeyfile"
|
||||
else
|
||||
ecmd="xbcrypt --encrypt-algo=$ealgo --encrypt-key=$ekey"
|
||||
fi
|
||||
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
ecmd+=" -d"
|
||||
fi
|
||||
|
||||
stagemsg+="-XB-Encrypted"
|
||||
}
|
||||
|
||||
get_transfer()
|
||||
{
|
||||
if [[ -z $SST_PORT ]];then
|
||||
TSST_PORT=4444
|
||||
else
|
||||
TSST_PORT=$SST_PORT
|
||||
fi
|
||||
|
||||
if [[ $tfmt == 'nc' ]];then
|
||||
if [[ ! -x `which nc` ]];then
|
||||
wsrep_log_error "nc(netcat) not found in path: $PATH"
|
||||
exit 2
|
||||
fi
|
||||
wsrep_log_info "Using netcat as streamer"
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
tcmd="nc -dl ${TSST_PORT}"
|
||||
else
|
||||
tcmd="nc ${REMOTEIP} ${TSST_PORT}"
|
||||
fi
|
||||
else
|
||||
tfmt='socat'
|
||||
wsrep_log_info "Using socat as streamer"
|
||||
if [[ ! -x `which socat` ]];then
|
||||
wsrep_log_error "socat not found in path: $PATH"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [[ $encrypt -eq 2 || $encrypt -eq 3 ]] && ! socat -V | grep -q WITH_OPENSSL;then
|
||||
wsrep_log_info "NOTE: socat is not openssl enabled, falling back to plain transfer"
|
||||
encrypt=-1
|
||||
fi
|
||||
|
||||
if [[ $encrypt -eq 2 ]];then
|
||||
wsrep_log_info "Using openssl based encryption with socat: with crt and pem"
|
||||
if [[ -z $tpem || -z $tcert ]];then
|
||||
wsrep_log_error "Both PEM and CRT files required"
|
||||
exit 22
|
||||
fi
|
||||
stagemsg+="-OpenSSL-Encrypted-2"
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
wsrep_log_info "Decrypting with PEM $tpem, CA: $tcert"
|
||||
tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=$tpem,cafile=${tcert}${sockopt} stdio"
|
||||
else
|
||||
wsrep_log_info "Encrypting with PEM $tpem, CA: $tcert"
|
||||
tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=$tpem,cafile=${tcert}${sockopt}"
|
||||
fi
|
||||
elif [[ $encrypt -eq 3 ]];then
|
||||
wsrep_log_info "Using openssl based encryption with socat: with key and crt"
|
||||
if [[ -z $tpem || -z $tkey ]];then
|
||||
wsrep_log_error "Both certificate and key files required"
|
||||
exit 22
|
||||
fi
|
||||
stagemsg+="-OpenSSL-Encrypted-3"
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
wsrep_log_info "Decrypting with certificate $tpem, key $tkey"
|
||||
tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=$tpem,key=${tkey},verify=0${sockopt} stdio"
|
||||
else
|
||||
wsrep_log_info "Encrypting with certificate $tpem, key $tkey"
|
||||
tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=$tpem,key=${tkey},verify=0${sockopt}"
|
||||
fi
|
||||
|
||||
else
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
tcmd="socat -u TCP-LISTEN:${TSST_PORT},reuseaddr${sockopt} stdio"
|
||||
else
|
||||
tcmd="socat -u stdio TCP:${REMOTEIP}:${TSST_PORT}${sockopt}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
parse_cnf()
|
||||
{
|
||||
local group=$1
|
||||
local var=$2
|
||||
reval=$(my_print_defaults -c $WSREP_SST_OPT_CONF $group | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2-)
|
||||
if [[ -z $reval ]];then
|
||||
[[ -n $3 ]] && reval=$3
|
||||
fi
|
||||
echo $reval
|
||||
}
|
||||
|
||||
get_footprint()
|
||||
{
|
||||
pushd $WSREP_SST_OPT_DATA 1>/dev/null
|
||||
payload=$(du --block-size=1 -c **/*.ibd **/*.MYI **/*.MYI ibdata1 | awk 'END { print $1 }')
|
||||
if my_print_defaults -c $WSREP_SST_OPT_CONF xtrabackup | grep -q -- "--compress";then
|
||||
# QuickLZ has around 50% compression ratio
|
||||
# When compression/compaction used, the progress is only an approximate.
|
||||
payload=$(( payload*1/2 ))
|
||||
fi
|
||||
popd 1>/dev/null
|
||||
pcmd+=" -s $payload"
|
||||
adjust_progress
|
||||
}
|
||||
|
||||
adjust_progress()
|
||||
{
|
||||
if [[ -n $progress && $progress != '1' ]];then
|
||||
if [[ -e $progress ]];then
|
||||
pcmd+=" 2>>$progress"
|
||||
else
|
||||
pcmd+=" 2>$progress"
|
||||
fi
|
||||
elif [[ -z $progress && -n $rlimit ]];then
|
||||
# When rlimit is non-zero
|
||||
pcmd="pv -q"
|
||||
fi
|
||||
|
||||
if [[ -n $rlimit && "$WSREP_SST_OPT_ROLE" == "donor" ]];then
|
||||
wsrep_log_info "Rate-limiting SST to $rlimit"
|
||||
pcmd+=" -L \$rlimit"
|
||||
fi
|
||||
}
|
||||
|
||||
read_cnf()
|
||||
{
|
||||
sfmt=$(parse_cnf sst streamfmt "xbstream")
|
||||
tfmt=$(parse_cnf sst transferfmt "socat")
|
||||
tcert=$(parse_cnf sst tca "")
|
||||
tpem=$(parse_cnf sst tcert "")
|
||||
tkey=$(parse_cnf sst tkey "")
|
||||
encrypt=$(parse_cnf sst encrypt 0)
|
||||
sockopt=$(parse_cnf sst sockopt "")
|
||||
progress=$(parse_cnf sst progress "")
|
||||
rebuild=$(parse_cnf sst rebuild 0)
|
||||
ttime=$(parse_cnf sst time 0)
|
||||
cpat=$(parse_cnf sst cpat '.*galera\.cache$\|.*sst_in_progress$\|.*grastate\.dat$\|.*\.err$\|.*\.log$\|.*RPM_UPGRADE_MARKER$\|.*RPM_UPGRADE_HISTORY$')
|
||||
incremental=$(parse_cnf sst incremental 0)
|
||||
ealgo=$(parse_cnf xtrabackup encrypt "")
|
||||
ekey=$(parse_cnf xtrabackup encrypt-key "")
|
||||
ekeyfile=$(parse_cnf xtrabackup encrypt-key-file "")
|
||||
scomp=$(parse_cnf sst compressor "")
|
||||
sdecomp=$(parse_cnf sst decompressor "")
|
||||
|
||||
|
||||
# Refer to http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html
|
||||
if [[ -z $ealgo ]];then
|
||||
ealgo=$(parse_cnf sst encrypt-algo "")
|
||||
ekey=$(parse_cnf sst encrypt-key "")
|
||||
ekeyfile=$(parse_cnf sst encrypt-key-file "")
|
||||
fi
|
||||
rlimit=$(parse_cnf sst rlimit "")
|
||||
uextra=$(parse_cnf sst use_extra 0)
|
||||
speciald=$(parse_cnf sst sst-special-dirs 1)
|
||||
iopts=$(parse_cnf sst inno-backup-opts "")
|
||||
iapts=$(parse_cnf sst inno-apply-opts "")
|
||||
impts=$(parse_cnf sst inno-move-opts "")
|
||||
}
|
||||
|
||||
get_stream()
|
||||
{
|
||||
if [[ $sfmt == 'xbstream' ]];then
|
||||
wsrep_log_info "Streaming with xbstream"
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
strmcmd="xbstream -x"
|
||||
else
|
||||
strmcmd="xbstream -c \${INFO_FILE}"
|
||||
fi
|
||||
else
|
||||
sfmt="tar"
|
||||
wsrep_log_info "Streaming with tar"
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
strmcmd="tar xfi - "
|
||||
else
|
||||
strmcmd="tar cf - \${INFO_FILE} "
|
||||
fi
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
get_proc()
|
||||
{
|
||||
set +e
|
||||
nproc=$(grep -c processor /proc/cpuinfo)
|
||||
[[ -z $nproc || $nproc -eq 0 ]] && nproc=1
|
||||
set -e
|
||||
}
|
||||
|
||||
sig_joiner_cleanup()
|
||||
{
|
||||
wsrep_log_error "Removing $MAGIC_FILE file due to signal"
|
||||
rm -f "$MAGIC_FILE"
|
||||
}
|
||||
|
||||
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
|
||||
if [ "${WSREP_SST_OPT_ROLE}" = "joiner" ];then
|
||||
wsrep_log_info "Removing the sst_in_progress file"
|
||||
wsrep_cleanup_progress_file
|
||||
fi
|
||||
if [[ -n $progress && -p $progress ]];then
|
||||
wsrep_log_info "Cleaning up fifo file $progress"
|
||||
rm $progress
|
||||
fi
|
||||
if [[ -n ${STATDIR:-} ]];then
|
||||
[[ -d $STATDIR ]] && rm -rf $STATDIR
|
||||
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
|
||||
|
||||
if [[ -n $XTRABACKUP_PID ]];then
|
||||
if check_pid $XTRABACKUP_PID
|
||||
then
|
||||
wsrep_log_error "xtrabackup process is still running. Killing... "
|
||||
kill_xtrabackup
|
||||
fi
|
||||
|
||||
rm -f $XTRABACKUP_PID
|
||||
fi
|
||||
rm -f ${DATA}/${IST_FILE}
|
||||
|
||||
if [[ -n $progress && -p $progress ]];then
|
||||
wsrep_log_info "Cleaning up fifo file $progress"
|
||||
rm $progress
|
||||
fi
|
||||
}
|
||||
|
||||
kill_xtrabackup()
|
||||
{
|
||||
local PID=$(cat $XTRABACKUP_PID)
|
||||
[ -n "$PID" -a "0" != "$PID" ] && kill $PID && (kill $PID && kill -9 $PID) || :
|
||||
rm -f "$XTRABACKUP_PID"
|
||||
}
|
||||
|
||||
setup_ports()
|
||||
{
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "donor" ]];then
|
||||
SST_PORT=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $2 }')
|
||||
REMOTEIP=$(echo $WSREP_SST_OPT_ADDR | awk -F ':' '{ print $1 }')
|
||||
lsn=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $4 }')
|
||||
else
|
||||
SST_PORT=$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $2 }')
|
||||
fi
|
||||
}
|
||||
|
||||
# waits ~10 seconds for nc to open the port and then reports ready
|
||||
# (regardless of timeout)
|
||||
wait_for_listen()
|
||||
{
|
||||
local PORT=$1
|
||||
local ADDR=$2
|
||||
local MODULE=$3
|
||||
for i in {1..50}
|
||||
do
|
||||
ss -p state listening "( sport = :$PORT )" | grep -qE 'socat|nc' && break
|
||||
sleep 0.2
|
||||
done
|
||||
if [[ $incremental -eq 1 ]];then
|
||||
echo "ready ${ADDR}/${MODULE}/$lsn"
|
||||
else
|
||||
echo "ready ${ADDR}/${MODULE}"
|
||||
fi
|
||||
}
|
||||
|
||||
check_extra()
|
||||
{
|
||||
local use_socket=1
|
||||
if [[ $uextra -eq 1 ]];then
|
||||
if my_print_defaults -c $WSREP_SST_OPT_CONF mysqld | tr '_' '-' | grep -- "--thread-handling=" | grep -q 'pool-of-threads';then
|
||||
local eport=$(my_print_defaults -c $WSREP_SST_OPT_CONF mysqld | tr '_' '-' | grep -- "--extra-port=" | cut -d= -f2)
|
||||
if [[ -n $eport ]];then
|
||||
# Xtrabackup works only locally.
|
||||
# Hence, setting host to 127.0.0.1 unconditionally.
|
||||
wsrep_log_info "SST through extra_port $eport"
|
||||
INNOEXTRA+=" --host=127.0.0.1 --port=$eport "
|
||||
use_socket=0
|
||||
else
|
||||
wsrep_log_error "Extra port $eport null, failing"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
wsrep_log_info "Thread pool not set, ignore the option use_extra"
|
||||
fi
|
||||
fi
|
||||
if [[ $use_socket -eq 1 ]] && [[ -n "${WSREP_SST_OPT_SOCKET}" ]];then
|
||||
INNOEXTRA+=" --socket=${WSREP_SST_OPT_SOCKET}"
|
||||
fi
|
||||
}
|
||||
|
||||
recv_joiner()
|
||||
{
|
||||
local dir=$1
|
||||
local msg=$2
|
||||
|
||||
pushd ${dir} 1>/dev/null
|
||||
set +e
|
||||
timeit "$msg" "$tcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )"
|
||||
set -e
|
||||
popd 1>/dev/null
|
||||
|
||||
|
||||
for ecode in "${RC[@]}";do
|
||||
if [[ $ecode -ne 0 ]];then
|
||||
wsrep_log_error "Error while getting data from donor node: " \
|
||||
"exit codes: ${RC[@]}"
|
||||
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}'"
|
||||
wsrep_log_info "Contents of datadir"
|
||||
wsrep_log_info "$(ls -l ${dir}/*)"
|
||||
exit 32
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
send_donor()
|
||||
{
|
||||
local dir=$1
|
||||
local msg=$2
|
||||
|
||||
pushd ${dir} 1>/dev/null
|
||||
set +e
|
||||
timeit "$msg" "$strmcmd | $tcmd; RC=( "\${PIPESTATUS[@]}" )"
|
||||
set -e
|
||||
popd 1>/dev/null
|
||||
|
||||
|
||||
for ecode in "${RC[@]}";do
|
||||
if [[ $ecode -ne 0 ]];then
|
||||
wsrep_log_error "Error while getting data from donor node: " \
|
||||
"exit codes: ${RC[@]}"
|
||||
exit 32
|
||||
fi
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
if [[ ! -x `which innobackupex` ]];then
|
||||
wsrep_log_error "innobackupex not in path: $PATH"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
rm -f "${MAGIC_FILE}"
|
||||
|
||||
if [[ ! ${WSREP_SST_OPT_ROLE} == 'joiner' && ! ${WSREP_SST_OPT_ROLE} == 'donor' ]];then
|
||||
wsrep_log_error "Invalid role ${WSREP_SST_OPT_ROLE}"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
read_cnf
|
||||
setup_ports
|
||||
get_stream
|
||||
get_transfer
|
||||
|
||||
if ${INNOBACKUPEX_BIN} /tmp --help | grep -q -- '--version-check'; then
|
||||
disver="--no-version-check"
|
||||
fi
|
||||
|
||||
|
||||
INNOEXTRA=""
|
||||
INNOAPPLY="${INNOBACKUPEX_BIN} $disver $iapts --apply-log \$rebuildcmd \${DATA} &>\${DATA}/innobackup.prepare.log"
|
||||
INNOMOVE="${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} $disver $impts --move-back --force-non-empty-directories \${DATA} &>\${DATA}/innobackup.move.log"
|
||||
INNOBACKUP="${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} $disver $iopts \$INNOEXTRA --galera-info --stream=\$sfmt \${TMPDIR} 2>\${DATA}/innobackup.backup.log"
|
||||
|
||||
if [ "$WSREP_SST_OPT_ROLE" = "donor" ]
|
||||
then
|
||||
trap cleanup_donor EXIT
|
||||
|
||||
if [ $WSREP_SST_OPT_BYPASS -eq 0 ]
|
||||
then
|
||||
|
||||
TMPDIR="${TMPDIR:-/tmp}"
|
||||
|
||||
if [ "${AUTH[0]}" != "(null)" ]; then
|
||||
INNOEXTRA+=" --user=${AUTH[0]}"
|
||||
fi
|
||||
|
||||
if [ ${#AUTH[*]} -eq 2 ]; then
|
||||
INNOEXTRA+=" --password=${AUTH[1]}"
|
||||
elif [ "${AUTH[0]}" != "(null)" ]; then
|
||||
# Empty password, used for testing, debugging etc.
|
||||
INNOEXTRA+=" --password="
|
||||
fi
|
||||
|
||||
get_keys
|
||||
if [[ $encrypt -eq 1 ]];then
|
||||
if [[ -n $ekey ]];then
|
||||
INNOEXTRA+=" --encrypt=$ealgo --encrypt-key=$ekey "
|
||||
else
|
||||
INNOEXTRA+=" --encrypt=$ealgo --encrypt-key-file=$ekeyfile "
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n $lsn ]];then
|
||||
INNOEXTRA+=" --incremental --incremental-lsn=$lsn "
|
||||
fi
|
||||
|
||||
check_extra
|
||||
|
||||
wsrep_log_info "Streaming GTID file before SST"
|
||||
|
||||
echo "${WSREP_SST_OPT_GTID}" > "${MAGIC_FILE}"
|
||||
|
||||
ttcmd="$tcmd"
|
||||
|
||||
if [[ $encrypt -eq 1 ]];then
|
||||
if [[ -n $scomp ]];then
|
||||
tcmd=" $ecmd | $scomp | $tcmd "
|
||||
else
|
||||
tcmd=" $ecmd | $tcmd "
|
||||
fi
|
||||
elif [[ -n $scomp ]];then
|
||||
tcmd=" $scomp | $tcmd "
|
||||
fi
|
||||
|
||||
|
||||
send_donor $DATA "${stagemsg}-gtid"
|
||||
|
||||
tcmd="$ttcmd"
|
||||
if [[ -n $progress ]];then
|
||||
get_footprint
|
||||
tcmd="$pcmd | $tcmd"
|
||||
elif [[ -n $rlimit ]];then
|
||||
adjust_progress
|
||||
tcmd="$pcmd | $tcmd"
|
||||
fi
|
||||
|
||||
wsrep_log_info "Sleeping before data transfer for SST"
|
||||
sleep 10
|
||||
|
||||
wsrep_log_info "Streaming the backup to joiner at ${REMOTEIP} ${SST_PORT:-4444}"
|
||||
|
||||
if [[ -n $scomp ]];then
|
||||
tcmd="$scomp | $tcmd"
|
||||
fi
|
||||
|
||||
set +e
|
||||
timeit "${stagemsg}-SST" "$INNOBACKUP | $tcmd; 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[$(( ${#RC[@]}-1 ))]} -eq 1 ]];then
|
||||
wsrep_log_error "$tcmd finished with error: ${RC[1]}"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
# innobackupex implicitly writes PID to fixed location in ${TMPDIR}
|
||||
XTRABACKUP_PID="${TMPDIR}/xtrabackup_pid"
|
||||
|
||||
|
||||
else # BYPASS FOR IST
|
||||
|
||||
wsrep_log_info "Bypassing the SST for IST"
|
||||
echo "continue" # now server can resume updating data
|
||||
echo "${WSREP_SST_OPT_GTID}" > "${MAGIC_FILE}"
|
||||
echo "1" > "${DATA}/${IST_FILE}"
|
||||
get_keys
|
||||
if [[ $encrypt -eq 1 ]];then
|
||||
if [[ -n $scomp ]];then
|
||||
tcmd=" $ecmd | $scomp | $tcmd "
|
||||
else
|
||||
tcmd=" $ecmd | $tcmd "
|
||||
fi
|
||||
elif [[ -n $scomp ]];then
|
||||
tcmd=" $scomp | $tcmd "
|
||||
fi
|
||||
strmcmd+=" \${IST_FILE}"
|
||||
|
||||
send_donor $DATA "${stagemsg}-IST"
|
||||
|
||||
fi
|
||||
|
||||
echo "done ${WSREP_SST_OPT_GTID}"
|
||||
wsrep_log_info "Total time on donor: $totime seconds"
|
||||
|
||||
elif [ "${WSREP_SST_OPT_ROLE}" = "joiner" ]
|
||||
then
|
||||
[[ -e $SST_PROGRESS_FILE ]] && wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE"
|
||||
[[ -n $SST_PROGRESS_FILE ]] && touch $SST_PROGRESS_FILE
|
||||
|
||||
if [[ $speciald -eq 1 ]];then
|
||||
wsrep_log_info "WARNING: sst-special-dirs feature requires PXC 2.1.6 or latter."
|
||||
fi
|
||||
|
||||
if [[ $speciald -eq 1 ]];then
|
||||
ib_home_dir=$(parse_cnf mysqld innodb-data-home-dir "")
|
||||
ib_log_dir=$(parse_cnf mysqld innodb-log-group-home-dir "")
|
||||
if [[ -z $ib_home_dir && -z $ib_log_dir ]];then
|
||||
speciald=0
|
||||
fi
|
||||
fi
|
||||
|
||||
stagemsg="Joiner-Recv"
|
||||
|
||||
if [[ ! -e ${DATA}/ibdata1 ]];then
|
||||
incremental=0
|
||||
fi
|
||||
|
||||
if [[ $incremental -eq 1 ]];then
|
||||
wsrep_log_info "Incremental SST enabled: NOT SUPPORTED yet"
|
||||
lsn=$(grep to_lsn xtrabackup_checkpoints | cut -d= -f2 | tr -d ' ')
|
||||
wsrep_log_info "Recovered LSN: $lsn"
|
||||
fi
|
||||
|
||||
sencrypted=1
|
||||
nthreads=1
|
||||
|
||||
MODULE="xtrabackup_sst"
|
||||
|
||||
rm -f "${DATA}/${IST_FILE}"
|
||||
|
||||
# May need xtrabackup_checkpoints later on
|
||||
rm -f ${DATA}/xtrabackup_binary ${DATA}/xtrabackup_galera_info ${DATA}/xtrabackup_logfile
|
||||
|
||||
ADDR=${WSREP_SST_OPT_ADDR}
|
||||
if [ -z "${SST_PORT}" ]
|
||||
then
|
||||
SST_PORT=4444
|
||||
ADDR="$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $1 }'):${SST_PORT}"
|
||||
fi
|
||||
|
||||
wait_for_listen ${SST_PORT} ${ADDR} ${MODULE} &
|
||||
|
||||
trap sig_joiner_cleanup HUP PIPE INT TERM
|
||||
trap cleanup_joiner EXIT
|
||||
|
||||
if [[ -n $progress ]];then
|
||||
adjust_progress
|
||||
tcmd+=" | $pcmd"
|
||||
fi
|
||||
|
||||
if [[ $incremental -eq 1 ]];then
|
||||
BDATA=$DATA
|
||||
DATA=$(mktemp -d)
|
||||
MAGIC_FILE="${DATA}/${INFO_FILE}"
|
||||
fi
|
||||
|
||||
get_keys
|
||||
if [[ $encrypt -eq 1 && $sencrypted -eq 1 ]];then
|
||||
if [[ -n $sdecomp ]];then
|
||||
strmcmd=" $sdecomp | $ecmd | $strmcmd"
|
||||
else
|
||||
strmcmd=" $ecmd | $strmcmd"
|
||||
fi
|
||||
elif [[ -n $sdecomp ]];then
|
||||
strmcmd=" $sdecomp | $strmcmd"
|
||||
fi
|
||||
|
||||
STATDIR=$(mktemp -d)
|
||||
MAGIC_FILE="${STATDIR}/${INFO_FILE}"
|
||||
recv_joiner $STATDIR "${stagemsg}-gtid" 1
|
||||
|
||||
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 "${STATDIR}/${IST_FILE}" ]
|
||||
then
|
||||
wsrep_log_info "Proceeding with SST"
|
||||
|
||||
if [[ $speciald -eq 1 && -d ${DATA}/.sst ]];then
|
||||
wsrep_log_info "WARNING: Stale temporary SST directory: ${DATA}/.sst from previous SST"
|
||||
fi
|
||||
|
||||
if [[ $incremental -ne 1 ]];then
|
||||
if [[ $speciald -eq 1 ]];then
|
||||
wsrep_log_info "Cleaning the existing datadir and innodb-data/log directories"
|
||||
find $ib_home_dir $ib_log_dir $DATA -mindepth 1 -regex $cpat -prune -o -exec rm -rfv {} 1>&2 \+
|
||||
else
|
||||
wsrep_log_info "Cleaning the existing datadir"
|
||||
find $DATA -mindepth 1 -regex $cpat -prune -o -exec rm -rfv {} 1>&2 \+
|
||||
fi
|
||||
tempdir=$(parse_cnf mysqld log-bin "")
|
||||
if [[ -n ${tempdir:-} ]];then
|
||||
binlog_dir=$(dirname $tempdir)
|
||||
binlog_file=$(basename $tempdir)
|
||||
if [[ -n ${binlog_dir:-} && $binlog_dir != '.' && $binlog_dir != $DATA ]];then
|
||||
pattern="$binlog_dir/$binlog_file\.[0-9]+$"
|
||||
wsrep_log_info "Cleaning the binlog directory $binlog_dir as well"
|
||||
find $binlog_dir -maxdepth 1 -type f -regex $pattern -exec rm -fv {} 1>&2 \+
|
||||
rm $binlog_dir/*.index || true
|
||||
fi
|
||||
fi
|
||||
|
||||
else
|
||||
wsrep_log_info "Removing existing ib_logfile files"
|
||||
rm -f ${BDATA}/ib_logfile*
|
||||
fi
|
||||
|
||||
|
||||
if [[ $speciald -eq 1 ]];then
|
||||
mkdir -p ${DATA}/.sst
|
||||
TDATA=${DATA}
|
||||
DATA="${DATA}/.sst"
|
||||
fi
|
||||
|
||||
|
||||
MAGIC_FILE="${DATA}/${INFO_FILE}"
|
||||
recv_joiner $DATA "${stagemsg}-SST" 0
|
||||
|
||||
get_proc
|
||||
|
||||
# Rebuild indexes for compact backups
|
||||
if grep -q 'compact = 1' ${DATA}/xtrabackup_checkpoints;then
|
||||
wsrep_log_info "Index compaction detected"
|
||||
rebuild=1
|
||||
fi
|
||||
|
||||
if [[ $rebuild -eq 1 ]];then
|
||||
nthreads=$(parse_cnf xtrabackup rebuild-threads $nproc)
|
||||
wsrep_log_info "Rebuilding during prepare with $nthreads threads"
|
||||
rebuildcmd="--rebuild-indexes --rebuild-threads=$nthreads"
|
||||
fi
|
||||
|
||||
if test -n "$(find ${DATA} -maxdepth 1 -type f -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: $PATH"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
if [[ -n $progress ]] && pv --help | grep -q 'line-mode';then
|
||||
count=$(find ${DATA} -type f -name '*.qp' | wc -l)
|
||||
count=$(( count*2 ))
|
||||
if pv --help | grep -q FORMAT;then
|
||||
pvopts="-f -s $count -l -N Decompression -F '%N => Rate:%r Elapsed:%t %e Progress: [%b/$count]'"
|
||||
else
|
||||
pvopts="-f -s $count -l -N Decompression"
|
||||
fi
|
||||
pcmd="pv $pvopts"
|
||||
adjust_progress
|
||||
dcmd="$pcmd | xargs -n 2 qpress -T${nproc}d"
|
||||
else
|
||||
dcmd="xargs -n 2 qpress -T${nproc}d"
|
||||
fi
|
||||
|
||||
|
||||
# Decompress the qpress files
|
||||
wsrep_log_info "Decompression with $nproc threads"
|
||||
timeit "Joiner-Decompression" "find ${DATA} -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd"
|
||||
extcode=$?
|
||||
|
||||
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
|
||||
|
||||
if [[ $incremental -eq 1 ]];then
|
||||
# Added --ibbackup=xtrabackup_55 because it fails otherwise citing connection issues.
|
||||
INNOAPPLY="${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} \
|
||||
--ibbackup=xtrabackup_55 --apply-log $rebuildcmd --redo-only $BDATA --incremental-dir=${DATA} &>>${BDATA}/innobackup.prepare.log"
|
||||
fi
|
||||
|
||||
wsrep_log_info "Preparing the backup at ${DATA}"
|
||||
timeit "Xtrabackup prepare stage" "$INNOAPPLY"
|
||||
|
||||
if [ $? -ne 0 ];
|
||||
then
|
||||
wsrep_log_error "${INNOBACKUPEX_BIN} apply finished with errors. Check ${DATA}/innobackup.prepare.log"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
if [[ $speciald -eq 1 ]];then
|
||||
MAGIC_FILE="${TDATA}/${INFO_FILE}"
|
||||
set +e
|
||||
rm $TDATA/innobackup.prepare.log $TDATA/innobackup.move.log
|
||||
set -e
|
||||
wsrep_log_info "Moving the backup to ${TDATA}"
|
||||
timeit "Xtrabackup move stage" "$INNOMOVE"
|
||||
if [[ $? -eq 0 ]];then
|
||||
wsrep_log_info "Move successful, removing ${DATA}"
|
||||
rm -rf $DATA
|
||||
DATA=${TDATA}
|
||||
else
|
||||
wsrep_log_error "Move failed, keeping ${DATA} for further diagnosis"
|
||||
wsrep_log_error "Check ${DATA}/innobackup.move.log for details"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $incremental -eq 1 ]];then
|
||||
wsrep_log_info "Cleaning up ${DATA} after incremental SST"
|
||||
[[ -d ${DATA} ]] && rm -rf ${DATA}
|
||||
DATA=$BDATA
|
||||
fi
|
||||
|
||||
else
|
||||
wsrep_log_info "${IST_FILE} received from donor: Running IST"
|
||||
fi
|
||||
|
||||
if [[ ! -r ${MAGIC_FILE} ]];then
|
||||
wsrep_log_error "SST magic file ${MAGIC_FILE} not found/readable"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
cat "${MAGIC_FILE}" # output UUID:seqno
|
||||
wsrep_log_info "Total time on joiner: $totime seconds"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
879
scripts/wsrep_sst_xtrabackup-v2.sh
Normal file
879
scripts/wsrep_sst_xtrabackup-v2.sh
Normal file
|
|
@ -0,0 +1,879 @@
|
|||
#!/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.
|
||||
|
||||
# Documentation: http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html
|
||||
# Make sure to read that before proceeding!
|
||||
|
||||
|
||||
|
||||
|
||||
. $(dirname $0)/wsrep_sst_common
|
||||
|
||||
ealgo=""
|
||||
ekey=""
|
||||
ekeyfile=""
|
||||
encrypt=0
|
||||
nproc=1
|
||||
ecode=0
|
||||
XTRABACKUP_PID=""
|
||||
SST_PORT=""
|
||||
REMOTEIP=""
|
||||
tcert=""
|
||||
tpem=""
|
||||
tkey=""
|
||||
sockopt=""
|
||||
progress=""
|
||||
ttime=0
|
||||
totime=0
|
||||
lsn=""
|
||||
incremental=0
|
||||
ecmd=""
|
||||
rlimit=""
|
||||
# Initially
|
||||
stagemsg="${WSREP_SST_OPT_ROLE}"
|
||||
cpat=""
|
||||
speciald=0
|
||||
ib_home_dir=""
|
||||
ib_log_dir=""
|
||||
|
||||
sfmt="tar"
|
||||
strmcmd=""
|
||||
tfmt=""
|
||||
tcmd=""
|
||||
rebuild=0
|
||||
rebuildcmd=""
|
||||
payload=0
|
||||
pvformat="-F '%N => Rate:%r Avg:%a Elapsed:%t %e Bytes: %b %p' "
|
||||
pvopts="-f -i 10 -N $WSREP_SST_OPT_ROLE "
|
||||
STATDIR=""
|
||||
uextra=0
|
||||
disver=""
|
||||
|
||||
scomp=""
|
||||
sdecomp=""
|
||||
|
||||
if which pv &>/dev/null && pv --help | grep -q FORMAT;then
|
||||
pvopts+=$pvformat
|
||||
fi
|
||||
pcmd="pv $pvopts"
|
||||
declare -a RC
|
||||
|
||||
INNOBACKUPEX_BIN=innobackupex
|
||||
readonly AUTH=(${WSREP_SST_OPT_AUTH//:/ })
|
||||
DATA="${WSREP_SST_OPT_DATA}"
|
||||
INFO_FILE="xtrabackup_galera_info"
|
||||
IST_FILE="xtrabackup_ist"
|
||||
MAGIC_FILE="${DATA}/${INFO_FILE}"
|
||||
|
||||
# Setting the path for ss and ip
|
||||
export PATH="/usr/sbin:/sbin:$PATH"
|
||||
|
||||
timeit(){
|
||||
local stage=$1
|
||||
shift
|
||||
local cmd="$@"
|
||||
local x1 x2 took extcode
|
||||
|
||||
if [[ $ttime -eq 1 ]];then
|
||||
x1=$(date +%s)
|
||||
wsrep_log_info "Evaluating $cmd"
|
||||
eval "$cmd"
|
||||
extcode=$?
|
||||
x2=$(date +%s)
|
||||
took=$(( x2-x1 ))
|
||||
wsrep_log_info "NOTE: $stage took $took seconds"
|
||||
totime=$(( totime+took ))
|
||||
else
|
||||
wsrep_log_info "Evaluating $cmd"
|
||||
eval "$cmd"
|
||||
extcode=$?
|
||||
fi
|
||||
return $extcode
|
||||
}
|
||||
|
||||
get_keys()
|
||||
{
|
||||
# $encrypt -eq 1 is for internal purposes only
|
||||
if [[ $encrypt -ge 2 || $encrypt -eq -1 ]];then
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ $encrypt -eq 0 ]];then
|
||||
if my_print_defaults -c $WSREP_SST_OPT_CONF xtrabackup | grep -q encrypt;then
|
||||
wsrep_log_error "Unexpected option combination. SST may fail. Refer to http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html "
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ $sfmt == 'tar' ]];then
|
||||
wsrep_log_info "NOTE: Xtrabackup-based encryption - encrypt=1 - cannot be enabled with tar format"
|
||||
encrypt=-1
|
||||
return
|
||||
fi
|
||||
|
||||
wsrep_log_info "Xtrabackup based encryption enabled in my.cnf - Supported only from Xtrabackup 2.1.4"
|
||||
|
||||
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
|
||||
|
||||
if [[ -z $ekey ]];then
|
||||
ecmd="xbcrypt --encrypt-algo=$ealgo --encrypt-key-file=$ekeyfile"
|
||||
else
|
||||
ecmd="xbcrypt --encrypt-algo=$ealgo --encrypt-key=$ekey"
|
||||
fi
|
||||
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
ecmd+=" -d"
|
||||
fi
|
||||
|
||||
stagemsg+="-XB-Encrypted"
|
||||
}
|
||||
|
||||
get_transfer()
|
||||
{
|
||||
if [[ -z $SST_PORT ]];then
|
||||
TSST_PORT=4444
|
||||
else
|
||||
TSST_PORT=$SST_PORT
|
||||
fi
|
||||
|
||||
if [[ $tfmt == 'nc' ]];then
|
||||
if [[ ! -x `which nc` ]];then
|
||||
wsrep_log_error "nc(netcat) not found in path: $PATH"
|
||||
exit 2
|
||||
fi
|
||||
wsrep_log_info "Using netcat as streamer"
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
tcmd="nc -dl ${TSST_PORT}"
|
||||
else
|
||||
tcmd="nc ${REMOTEIP} ${TSST_PORT}"
|
||||
fi
|
||||
else
|
||||
tfmt='socat'
|
||||
wsrep_log_info "Using socat as streamer"
|
||||
if [[ ! -x `which socat` ]];then
|
||||
wsrep_log_error "socat not found in path: $PATH"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [[ $encrypt -eq 2 || $encrypt -eq 3 ]] && ! socat -V | grep -q WITH_OPENSSL;then
|
||||
wsrep_log_info "NOTE: socat is not openssl enabled, falling back to plain transfer"
|
||||
encrypt=-1
|
||||
fi
|
||||
|
||||
if [[ $encrypt -eq 2 ]];then
|
||||
wsrep_log_info "Using openssl based encryption with socat: with crt and pem"
|
||||
if [[ -z $tpem || -z $tcert ]];then
|
||||
wsrep_log_error "Both PEM and CRT files required"
|
||||
exit 22
|
||||
fi
|
||||
stagemsg+="-OpenSSL-Encrypted-2"
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
wsrep_log_info "Decrypting with PEM $tpem, CA: $tcert"
|
||||
tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=$tpem,cafile=${tcert}${sockopt} stdio"
|
||||
else
|
||||
wsrep_log_info "Encrypting with PEM $tpem, CA: $tcert"
|
||||
tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=$tpem,cafile=${tcert}${sockopt}"
|
||||
fi
|
||||
elif [[ $encrypt -eq 3 ]];then
|
||||
wsrep_log_info "Using openssl based encryption with socat: with key and crt"
|
||||
if [[ -z $tpem || -z $tkey ]];then
|
||||
wsrep_log_error "Both certificate and key files required"
|
||||
exit 22
|
||||
fi
|
||||
stagemsg+="-OpenSSL-Encrypted-3"
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
wsrep_log_info "Decrypting with certificate $tpem, key $tkey"
|
||||
tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=$tpem,key=${tkey},verify=0${sockopt} stdio"
|
||||
else
|
||||
wsrep_log_info "Encrypting with certificate $tpem, key $tkey"
|
||||
tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=$tpem,key=${tkey},verify=0${sockopt}"
|
||||
fi
|
||||
|
||||
else
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
tcmd="socat -u TCP-LISTEN:${TSST_PORT},reuseaddr${sockopt} stdio"
|
||||
else
|
||||
tcmd="socat -u stdio TCP:${REMOTEIP}:${TSST_PORT}${sockopt}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
parse_cnf()
|
||||
{
|
||||
local group=$1
|
||||
local var=$2
|
||||
reval=$(my_print_defaults -c $WSREP_SST_OPT_CONF $group | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2-)
|
||||
if [[ -z $reval ]];then
|
||||
[[ -n $3 ]] && reval=$3
|
||||
fi
|
||||
echo $reval
|
||||
}
|
||||
|
||||
get_footprint()
|
||||
{
|
||||
pushd $WSREP_SST_OPT_DATA 1>/dev/null
|
||||
payload=$(du --block-size=1 -c **/*.ibd **/*.MYI **/*.MYI ibdata1 | awk 'END { print $1 }')
|
||||
if my_print_defaults -c $WSREP_SST_OPT_CONF xtrabackup | grep -q -- "--compress";then
|
||||
# QuickLZ has around 50% compression ratio
|
||||
# When compression/compaction used, the progress is only an approximate.
|
||||
payload=$(( payload*1/2 ))
|
||||
fi
|
||||
popd 1>/dev/null
|
||||
pcmd+=" -s $payload"
|
||||
adjust_progress
|
||||
}
|
||||
|
||||
adjust_progress()
|
||||
{
|
||||
if [[ -n $progress && $progress != '1' ]];then
|
||||
if [[ -e $progress ]];then
|
||||
pcmd+=" 2>>$progress"
|
||||
else
|
||||
pcmd+=" 2>$progress"
|
||||
fi
|
||||
elif [[ -z $progress && -n $rlimit ]];then
|
||||
# When rlimit is non-zero
|
||||
pcmd="pv -q"
|
||||
fi
|
||||
|
||||
if [[ -n $rlimit && "$WSREP_SST_OPT_ROLE" == "donor" ]];then
|
||||
wsrep_log_info "Rate-limiting SST to $rlimit"
|
||||
pcmd+=" -L \$rlimit"
|
||||
fi
|
||||
}
|
||||
|
||||
read_cnf()
|
||||
{
|
||||
sfmt=$(parse_cnf sst streamfmt "xbstream")
|
||||
tfmt=$(parse_cnf sst transferfmt "socat")
|
||||
tcert=$(parse_cnf sst tca "")
|
||||
tpem=$(parse_cnf sst tcert "")
|
||||
tkey=$(parse_cnf sst tkey "")
|
||||
encrypt=$(parse_cnf sst encrypt 0)
|
||||
sockopt=$(parse_cnf sst sockopt "")
|
||||
progress=$(parse_cnf sst progress "")
|
||||
rebuild=$(parse_cnf sst rebuild 0)
|
||||
ttime=$(parse_cnf sst time 0)
|
||||
cpat=$(parse_cnf sst cpat '.*galera\.cache$\|.*sst_in_progress$\|.*grastate\.dat$\|.*\.err$\|.*\.log$\|.*RPM_UPGRADE_MARKER$\|.*RPM_UPGRADE_HISTORY$')
|
||||
incremental=$(parse_cnf sst incremental 0)
|
||||
ealgo=$(parse_cnf xtrabackup encrypt "")
|
||||
ekey=$(parse_cnf xtrabackup encrypt-key "")
|
||||
ekeyfile=$(parse_cnf xtrabackup encrypt-key-file "")
|
||||
scomp=$(parse_cnf sst compressor "")
|
||||
sdecomp=$(parse_cnf sst decompressor "")
|
||||
|
||||
|
||||
# Refer to http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html
|
||||
if [[ -z $ealgo ]];then
|
||||
ealgo=$(parse_cnf sst encrypt-algo "")
|
||||
ekey=$(parse_cnf sst encrypt-key "")
|
||||
ekeyfile=$(parse_cnf sst encrypt-key-file "")
|
||||
fi
|
||||
rlimit=$(parse_cnf sst rlimit "")
|
||||
uextra=$(parse_cnf sst use_extra 0)
|
||||
speciald=$(parse_cnf sst sst-special-dirs 1)
|
||||
iopts=$(parse_cnf sst inno-backup-opts "")
|
||||
iapts=$(parse_cnf sst inno-apply-opts "")
|
||||
impts=$(parse_cnf sst inno-move-opts "")
|
||||
}
|
||||
|
||||
get_stream()
|
||||
{
|
||||
if [[ $sfmt == 'xbstream' ]];then
|
||||
wsrep_log_info "Streaming with xbstream"
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
strmcmd="xbstream -x"
|
||||
else
|
||||
strmcmd="xbstream -c \${INFO_FILE}"
|
||||
fi
|
||||
else
|
||||
sfmt="tar"
|
||||
wsrep_log_info "Streaming with tar"
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
strmcmd="tar xfi - "
|
||||
else
|
||||
strmcmd="tar cf - \${INFO_FILE} "
|
||||
fi
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
get_proc()
|
||||
{
|
||||
set +e
|
||||
nproc=$(grep -c processor /proc/cpuinfo)
|
||||
[[ -z $nproc || $nproc -eq 0 ]] && nproc=1
|
||||
set -e
|
||||
}
|
||||
|
||||
sig_joiner_cleanup()
|
||||
{
|
||||
wsrep_log_error "Removing $MAGIC_FILE file due to signal"
|
||||
rm -f "$MAGIC_FILE"
|
||||
}
|
||||
|
||||
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
|
||||
if [ "${WSREP_SST_OPT_ROLE}" = "joiner" ];then
|
||||
wsrep_log_info "Removing the sst_in_progress file"
|
||||
wsrep_cleanup_progress_file
|
||||
fi
|
||||
if [[ -n $progress && -p $progress ]];then
|
||||
wsrep_log_info "Cleaning up fifo file $progress"
|
||||
rm $progress
|
||||
fi
|
||||
if [[ -n ${STATDIR:-} ]];then
|
||||
[[ -d $STATDIR ]] && rm -rf $STATDIR
|
||||
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
|
||||
|
||||
if [[ -n $XTRABACKUP_PID ]];then
|
||||
if check_pid $XTRABACKUP_PID
|
||||
then
|
||||
wsrep_log_error "xtrabackup process is still running. Killing... "
|
||||
kill_xtrabackup
|
||||
fi
|
||||
|
||||
rm -f $XTRABACKUP_PID
|
||||
fi
|
||||
rm -f ${DATA}/${IST_FILE}
|
||||
|
||||
if [[ -n $progress && -p $progress ]];then
|
||||
wsrep_log_info "Cleaning up fifo file $progress"
|
||||
rm $progress
|
||||
fi
|
||||
}
|
||||
|
||||
kill_xtrabackup()
|
||||
{
|
||||
local PID=$(cat $XTRABACKUP_PID)
|
||||
[ -n "$PID" -a "0" != "$PID" ] && kill $PID && (kill $PID && kill -9 $PID) || :
|
||||
rm -f "$XTRABACKUP_PID"
|
||||
}
|
||||
|
||||
setup_ports()
|
||||
{
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "donor" ]];then
|
||||
SST_PORT=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $2 }')
|
||||
REMOTEIP=$(echo $WSREP_SST_OPT_ADDR | awk -F ':' '{ print $1 }')
|
||||
lsn=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $4 }')
|
||||
else
|
||||
SST_PORT=$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $2 }')
|
||||
fi
|
||||
}
|
||||
|
||||
# waits ~10 seconds for nc to open the port and then reports ready
|
||||
# (regardless of timeout)
|
||||
wait_for_listen()
|
||||
{
|
||||
local PORT=$1
|
||||
local ADDR=$2
|
||||
local MODULE=$3
|
||||
for i in {1..50}
|
||||
do
|
||||
ss -p state listening "( sport = :$PORT )" | grep -qE 'socat|nc' && break
|
||||
sleep 0.2
|
||||
done
|
||||
if [[ $incremental -eq 1 ]];then
|
||||
echo "ready ${ADDR}/${MODULE}/$lsn"
|
||||
else
|
||||
echo "ready ${ADDR}/${MODULE}"
|
||||
fi
|
||||
}
|
||||
|
||||
check_extra()
|
||||
{
|
||||
local use_socket=1
|
||||
if [[ $uextra -eq 1 ]];then
|
||||
if my_print_defaults -c $WSREP_SST_OPT_CONF mysqld | tr '_' '-' | grep -- "--thread-handling=" | grep -q 'pool-of-threads';then
|
||||
local eport=$(my_print_defaults -c $WSREP_SST_OPT_CONF mysqld | tr '_' '-' | grep -- "--extra-port=" | cut -d= -f2)
|
||||
if [[ -n $eport ]];then
|
||||
# Xtrabackup works only locally.
|
||||
# Hence, setting host to 127.0.0.1 unconditionally.
|
||||
wsrep_log_info "SST through extra_port $eport"
|
||||
INNOEXTRA+=" --host=127.0.0.1 --port=$eport "
|
||||
use_socket=0
|
||||
else
|
||||
wsrep_log_error "Extra port $eport null, failing"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
wsrep_log_info "Thread pool not set, ignore the option use_extra"
|
||||
fi
|
||||
fi
|
||||
if [[ $use_socket -eq 1 ]] && [[ -n "${WSREP_SST_OPT_SOCKET}" ]];then
|
||||
INNOEXTRA+=" --socket=${WSREP_SST_OPT_SOCKET}"
|
||||
fi
|
||||
}
|
||||
|
||||
recv_joiner()
|
||||
{
|
||||
local dir=$1
|
||||
local msg=$2
|
||||
|
||||
pushd ${dir} 1>/dev/null
|
||||
set +e
|
||||
timeit "$msg" "$tcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )"
|
||||
set -e
|
||||
popd 1>/dev/null
|
||||
|
||||
|
||||
for ecode in "${RC[@]}";do
|
||||
if [[ $ecode -ne 0 ]];then
|
||||
wsrep_log_error "Error while getting data from donor node: " \
|
||||
"exit codes: ${RC[@]}"
|
||||
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}'"
|
||||
wsrep_log_info "Contents of datadir"
|
||||
wsrep_log_info "$(ls -l ${dir}/*)"
|
||||
exit 32
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
send_donor()
|
||||
{
|
||||
local dir=$1
|
||||
local msg=$2
|
||||
|
||||
pushd ${dir} 1>/dev/null
|
||||
set +e
|
||||
timeit "$msg" "$strmcmd | $tcmd; RC=( "\${PIPESTATUS[@]}" )"
|
||||
set -e
|
||||
popd 1>/dev/null
|
||||
|
||||
|
||||
for ecode in "${RC[@]}";do
|
||||
if [[ $ecode -ne 0 ]];then
|
||||
wsrep_log_error "Error while getting data from donor node: " \
|
||||
"exit codes: ${RC[@]}"
|
||||
exit 32
|
||||
fi
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
if [[ ! -x `which innobackupex` ]];then
|
||||
wsrep_log_error "innobackupex not in path: $PATH"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
rm -f "${MAGIC_FILE}"
|
||||
|
||||
if [[ ! ${WSREP_SST_OPT_ROLE} == 'joiner' && ! ${WSREP_SST_OPT_ROLE} == 'donor' ]];then
|
||||
wsrep_log_error "Invalid role ${WSREP_SST_OPT_ROLE}"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
read_cnf
|
||||
setup_ports
|
||||
get_stream
|
||||
get_transfer
|
||||
|
||||
if ${INNOBACKUPEX_BIN} /tmp --help | grep -q -- '--version-check'; then
|
||||
disver="--no-version-check"
|
||||
fi
|
||||
|
||||
|
||||
INNOEXTRA=""
|
||||
INNOAPPLY="${INNOBACKUPEX_BIN} $disver $iapts --apply-log \$rebuildcmd \${DATA} &>\${DATA}/innobackup.prepare.log"
|
||||
INNOMOVE="${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} $disver $impts --move-back --force-non-empty-directories \${DATA} &>\${DATA}/innobackup.move.log"
|
||||
INNOBACKUP="${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} $disver $iopts \$INNOEXTRA --galera-info --stream=\$sfmt \${TMPDIR} 2>\${DATA}/innobackup.backup.log"
|
||||
|
||||
if [ "$WSREP_SST_OPT_ROLE" = "donor" ]
|
||||
then
|
||||
trap cleanup_donor EXIT
|
||||
|
||||
if [ $WSREP_SST_OPT_BYPASS -eq 0 ]
|
||||
then
|
||||
|
||||
TMPDIR="${TMPDIR:-/tmp}"
|
||||
|
||||
if [ "${AUTH[0]}" != "(null)" ]; then
|
||||
INNOEXTRA+=" --user=${AUTH[0]}"
|
||||
fi
|
||||
|
||||
if [ ${#AUTH[*]} -eq 2 ]; then
|
||||
INNOEXTRA+=" --password=${AUTH[1]}"
|
||||
elif [ "${AUTH[0]}" != "(null)" ]; then
|
||||
# Empty password, used for testing, debugging etc.
|
||||
INNOEXTRA+=" --password="
|
||||
fi
|
||||
|
||||
get_keys
|
||||
if [[ $encrypt -eq 1 ]];then
|
||||
if [[ -n $ekey ]];then
|
||||
INNOEXTRA+=" --encrypt=$ealgo --encrypt-key=$ekey "
|
||||
else
|
||||
INNOEXTRA+=" --encrypt=$ealgo --encrypt-key-file=$ekeyfile "
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n $lsn ]];then
|
||||
INNOEXTRA+=" --incremental --incremental-lsn=$lsn "
|
||||
fi
|
||||
|
||||
check_extra
|
||||
|
||||
wsrep_log_info "Streaming GTID file before SST"
|
||||
|
||||
echo "${WSREP_SST_OPT_GTID}" > "${MAGIC_FILE}"
|
||||
|
||||
ttcmd="$tcmd"
|
||||
|
||||
if [[ $encrypt -eq 1 ]];then
|
||||
if [[ -n $scomp ]];then
|
||||
tcmd=" $ecmd | $scomp | $tcmd "
|
||||
else
|
||||
tcmd=" $ecmd | $tcmd "
|
||||
fi
|
||||
elif [[ -n $scomp ]];then
|
||||
tcmd=" $scomp | $tcmd "
|
||||
fi
|
||||
|
||||
|
||||
send_donor $DATA "${stagemsg}-gtid"
|
||||
|
||||
tcmd="$ttcmd"
|
||||
if [[ -n $progress ]];then
|
||||
get_footprint
|
||||
tcmd="$pcmd | $tcmd"
|
||||
elif [[ -n $rlimit ]];then
|
||||
adjust_progress
|
||||
tcmd="$pcmd | $tcmd"
|
||||
fi
|
||||
|
||||
wsrep_log_info "Sleeping before data transfer for SST"
|
||||
sleep 10
|
||||
|
||||
wsrep_log_info "Streaming the backup to joiner at ${REMOTEIP} ${SST_PORT:-4444}"
|
||||
|
||||
if [[ -n $scomp ]];then
|
||||
tcmd="$scomp | $tcmd"
|
||||
fi
|
||||
|
||||
set +e
|
||||
timeit "${stagemsg}-SST" "$INNOBACKUP | $tcmd; 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[$(( ${#RC[@]}-1 ))]} -eq 1 ]];then
|
||||
wsrep_log_error "$tcmd finished with error: ${RC[1]}"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
# innobackupex implicitly writes PID to fixed location in ${TMPDIR}
|
||||
XTRABACKUP_PID="${TMPDIR}/xtrabackup_pid"
|
||||
|
||||
|
||||
else # BYPASS FOR IST
|
||||
|
||||
wsrep_log_info "Bypassing the SST for IST"
|
||||
echo "continue" # now server can resume updating data
|
||||
echo "${WSREP_SST_OPT_GTID}" > "${MAGIC_FILE}"
|
||||
echo "1" > "${DATA}/${IST_FILE}"
|
||||
get_keys
|
||||
if [[ $encrypt -eq 1 ]];then
|
||||
if [[ -n $scomp ]];then
|
||||
tcmd=" $ecmd | $scomp | $tcmd "
|
||||
else
|
||||
tcmd=" $ecmd | $tcmd "
|
||||
fi
|
||||
elif [[ -n $scomp ]];then
|
||||
tcmd=" $scomp | $tcmd "
|
||||
fi
|
||||
strmcmd+=" \${IST_FILE}"
|
||||
|
||||
send_donor $DATA "${stagemsg}-IST"
|
||||
|
||||
fi
|
||||
|
||||
echo "done ${WSREP_SST_OPT_GTID}"
|
||||
wsrep_log_info "Total time on donor: $totime seconds"
|
||||
|
||||
elif [ "${WSREP_SST_OPT_ROLE}" = "joiner" ]
|
||||
then
|
||||
[[ -e $SST_PROGRESS_FILE ]] && wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE"
|
||||
[[ -n $SST_PROGRESS_FILE ]] && touch $SST_PROGRESS_FILE
|
||||
|
||||
if [[ $speciald -eq 1 ]];then
|
||||
wsrep_log_info "WARNING: sst-special-dirs feature requires PXC 2.1.6 or latter."
|
||||
fi
|
||||
|
||||
if [[ $speciald -eq 1 ]];then
|
||||
ib_home_dir=$(parse_cnf mysqld innodb-data-home-dir "")
|
||||
ib_log_dir=$(parse_cnf mysqld innodb-log-group-home-dir "")
|
||||
if [[ -z $ib_home_dir && -z $ib_log_dir ]];then
|
||||
speciald=0
|
||||
fi
|
||||
fi
|
||||
|
||||
stagemsg="Joiner-Recv"
|
||||
|
||||
if [[ ! -e ${DATA}/ibdata1 ]];then
|
||||
incremental=0
|
||||
fi
|
||||
|
||||
if [[ $incremental -eq 1 ]];then
|
||||
wsrep_log_info "Incremental SST enabled: NOT SUPPORTED yet"
|
||||
lsn=$(grep to_lsn xtrabackup_checkpoints | cut -d= -f2 | tr -d ' ')
|
||||
wsrep_log_info "Recovered LSN: $lsn"
|
||||
fi
|
||||
|
||||
sencrypted=1
|
||||
nthreads=1
|
||||
|
||||
MODULE="xtrabackup_sst"
|
||||
|
||||
rm -f "${DATA}/${IST_FILE}"
|
||||
|
||||
# May need xtrabackup_checkpoints later on
|
||||
rm -f ${DATA}/xtrabackup_binary ${DATA}/xtrabackup_galera_info ${DATA}/xtrabackup_logfile
|
||||
|
||||
ADDR=${WSREP_SST_OPT_ADDR}
|
||||
if [ -z "${SST_PORT}" ]
|
||||
then
|
||||
SST_PORT=4444
|
||||
ADDR="$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $1 }'):${SST_PORT}"
|
||||
fi
|
||||
|
||||
wait_for_listen ${SST_PORT} ${ADDR} ${MODULE} &
|
||||
|
||||
trap sig_joiner_cleanup HUP PIPE INT TERM
|
||||
trap cleanup_joiner EXIT
|
||||
|
||||
if [[ -n $progress ]];then
|
||||
adjust_progress
|
||||
tcmd+=" | $pcmd"
|
||||
fi
|
||||
|
||||
if [[ $incremental -eq 1 ]];then
|
||||
BDATA=$DATA
|
||||
DATA=$(mktemp -d)
|
||||
MAGIC_FILE="${DATA}/${INFO_FILE}"
|
||||
fi
|
||||
|
||||
get_keys
|
||||
if [[ $encrypt -eq 1 && $sencrypted -eq 1 ]];then
|
||||
if [[ -n $sdecomp ]];then
|
||||
strmcmd=" $sdecomp | $ecmd | $strmcmd"
|
||||
else
|
||||
strmcmd=" $ecmd | $strmcmd"
|
||||
fi
|
||||
elif [[ -n $sdecomp ]];then
|
||||
strmcmd=" $sdecomp | $strmcmd"
|
||||
fi
|
||||
|
||||
STATDIR=$(mktemp -d)
|
||||
MAGIC_FILE="${STATDIR}/${INFO_FILE}"
|
||||
recv_joiner $STATDIR "${stagemsg}-gtid" 1
|
||||
|
||||
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 "${STATDIR}/${IST_FILE}" ]
|
||||
then
|
||||
wsrep_log_info "Proceeding with SST"
|
||||
|
||||
if [[ $speciald -eq 1 && -d ${DATA}/.sst ]];then
|
||||
wsrep_log_info "WARNING: Stale temporary SST directory: ${DATA}/.sst from previous SST"
|
||||
fi
|
||||
|
||||
if [[ $incremental -ne 1 ]];then
|
||||
if [[ $speciald -eq 1 ]];then
|
||||
wsrep_log_info "Cleaning the existing datadir and innodb-data/log directories"
|
||||
find $ib_home_dir $ib_log_dir $DATA -mindepth 1 -regex $cpat -prune -o -exec rm -rfv {} 1>&2 \+
|
||||
else
|
||||
wsrep_log_info "Cleaning the existing datadir"
|
||||
find $DATA -mindepth 1 -regex $cpat -prune -o -exec rm -rfv {} 1>&2 \+
|
||||
fi
|
||||
tempdir=$(parse_cnf mysqld log-bin "")
|
||||
if [[ -n ${tempdir:-} ]];then
|
||||
binlog_dir=$(dirname $tempdir)
|
||||
binlog_file=$(basename $tempdir)
|
||||
if [[ -n ${binlog_dir:-} && $binlog_dir != '.' && $binlog_dir != $DATA ]];then
|
||||
pattern="$binlog_dir/$binlog_file\.[0-9]+$"
|
||||
wsrep_log_info "Cleaning the binlog directory $binlog_dir as well"
|
||||
find $binlog_dir -maxdepth 1 -type f -regex $pattern -exec rm -fv {} 1>&2 \+
|
||||
rm $binlog_dir/*.index || true
|
||||
fi
|
||||
fi
|
||||
|
||||
else
|
||||
wsrep_log_info "Removing existing ib_logfile files"
|
||||
rm -f ${BDATA}/ib_logfile*
|
||||
fi
|
||||
|
||||
|
||||
if [[ $speciald -eq 1 ]];then
|
||||
mkdir -p ${DATA}/.sst
|
||||
TDATA=${DATA}
|
||||
DATA="${DATA}/.sst"
|
||||
fi
|
||||
|
||||
|
||||
MAGIC_FILE="${DATA}/${INFO_FILE}"
|
||||
recv_joiner $DATA "${stagemsg}-SST" 0
|
||||
|
||||
get_proc
|
||||
|
||||
# Rebuild indexes for compact backups
|
||||
if grep -q 'compact = 1' ${DATA}/xtrabackup_checkpoints;then
|
||||
wsrep_log_info "Index compaction detected"
|
||||
rebuild=1
|
||||
fi
|
||||
|
||||
if [[ $rebuild -eq 1 ]];then
|
||||
nthreads=$(parse_cnf xtrabackup rebuild-threads $nproc)
|
||||
wsrep_log_info "Rebuilding during prepare with $nthreads threads"
|
||||
rebuildcmd="--rebuild-indexes --rebuild-threads=$nthreads"
|
||||
fi
|
||||
|
||||
if test -n "$(find ${DATA} -maxdepth 1 -type f -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: $PATH"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
if [[ -n $progress ]] && pv --help | grep -q 'line-mode';then
|
||||
count=$(find ${DATA} -type f -name '*.qp' | wc -l)
|
||||
count=$(( count*2 ))
|
||||
if pv --help | grep -q FORMAT;then
|
||||
pvopts="-f -s $count -l -N Decompression -F '%N => Rate:%r Elapsed:%t %e Progress: [%b/$count]'"
|
||||
else
|
||||
pvopts="-f -s $count -l -N Decompression"
|
||||
fi
|
||||
pcmd="pv $pvopts"
|
||||
adjust_progress
|
||||
dcmd="$pcmd | xargs -n 2 qpress -T${nproc}d"
|
||||
else
|
||||
dcmd="xargs -n 2 qpress -T${nproc}d"
|
||||
fi
|
||||
|
||||
|
||||
# Decompress the qpress files
|
||||
wsrep_log_info "Decompression with $nproc threads"
|
||||
timeit "Joiner-Decompression" "find ${DATA} -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd"
|
||||
extcode=$?
|
||||
|
||||
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
|
||||
|
||||
if [[ $incremental -eq 1 ]];then
|
||||
# Added --ibbackup=xtrabackup_55 because it fails otherwise citing connection issues.
|
||||
INNOAPPLY="${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} \
|
||||
--ibbackup=xtrabackup_55 --apply-log $rebuildcmd --redo-only $BDATA --incremental-dir=${DATA} &>>${BDATA}/innobackup.prepare.log"
|
||||
fi
|
||||
|
||||
wsrep_log_info "Preparing the backup at ${DATA}"
|
||||
timeit "Xtrabackup prepare stage" "$INNOAPPLY"
|
||||
|
||||
if [ $? -ne 0 ];
|
||||
then
|
||||
wsrep_log_error "${INNOBACKUPEX_BIN} apply finished with errors. Check ${DATA}/innobackup.prepare.log"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
if [[ $speciald -eq 1 ]];then
|
||||
MAGIC_FILE="${TDATA}/${INFO_FILE}"
|
||||
set +e
|
||||
rm $TDATA/innobackup.prepare.log $TDATA/innobackup.move.log
|
||||
set -e
|
||||
wsrep_log_info "Moving the backup to ${TDATA}"
|
||||
timeit "Xtrabackup move stage" "$INNOMOVE"
|
||||
if [[ $? -eq 0 ]];then
|
||||
wsrep_log_info "Move successful, removing ${DATA}"
|
||||
rm -rf $DATA
|
||||
DATA=${TDATA}
|
||||
else
|
||||
wsrep_log_error "Move failed, keeping ${DATA} for further diagnosis"
|
||||
wsrep_log_error "Check ${DATA}/innobackup.move.log for details"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ $incremental -eq 1 ]];then
|
||||
wsrep_log_info "Cleaning up ${DATA} after incremental SST"
|
||||
[[ -d ${DATA} ]] && rm -rf ${DATA}
|
||||
DATA=$BDATA
|
||||
fi
|
||||
|
||||
else
|
||||
wsrep_log_info "${IST_FILE} received from donor: Running IST"
|
||||
fi
|
||||
|
||||
if [[ ! -r ${MAGIC_FILE} ]];then
|
||||
wsrep_log_error "SST magic file ${MAGIC_FILE} not found/readable"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
cat "${MAGIC_FILE}" # output UUID:seqno
|
||||
wsrep_log_info "Total time on joiner: $totime seconds"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
|
@ -15,25 +15,11 @@
|
|||
# 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 #
|
||||
# #
|
||||
#############################################################################################################
|
||||
# Optional dependencies and options documented here: http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html
|
||||
# Make sure to read that before proceeding!
|
||||
|
||||
|
||||
|
||||
|
||||
. $(dirname $0)/wsrep_sst_common
|
||||
|
||||
|
|
@ -44,28 +30,89 @@ encrypt=0
|
|||
nproc=1
|
||||
ecode=0
|
||||
XTRABACKUP_PID=""
|
||||
SST_PORT=""
|
||||
REMOTEIP=""
|
||||
tcert=""
|
||||
tpem=""
|
||||
sockopt=""
|
||||
progress=""
|
||||
ttime=0
|
||||
totime=0
|
||||
lsn=""
|
||||
incremental=0
|
||||
ecmd=""
|
||||
rlimit=""
|
||||
|
||||
sfmt="tar"
|
||||
strmcmd=""
|
||||
tfmt=""
|
||||
tcmd=""
|
||||
rebuild=0
|
||||
rebuildcmd=""
|
||||
payload=0
|
||||
pvformat="-F '%N => Rate:%r Avg:%a Elapsed:%t %e Bytes: %b %p' "
|
||||
pvopts="-f -i 10 -N $WSREP_SST_OPT_ROLE "
|
||||
uextra=0
|
||||
|
||||
if which pv &>/dev/null && pv --help | grep -q FORMAT;then
|
||||
pvopts+=$pvformat
|
||||
fi
|
||||
pcmd="pv $pvopts"
|
||||
declare -a RC
|
||||
|
||||
INNOBACKUPEX_BIN=innobackupex
|
||||
readonly AUTH=(${WSREP_SST_OPT_AUTH//:/ })
|
||||
DATA="${WSREP_SST_OPT_DATA}"
|
||||
INFO_FILE="xtrabackup_galera_info"
|
||||
IST_FILE="xtrabackup_ist"
|
||||
MAGIC_FILE="${DATA}/${INFO_FILE}"
|
||||
|
||||
# Setting the path for ss and ip
|
||||
export PATH="/usr/sbin:/sbin:$PATH"
|
||||
|
||||
timeit(){
|
||||
local stage=$1
|
||||
shift
|
||||
local cmd="$@"
|
||||
local x1 x2 took extcode
|
||||
|
||||
if [[ $ttime -eq 1 ]];then
|
||||
x1=$(date +%s)
|
||||
wsrep_log_info "Evaluating $cmd"
|
||||
eval "$cmd"
|
||||
extcode=$?
|
||||
x2=$(date +%s)
|
||||
took=$(( x2-x1 ))
|
||||
wsrep_log_info "NOTE: $stage took $took seconds"
|
||||
totime=$(( totime+took ))
|
||||
else
|
||||
wsrep_log_info "Evaluating $cmd"
|
||||
eval "$cmd"
|
||||
extcode=$?
|
||||
fi
|
||||
return $extcode
|
||||
}
|
||||
|
||||
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"
|
||||
if [[ $encrypt -eq 2 ]];then
|
||||
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 [[ $encrypt -eq 0 ]];then
|
||||
if my_print_defaults -c $WSREP_SST_OPT_CONF xtrabackup | grep -q encrypt;then
|
||||
wsrep_log_error "Unexpected option combination. SST may fail. Refer to http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html "
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
if [[ $sfmt == 'tar' ]];then
|
||||
wsrep_log_info "NOTE: Xtrabackup-based encryption - encrypt=1 - cannot be enabled with tar format"
|
||||
encrypt=0
|
||||
return
|
||||
fi
|
||||
|
||||
wsrep_log_info "Xtrabackup based encryption enabled in my.cnf - Supported only from Xtrabackup 2.1.4"
|
||||
|
||||
if [[ -z $ealgo ]];then
|
||||
wsrep_log_error "FATAL: Encryption algorithm empty from my.cnf, bailing out"
|
||||
|
|
@ -76,35 +123,160 @@ get_keys()
|
|||
wsrep_log_error "FATAL: Either key or keyfile must be readable"
|
||||
exit 3
|
||||
fi
|
||||
encrypt=1
|
||||
|
||||
if [[ -z $ekey ]];then
|
||||
ecmd="xbcrypt --encrypt-algo=$ealgo --encrypt-key-file=$ekeyfile"
|
||||
else
|
||||
ecmd="xbcrypt --encrypt-algo=$ealgo --encrypt-key=$ekey"
|
||||
fi
|
||||
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
ecmd+=" -d"
|
||||
fi
|
||||
}
|
||||
|
||||
get_transfer()
|
||||
{
|
||||
if [[ -z $SST_PORT ]];then
|
||||
TSST_PORT=4444
|
||||
else
|
||||
TSST_PORT=$SST_PORT
|
||||
fi
|
||||
|
||||
if [[ $tfmt == 'nc' ]];then
|
||||
if [[ ! -x `which nc` ]];then
|
||||
wsrep_log_error "nc(netcat) not found in path: $PATH"
|
||||
exit 2
|
||||
fi
|
||||
wsrep_log_info "Using netcat as streamer"
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
tcmd="nc -dl ${TSST_PORT}"
|
||||
else
|
||||
tcmd="nc ${REMOTEIP} ${TSST_PORT}"
|
||||
fi
|
||||
else
|
||||
tfmt='socat'
|
||||
wsrep_log_info "Using socat as streamer"
|
||||
if [[ ! -x `which socat` ]];then
|
||||
wsrep_log_error "socat not found in path: $PATH"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [[ $encrypt -eq 2 ]] && ! socat -V | grep -q OPENSSL;then
|
||||
wsrep_log_info "NOTE: socat is not openssl enabled, falling back to plain transfer"
|
||||
encrypt=0
|
||||
fi
|
||||
|
||||
if [[ $encrypt -eq 2 ]];then
|
||||
wsrep_log_info "Using openssl based encryption with socat"
|
||||
if [[ -z $tpem || -z $tcert ]];then
|
||||
wsrep_log_error "Both PEM and CRT files required"
|
||||
exit 22
|
||||
fi
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
wsrep_log_info "Decrypting with PEM $tpem, CA: $tcert"
|
||||
tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=$tpem,cafile=${tcert}${sockopt} stdio"
|
||||
else
|
||||
wsrep_log_info "Encrypting with PEM $tpem, CA: $tcert"
|
||||
tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=$tpem,cafile=${tcert}${sockopt}"
|
||||
fi
|
||||
else
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||
tcmd="socat -u TCP-LISTEN:${TSST_PORT},reuseaddr${sockopt} stdio"
|
||||
else
|
||||
tcmd="socat -u stdio TCP:${REMOTEIP}:${TSST_PORT}${sockopt}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
parse_cnf()
|
||||
{
|
||||
local group=$1
|
||||
local var=$2
|
||||
reval=$(my_print_defaults -c $WSREP_SST_OPT_CONF $group | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2-)
|
||||
if [[ -z $reval ]];then
|
||||
[[ -n $3 ]] && reval=$3
|
||||
fi
|
||||
echo $reval
|
||||
}
|
||||
|
||||
get_footprint()
|
||||
{
|
||||
pushd $WSREP_SST_OPT_DATA 1>/dev/null
|
||||
payload=$(du --block-size=1 -c **/*.ibd **/*.MYI **/*.MYI ibdata1 | awk 'END { print $1 }')
|
||||
if my_print_defaults -c $WSREP_SST_OPT_CONF xtrabackup | grep -q -- "--compress";then
|
||||
# QuickLZ has around 50% compression ratio
|
||||
# When compression/compaction used, the progress is only an approximate.
|
||||
payload=$(( payload*1/2 ))
|
||||
fi
|
||||
popd 1>/dev/null
|
||||
pcmd+=" -s $payload"
|
||||
adjust_progress
|
||||
}
|
||||
|
||||
adjust_progress()
|
||||
{
|
||||
if [[ -n $progress && $progress != '1' ]];then
|
||||
if [[ -e $progress ]];then
|
||||
pcmd+=" 2>>$progress"
|
||||
else
|
||||
pcmd+=" 2>$progress"
|
||||
fi
|
||||
elif [[ -z $progress && -n $rlimit ]];then
|
||||
# When rlimit is non-zero
|
||||
pcmd="pv -q"
|
||||
fi
|
||||
|
||||
if [[ -n $rlimit && "$WSREP_SST_OPT_ROLE" == "donor" ]];then
|
||||
wsrep_log_info "Rate-limiting SST to $rlimit"
|
||||
pcmd+=" -L \$rlimit"
|
||||
fi
|
||||
}
|
||||
|
||||
read_cnf()
|
||||
{
|
||||
sfmt=$(my_print_defaults -c $WSREP_SST_OPT_CONF sst | grep -- '--streamfmt' | cut -d= -f2)
|
||||
sfmt=$(parse_cnf sst streamfmt "tar")
|
||||
tfmt=$(parse_cnf sst transferfmt "socat")
|
||||
tcert=$(parse_cnf sst tca "")
|
||||
tpem=$(parse_cnf sst tcert "")
|
||||
encrypt=$(parse_cnf sst encrypt 0)
|
||||
sockopt=$(parse_cnf sst sockopt "")
|
||||
progress=$(parse_cnf sst progress "")
|
||||
rebuild=$(parse_cnf sst rebuild 0)
|
||||
ttime=$(parse_cnf sst time 0)
|
||||
incremental=$(parse_cnf sst incremental 0)
|
||||
ealgo=$(parse_cnf xtrabackup encrypt "")
|
||||
ekey=$(parse_cnf xtrabackup encrypt-key "")
|
||||
ekeyfile=$(parse_cnf xtrabackup encrypt-key-file "")
|
||||
|
||||
# Refer to http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html
|
||||
if [[ -z $ealgo ]];then
|
||||
ealgo=$(parse_cnf sst encrypt-algo "")
|
||||
ekey=$(parse_cnf sst encrypt-key "")
|
||||
ekeyfile=$(parse_cnf sst encrypt-key-file "")
|
||||
fi
|
||||
rlimit=$(parse_cnf sst rlimit "")
|
||||
uextra=$(parse_cnf sst use_extra 0)
|
||||
}
|
||||
|
||||
get_stream()
|
||||
{
|
||||
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}"
|
||||
strmcmd="xbstream -x"
|
||||
else
|
||||
wsrep_log_error "Invalid role: $WSREP_SST_OPT_ROLE"
|
||||
exit 22
|
||||
strmcmd="xbstream -c \${INFO_FILE} \${IST_FILE}"
|
||||
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}"
|
||||
strmcmd="tar xfi - --recursive-unlink -h"
|
||||
else
|
||||
wsrep_log_error "Invalid role: $WSREP_SST_OPT_ROLE"
|
||||
exit 22
|
||||
strmcmd="tar cf - \${INFO_FILE} \${IST_FILE}"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
|
@ -118,6 +290,12 @@ get_proc()
|
|||
set -e
|
||||
}
|
||||
|
||||
sig_joiner_cleanup()
|
||||
{
|
||||
wsrep_log_error "Removing $MAGIC_FILE file due to signal"
|
||||
rm -f "$MAGIC_FILE"
|
||||
}
|
||||
|
||||
cleanup_joiner()
|
||||
{
|
||||
# Since this is invoked just after exit NNN
|
||||
|
|
@ -125,18 +303,14 @@ cleanup_joiner()
|
|||
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
|
||||
if [[ -n $progress && -p $progress ]];then
|
||||
wsrep_log_info "Cleaning up fifo file $progress"
|
||||
rm $progress
|
||||
fi
|
||||
}
|
||||
|
||||
check_pid()
|
||||
|
|
@ -152,119 +326,161 @@ cleanup_donor()
|
|||
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"
|
||||
if [[ -n $XTRABACKUP_PID ]];then
|
||||
if check_pid $XTRABACKUP_PID
|
||||
then
|
||||
wsrep_log_error "xtrabackup process is still running. Killing... "
|
||||
kill_xtrabackup
|
||||
fi
|
||||
|
||||
rm -f $XTRABACKUP_PID
|
||||
fi
|
||||
rm -f ${DATA}/${IST_FILE}
|
||||
|
||||
if [[ -n $progress && -p $progress ]];then
|
||||
wsrep_log_info "Cleaning up fifo file $progress"
|
||||
rm $progress
|
||||
fi
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
setup_ports()
|
||||
{
|
||||
if [[ "$WSREP_SST_OPT_ROLE" == "donor" ]];then
|
||||
SST_PORT=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $2 }')
|
||||
REMOTEIP=$(echo $WSREP_SST_OPT_ADDR | awk -F ':' '{ print $1 }')
|
||||
lsn=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $4 }')
|
||||
else
|
||||
SST_PORT=$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $2 }')
|
||||
fi
|
||||
}
|
||||
|
||||
# waits ~10 seconds for nc to open the port and then reports ready
|
||||
# (regardless of timeout)
|
||||
wait_for_nc()
|
||||
wait_for_listen()
|
||||
{
|
||||
local PORT=$1
|
||||
local ADDR=$2
|
||||
local MODULE=$3
|
||||
for i in $(seq 1 50)
|
||||
for i in {1..50}
|
||||
do
|
||||
netstat -nptl 2>/dev/null | grep '/nc\s*$' | awk '{ print $4 }' | \
|
||||
sed 's/.*://' | grep \^${PORT}\$ >/dev/null && break
|
||||
ss -p state listening "( sport = :$PORT )" | grep -qE 'socat|nc' && break
|
||||
sleep 0.2
|
||||
done
|
||||
if [[ $incremental -eq 1 ]];then
|
||||
echo "ready ${ADDR}/${MODULE}/$lsn"
|
||||
else
|
||||
echo "ready ${ADDR}/${MODULE}"
|
||||
fi
|
||||
}
|
||||
|
||||
INNOBACKUPEX_BIN=innobackupex
|
||||
INNOBACKUPEX_ARGS=""
|
||||
NC_BIN=nc
|
||||
check_extra()
|
||||
{
|
||||
local use_socket=1
|
||||
if [[ $uextra -eq 1 ]];then
|
||||
if my_print_defaults -c $WSREP_SST_OPT_CONF mysqld | tr '_' '-' | grep -- "--thread-handling=" | grep -q 'pool-of-threads';then
|
||||
local eport=$(my_print_defaults -c $WSREP_SST_OPT_CONF mysqld | tr '_' '-' | grep -- "--extra-port=" | cut -d= -f2)
|
||||
if [[ -n $eport ]];then
|
||||
# Xtrabackup works only locally.
|
||||
# Hence, setting host to 127.0.0.1 unconditionally.
|
||||
wsrep_log_info "SST through extra_port $eport"
|
||||
INNOEXTRA+=" --host=127.0.0.1 --port=$eport "
|
||||
use_socket=0
|
||||
else
|
||||
wsrep_log_error "Extra port $eport null, failing"
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
wsrep_log_info "Thread pool not set, ignore the option use_extra"
|
||||
fi
|
||||
fi
|
||||
if [[ $use_socket -eq 1 ]] && [[ -n "${WSREP_SST_OPT_SOCKET}" ]];then
|
||||
INNOEXTRA+=" --socket=${WSREP_SST_OPT_SOCKET}"
|
||||
fi
|
||||
}
|
||||
|
||||
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
|
||||
if [[ ! -x `which innobackupex` ]];then
|
||||
wsrep_log_error "innobackupex not in path: $PATH"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
#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}"
|
||||
|
||||
if [[ ! ${WSREP_SST_OPT_ROLE} == 'joiner' && ! ${WSREP_SST_OPT_ROLE} == 'donor' ]];then
|
||||
wsrep_log_error "Invalid role ${WSREP_SST_OPT_ROLE}"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
read_cnf
|
||||
setup_ports
|
||||
get_stream
|
||||
get_transfer
|
||||
|
||||
INNOEXTRA=""
|
||||
INNOAPPLY="${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} --apply-log \$rebuildcmd \${DATA} &>\${DATA}/innobackup.prepare.log"
|
||||
INNOBACKUP="${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} \$INNOEXTRA --galera-info --stream=\$sfmt \${TMPDIR} 2>\${DATA}/innobackup.backup.log"
|
||||
|
||||
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}"
|
||||
TMPDIR="${TMPDIR:-/tmp}"
|
||||
|
||||
if [ "${AUTH[0]}" != "(null)" ]; then
|
||||
INNOBACKUPEX_ARGS="${INNOBACKUPEX_ARGS} --user=${AUTH[0]}"
|
||||
fi
|
||||
INNOEXTRA+=" --user=${AUTH[0]}"
|
||||
fi
|
||||
|
||||
if [ ${#AUTH[*]} -eq 2 ]; then
|
||||
INNOBACKUPEX_ARGS="${INNOBACKUPEX_ARGS} --password=${AUTH[1]}"
|
||||
else
|
||||
INNOEXTRA+=" --password=${AUTH[1]}"
|
||||
elif [ "${AUTH[0]}" != "(null)" ]; then
|
||||
# Empty password, used for testing, debugging etc.
|
||||
INNOBACKUPEX_ARGS="${INNOBACKUPEX_ARGS} --password="
|
||||
fi
|
||||
INNOEXTRA+=" --password="
|
||||
fi
|
||||
|
||||
get_keys
|
||||
if [[ $encrypt -eq 1 ]];then
|
||||
if [[ -n $ekey ]];then
|
||||
INNOBACKUPEX_ARGS="${INNOBACKUPEX_ARGS} --encrypt=$ealgo --encrypt-key=$ekey"
|
||||
INNOEXTRA+=" --encrypt=$ealgo --encrypt-key=$ekey "
|
||||
else
|
||||
INNOBACKUPEX_ARGS="${INNOBACKUPEX_ARGS} --encrypt=$ealgo --encrypt-key-file=$ekeyfile"
|
||||
INNOEXTRA+=" --encrypt=$ealgo --encrypt-key-file=$ekeyfile "
|
||||
fi
|
||||
fi
|
||||
|
||||
wsrep_log_info "Streaming the backup to joiner at ${REMOTEIP} ${NC_PORT}"
|
||||
if [[ -n $lsn ]];then
|
||||
INNOEXTRA+=" --incremental --incremental-lsn=$lsn "
|
||||
fi
|
||||
|
||||
check_extra
|
||||
|
||||
wsrep_log_info "Streaming the backup to joiner at ${REMOTEIP} ${SST_PORT}"
|
||||
|
||||
if [[ -n $progress ]];then
|
||||
get_footprint
|
||||
tcmd="$pcmd | $tcmd"
|
||||
elif [[ -n $rlimit ]];then
|
||||
adjust_progress
|
||||
tcmd="$pcmd | $tcmd"
|
||||
fi
|
||||
|
||||
set +e
|
||||
${INNOBACKUPEX_BIN} ${INNOBACKUPEX_ARGS} ${TMPDIR} \
|
||||
2> ${DATA}/innobackup.backup.log | \
|
||||
${NC_BIN} ${REMOTEIP} ${NC_PORT}
|
||||
|
||||
RC=( "${PIPESTATUS[@]}" )
|
||||
timeit "Donor-Transfer" "$INNOBACKUP | $tcmd; 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]}"
|
||||
elif [[ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]];then
|
||||
wsrep_log_error "$tcmd finished with error: ${RC[1]}"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
|
|
@ -272,7 +488,8 @@ then
|
|||
XTRABACKUP_PID="${TMPDIR}/xtrabackup_pid"
|
||||
|
||||
|
||||
else # BYPASS
|
||||
else # BYPASS FOR IST
|
||||
|
||||
wsrep_log_info "Bypassing the SST for IST"
|
||||
STATE="${WSREP_SST_OPT_GTID}"
|
||||
echo "continue" # now server can resume updating data
|
||||
|
|
@ -282,15 +499,9 @@ then
|
|||
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}
|
||||
tcmd=" $ecmd | $tcmd"
|
||||
fi
|
||||
RC=( "${PIPESTATUS[@]}" )
|
||||
timeit "Donor-IST-Unencrypted-transfer" "$strmcmd | $tcmd; RC=( "\${PIPESTATUS[@]}" )"
|
||||
set -e
|
||||
popd 1>/dev/null
|
||||
|
||||
|
|
@ -301,62 +512,81 @@ then
|
|||
exit 1
|
||||
fi
|
||||
done
|
||||
#rm -f ${DATA}/${IST_FILE}
|
||||
fi
|
||||
|
||||
echo "done ${WSREP_SST_OPT_GTID}"
|
||||
wsrep_log_info "Total time on donor: $totime seconds"
|
||||
|
||||
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
|
||||
|
||||
if [[ ! -e ${DATA}/ibdata1 ]];then
|
||||
incremental=0
|
||||
fi
|
||||
|
||||
if [[ $incremental -eq 1 ]];then
|
||||
wsrep_log_info "Incremental SST enabled"
|
||||
#lsn=$(/pxc/bin/mysqld --defaults-file=$WSREP_SST_OPT_CONF --basedir=/pxc --wsrep-recover 2>&1 | grep -o 'log sequence number .*' | cut -d " " -f 4 | head -1)
|
||||
lsn=$(grep to_lsn xtrabackup_checkpoints | cut -d= -f2 | tr -d ' ')
|
||||
wsrep_log_info "Recovered LSN: $lsn"
|
||||
fi
|
||||
|
||||
sencrypted=1
|
||||
nthreads=1
|
||||
|
||||
MODULE="xtrabackup_sst"
|
||||
|
||||
rm -f ${DATA}/xtrabackup_*
|
||||
# May need xtrabackup_checkpoints later on
|
||||
rm -f ${DATA}/xtrabackup_binary ${DATA}/xtrabackup_galera_info ${DATA}/xtrabackup_logfile
|
||||
|
||||
ADDR=${WSREP_SST_OPT_ADDR}
|
||||
NC_PORT=$(echo ${ADDR} | awk -F ':' '{ print $2 }')
|
||||
if [ -z "${NC_PORT}" ]
|
||||
if [ -z "${SST_PORT}" ]
|
||||
then
|
||||
NC_PORT=4444
|
||||
ADDR="$(echo ${ADDR} | awk -F ':' '{ print $1 }'):${NC_PORT}"
|
||||
SST_PORT=4444
|
||||
ADDR="$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $1 }'):${SST_PORT}"
|
||||
fi
|
||||
|
||||
wait_for_nc ${NC_PORT} ${ADDR} ${MODULE} &
|
||||
wait_for_listen ${SST_PORT} ${ADDR} ${MODULE} &
|
||||
|
||||
trap "exit 32" HUP PIPE
|
||||
trap "exit 3" INT TERM
|
||||
trap sig_joiner_cleanup HUP PIPE INT TERM
|
||||
trap cleanup_joiner EXIT
|
||||
|
||||
if [[ -n $progress ]];then
|
||||
adjust_progress
|
||||
tcmd+=" | $pcmd"
|
||||
fi
|
||||
|
||||
if [[ $incremental -eq 1 ]];then
|
||||
BDATA=$DATA
|
||||
DATA=$(mktemp -d)
|
||||
MAGIC_FILE="${DATA}/${INFO_FILE}"
|
||||
fi
|
||||
|
||||
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
|
||||
strmcmd=" $ecmd | $strmcmd"
|
||||
fi
|
||||
RC=( "${PIPESTATUS[@]}" )
|
||||
|
||||
pushd ${DATA} 1>/dev/null
|
||||
timeit "Joiner-Recv-Unencrypted" "$tcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )"
|
||||
popd 1>/dev/null
|
||||
|
||||
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" \
|
||||
wsrep_log_error "Data directory ${DATA} may not be empty: lp:1193240" \
|
||||
"Manual intervention required in that case"
|
||||
exit 32
|
||||
fi
|
||||
fi
|
||||
|
||||
wait %% # join wait_for_nc thread
|
||||
wait %% # join for wait_for_listen thread
|
||||
|
||||
for ecode in "${RC[@]}";do
|
||||
if [[ $ecode -ne 0 ]];then
|
||||
|
|
@ -370,43 +600,25 @@ then
|
|||
then
|
||||
# this message should cause joiner to abort
|
||||
wsrep_log_error "xtrabackup process ended without creating '${MAGIC_FILE}'"
|
||||
wsrep_log_info "Contents of datadir"
|
||||
wsrep_log_info "$(ls -l ${DATA}/**/*)"
|
||||
exit 32
|
||||
fi
|
||||
|
||||
if ! ps -p ${WSREP_SST_OPT_PARENT} >/dev/null
|
||||
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}" ]
|
||||
if [ ! -r "${DATA}/${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
|
||||
if [[ $incremental -ne 1 ]];then
|
||||
rm -f ${DATA}/ib_logfile*
|
||||
else
|
||||
rm -f ${BDATA}/ib_logfile*
|
||||
fi
|
||||
|
||||
get_proc
|
||||
|
|
@ -414,33 +626,47 @@ then
|
|||
# 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"
|
||||
rebuild=1
|
||||
fi
|
||||
|
||||
if test -n "$(find ${DATA} -maxdepth 1 -name '*.qp' -print -quit)";then
|
||||
if [[ $rebuild -eq 1 ]];then
|
||||
nthreads=$(parse_cnf xtrabackup rebuild-threads $nproc)
|
||||
wsrep_log_info "Rebuilding during prepare with $nthreads threads"
|
||||
rebuildcmd="--rebuild-indexes --rebuild-threads=$nthreads"
|
||||
fi
|
||||
|
||||
if test -n "$(find ${DATA} -maxdepth 1 -type f -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"
|
||||
wsrep_log_error "qpress not found in path: $PATH"
|
||||
exit 22
|
||||
fi
|
||||
|
||||
set +e
|
||||
if [[ -n $progress ]] && pv --help | grep -q 'line-mode';then
|
||||
count=$(find ${DATA} -type f -name '*.qp' | wc -l)
|
||||
count=$(( count*2 ))
|
||||
if pv --help | grep -q FORMAT;then
|
||||
pvopts="-f -s $count -l -N Decompression -F '%N => Rate:%r Elapsed:%t %e Progress: [%b/$count]'"
|
||||
else
|
||||
pvopts="-f -s $count -l -N Decompression"
|
||||
fi
|
||||
pcmd="pv $pvopts"
|
||||
adjust_progress
|
||||
dcmd="$pcmd | xargs -n 2 qpress -T${nproc}d"
|
||||
else
|
||||
dcmd="xargs -n 2 qpress -T${nproc}d"
|
||||
fi
|
||||
|
||||
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
|
||||
timeit "Decompression" "find ${DATA} -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd"
|
||||
extcode=$?
|
||||
|
||||
set -e
|
||||
|
||||
if [[ $extcode -eq 0 ]];then
|
||||
wsrep_log_info "Removing qpress files after decompression"
|
||||
find ${DATA} -type f -name '*.qp' -delete
|
||||
|
|
@ -453,10 +679,21 @@ then
|
|||
fi
|
||||
fi
|
||||
|
||||
wsrep_log_info "Preparing the backup at ${DATA}"
|
||||
if [[ $incremental -eq 1 ]];then
|
||||
# Added --ibbackup=xtrabackup_55 because it fails otherwise citing connection issues.
|
||||
INNOAPPLY="${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} \
|
||||
--ibbackup=xtrabackup_55 --apply-log $rebuildcmd --redo-only $BDATA --incremental-dir=${DATA} &>>${BDATA}/innobackup.prepare.log"
|
||||
fi
|
||||
|
||||
wsrep_log_info "Preparing the backup at ${DATA}"
|
||||
timeit "Xtrabackup prepare stage" "$INNOAPPLY"
|
||||
|
||||
if [[ $incremental -eq 1 ]];then
|
||||
wsrep_log_info "Cleaning up ${DATA} after incremental SST"
|
||||
[[ -d ${DATA} ]] && rm -rf ${DATA}
|
||||
DATA=$BDATA
|
||||
fi
|
||||
|
||||
${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"
|
||||
|
|
@ -466,14 +703,13 @@ then
|
|||
wsrep_log_info "${IST_FILE} received from donor: Running IST"
|
||||
fi
|
||||
|
||||
if [[ ! -r ${MAGIC_FILE} ]];then
|
||||
wsrep_log_error "SST magic file ${MAGIC_FILE} not found/readable"
|
||||
exit 2
|
||||
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
|
||||
wsrep_log_info "Total time on joiner: $totime seconds"
|
||||
fi
|
||||
|
||||
exit 0
|
||||
|
|
|
|||
33
sql/slave.cc
33
sql/slave.cc
|
|
@ -3456,12 +3456,18 @@ pthread_handler_t handle_slave_sql(void *arg)
|
|||
my_off_t UNINIT_VAR(saved_log_pos);
|
||||
my_off_t UNINIT_VAR(saved_master_log_pos);
|
||||
my_off_t saved_skip= 0;
|
||||
#ifdef WITH_WSREP
|
||||
my_bool wsrep_node_dropped= FALSE;
|
||||
#endif /* WITH_WSREP */
|
||||
Relay_log_info* rli = &((Master_info*)arg)->rli;
|
||||
const char *errmsg;
|
||||
|
||||
// needs to call my_thread_init(), otherwise we get a coredump in DBUG_ stuff
|
||||
my_thread_init();
|
||||
DBUG_ENTER("handle_slave_sql");
|
||||
#ifdef WITH_WSREP
|
||||
wsrep_restart_point:
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
LINT_INIT(saved_master_log_pos);
|
||||
LINT_INIT(saved_log_pos);
|
||||
|
|
@ -3727,6 +3733,12 @@ log '%s' at position %s, relay log '%s' position: %s", RPL_LOG_NAME,
|
|||
Error running query, slave SQL thread aborted. Fix the problem, and restart \
|
||||
the slave SQL thread with \"SLAVE START\". We stopped at log \
|
||||
'%s' position %s", RPL_LOG_NAME, llstr(rli->group_master_log_pos, llbuff));
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP_ON && last_errno == ER_UNKNOWN_COM_ERROR)
|
||||
{
|
||||
wsrep_node_dropped= TRUE;
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
}
|
||||
goto err;
|
||||
}
|
||||
|
|
@ -3791,6 +3803,27 @@ err_during_init:
|
|||
THD_CHECK_SENTRY(thd);
|
||||
delete thd;
|
||||
mysql_mutex_unlock(&LOCK_thread_count);
|
||||
#ifdef WITH_WSREP
|
||||
/* if slave stopped due to node going non primary, we set global flag to
|
||||
trigger automatic restart of slave when node joins back to cluster
|
||||
*/
|
||||
if (wsrep_node_dropped && wsrep_restart_slave)
|
||||
{
|
||||
if (wsrep_ready)
|
||||
{
|
||||
WSREP_INFO("Slave error due to node temporarily non-primary"
|
||||
"SQL slave will continue");
|
||||
wsrep_node_dropped= FALSE;
|
||||
mysql_mutex_unlock(&rli->run_lock);
|
||||
goto wsrep_restart_point;
|
||||
} else {
|
||||
WSREP_INFO("Slave error due to node going non-primary");
|
||||
WSREP_INFO("wsrep_restart_slave was set and therefore slave will be "
|
||||
"automatically restarted when node joins back to cluster");
|
||||
wsrep_restart_slave_activated= TRUE;
|
||||
}
|
||||
}
|
||||
#endif /* WITH_WSREP */
|
||||
/*
|
||||
Note: the order of the broadcast and unlock calls below (first broadcast, then unlock)
|
||||
is important. Otherwise a killer_thread can execute between the calls and
|
||||
|
|
|
|||
|
|
@ -5181,6 +5181,7 @@ restart:
|
|||
thd->lex->sql_command== SQLCOM_LOAD ||
|
||||
thd->lex->sql_command== SQLCOM_DELETE) &&
|
||||
wsrep_replicate_myisam &&
|
||||
(*start) &&
|
||||
(*start)->table && (*start)->table->file->ht->db_type == DB_TYPE_MYISAM)
|
||||
{
|
||||
WSREP_TO_ISOLATION_BEGIN(NULL, NULL, (*start));
|
||||
|
|
|
|||
|
|
@ -3918,6 +3918,10 @@ static Sys_var_mybool Sys_wsrep_load_data_splitting(
|
|||
"transaction after every 10K rows inserted",
|
||||
GLOBAL_VAR(wsrep_load_data_splitting),
|
||||
CMD_LINE(OPT_ARG), DEFAULT(TRUE));
|
||||
|
||||
static Sys_var_mybool Sys_wsrep_restart_slave(
|
||||
"wsrep_restart_slave", "Should MySQL slave be restarted automatically, when node joins back to cluster",
|
||||
GLOBAL_VAR(wsrep_restart_slave), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
static Sys_var_charptr Sys_ignore_db_dirs(
|
||||
|
|
|
|||
|
|
@ -320,3 +320,59 @@ void wsrep_dump_rbr_buf(THD *thd, const void* rbr_buf, size_t buf_len)
|
|||
}
|
||||
}
|
||||
|
||||
void wsrep_dump_rbr_direct(THD* thd, IO_CACHE* cache)
|
||||
{
|
||||
char filename[PATH_MAX]= {0};
|
||||
int len= snprintf(filename, PATH_MAX, "%s/GRA_%ld_%lld.log",
|
||||
wsrep_data_home_dir, thd->thread_id,
|
||||
(long long)wsrep_thd_trx_seqno(thd));
|
||||
size_t bytes_in_cache = 0;
|
||||
// check path
|
||||
if (len >= PATH_MAX)
|
||||
{
|
||||
WSREP_ERROR("RBR dump path too long: %d, skipping dump.", len);
|
||||
return ;
|
||||
}
|
||||
// init cache
|
||||
my_off_t const saved_pos(my_b_tell(cache));
|
||||
if (reinit_io_cache(cache, READ_CACHE, 0, 0, 0))
|
||||
{
|
||||
WSREP_ERROR("failed to initialize io-cache");
|
||||
return ;
|
||||
}
|
||||
// open file
|
||||
FILE* of = fopen(filename, "wb");
|
||||
if (!of)
|
||||
{
|
||||
WSREP_ERROR("Failed to open file '%s': %d (%s)",
|
||||
filename, errno, strerror(errno));
|
||||
goto cleanup;
|
||||
}
|
||||
// ready to write
|
||||
bytes_in_cache= my_b_bytes_in_cache(cache);
|
||||
if (unlikely(bytes_in_cache == 0)) bytes_in_cache = my_b_fill(cache);
|
||||
if (likely(bytes_in_cache > 0)) do
|
||||
{
|
||||
if (my_fwrite(of, cache->read_pos, bytes_in_cache,
|
||||
MYF(MY_WME | MY_NABP)) == (size_t) -1)
|
||||
{
|
||||
WSREP_ERROR("Failed to write file '%s'", filename);
|
||||
goto cleanup;
|
||||
}
|
||||
cache->read_pos= cache->read_end;
|
||||
} while ((cache->file >= 0) && (bytes_in_cache= my_b_fill(cache)));
|
||||
if(cache->error == -1)
|
||||
{
|
||||
WSREP_ERROR("RBR inconsistent");
|
||||
goto cleanup;
|
||||
}
|
||||
cleanup:
|
||||
// init back
|
||||
if (reinit_io_cache(cache, WRITE_CACHE, saved_pos, 0, 0))
|
||||
{
|
||||
WSREP_ERROR("failed to reinitialize io-cache");
|
||||
}
|
||||
// close file
|
||||
if (of) fclose(of);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -46,4 +46,7 @@ int wsrep_write_cache (wsrep_t* wsrep,
|
|||
/* Dump replication buffer to disk */
|
||||
void wsrep_dump_rbr_buf(THD *thd, const void* rbr_buf, size_t buf_len);
|
||||
|
||||
/* Dump replication buffer to disk without intermediate buffer */
|
||||
void wsrep_dump_rbr_direct(THD* thd, IO_CACHE* cache);
|
||||
|
||||
#endif /* WSREP_BINLOG_H */
|
||||
|
|
|
|||
|
|
@ -505,11 +505,17 @@ wsrep_run_wsrep_commit(THD *thd, handlerton *hton, bool all)
|
|||
|
||||
DBUG_RETURN(WSREP_TRX_CERT_FAIL);
|
||||
|
||||
case WSREP_SIZE_EXCEEDED:
|
||||
WSREP_ERROR("transaction size exceeded");
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
DBUG_RETURN(WSREP_TRX_SIZE_EXCEEDED);
|
||||
case WSREP_CONN_FAIL:
|
||||
WSREP_ERROR("connection failure");
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
DBUG_RETURN(WSREP_TRX_ERROR);
|
||||
default:
|
||||
WSREP_ERROR("unknown connection failure");
|
||||
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
|
||||
DBUG_RETURN(WSREP_TRX_ERROR);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include "log_event.h"
|
||||
#include <slave.h>
|
||||
|
||||
Format_description_log_event *wsrep_format_desc = NULL;
|
||||
wsrep_t *wsrep = NULL;
|
||||
|
|
@ -59,7 +60,10 @@ ulong wsrep_mysql_replication_bundle = 0;
|
|||
my_bool wsrep_desync = 0; // desynchronize the node from the
|
||||
// cluster
|
||||
my_bool wsrep_load_data_splitting = 1; // commit load data every 10K intervals
|
||||
|
||||
my_bool wsrep_restart_slave = 0; // should mysql slave thread be
|
||||
// restarted, if node joins back
|
||||
my_bool wsrep_restart_slave_activated = 0; // node has dropped, and slave
|
||||
// restart will be needed
|
||||
/*
|
||||
* End configuration options
|
||||
*/
|
||||
|
|
@ -406,6 +410,25 @@ static void wsrep_synced_cb(void* app_ctx)
|
|||
// and wait for SE initialization
|
||||
wsrep_SE_init_wait();
|
||||
}
|
||||
if (wsrep_restart_slave_activated)
|
||||
{
|
||||
int rcode;
|
||||
WSREP_INFO("MySQL slave restart");
|
||||
wsrep_restart_slave_activated= FALSE;
|
||||
|
||||
mysql_mutex_lock(&LOCK_active_mi);
|
||||
if ((rcode = start_slave_threads(1 /* need mutex */,
|
||||
0 /* no wait for start*/,
|
||||
active_mi,
|
||||
master_info_file,
|
||||
relay_log_info_file,
|
||||
SLAVE_SQL)))
|
||||
{
|
||||
WSREP_WARN("Failed to create slave threads: %d", rcode);
|
||||
}
|
||||
mysql_mutex_unlock(&LOCK_active_mi);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void wsrep_init_position()
|
||||
|
|
@ -627,6 +650,7 @@ int wsrep_init()
|
|||
{
|
||||
DBUG_PRINT("wsrep",("wsrep::init() failed: %d", rcode));
|
||||
WSREP_ERROR("wsrep::init() failed: %d, must shutdown", rcode);
|
||||
wsrep->free(wsrep);
|
||||
free(wsrep);
|
||||
wsrep = NULL;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -95,6 +95,8 @@ extern my_bool wsrep_replicate_myisam;
|
|||
extern my_bool wsrep_log_conflicts;
|
||||
extern ulong wsrep_mysql_replication_bundle;
|
||||
extern my_bool wsrep_load_data_splitting;
|
||||
extern my_bool wsrep_restart_slave;
|
||||
extern my_bool wsrep_restart_slave_activated;
|
||||
|
||||
enum enum_wsrep_OSU_method { WSREP_OSU_TOI, WSREP_OSU_RSU };
|
||||
|
||||
|
|
|
|||
|
|
@ -75,15 +75,18 @@ void wsrep_notify_status (wsrep_member_status_t status,
|
|||
cmd_off += snprintf (cmd_ptr + cmd_off, cmd_len - cmd_off,
|
||||
" --index %d", view->my_idx);
|
||||
|
||||
cmd_off += snprintf (cmd_ptr + cmd_off, cmd_len - cmd_off, " --members");
|
||||
|
||||
for (int i = 0; i < view->memb_num; i++)
|
||||
if (view->memb_num)
|
||||
{
|
||||
wsrep_uuid_print (&view->members[i].id, uuid_str, sizeof(uuid_str));
|
||||
cmd_off += snprintf (cmd_ptr + cmd_off, cmd_len - cmd_off,
|
||||
"%c%s/%s/%s", i > 0 ? ',' : ' ',
|
||||
uuid_str, view->members[i].name,
|
||||
view->members[i].incoming);
|
||||
cmd_off += snprintf (cmd_ptr + cmd_off, cmd_len - cmd_off, " --members");
|
||||
|
||||
for (int i = 0; i < view->memb_num; i++)
|
||||
{
|
||||
wsrep_uuid_print (&view->members[i].id, uuid_str, sizeof(uuid_str));
|
||||
cmd_off += snprintf (cmd_ptr + cmd_off, cmd_len - cmd_off,
|
||||
"%c%s/%s/%s", i > 0 ? ',' : ' ',
|
||||
uuid_str, view->members[i].name,
|
||||
view->members[i].incoming);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -934,8 +934,9 @@ wait_signal:
|
|||
else
|
||||
{
|
||||
WSREP_ERROR("Failed to read from: %s", proc.cmd());
|
||||
proc.wait();
|
||||
}
|
||||
if (err && proc.error()) err= proc.error();
|
||||
if (!err && proc.error()) err= proc.error();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1207,6 +1207,7 @@ echo "=====" >> $STATUS_HISTORY
|
|||
%attr(755, root, root) %{_bindir}/wsrep_sst_rsync
|
||||
%attr(755, root, root) %{_bindir}/wsrep_sst_rsync_wan
|
||||
%attr(755, root, root) %{_bindir}/wsrep_sst_xtrabackup
|
||||
%attr(755, root, root) %{_bindir}/wsrep_sst_xtrabackup-v2
|
||||
%endif
|
||||
|
||||
%attr(755, root, root) %{_sbindir}/mysqld
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ do
|
|||
--members)
|
||||
MEMBERS=$2
|
||||
shift
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
|
|
|
|||
|
|
@ -137,7 +137,11 @@ typedef void (*wsrep_log_cb_t)(wsrep_log_level_t, const char *);
|
|||
typedef uint64_t wsrep_trx_id_t; //!< application transaction ID
|
||||
typedef uint64_t wsrep_conn_id_t; //!< application connection ID
|
||||
typedef int64_t wsrep_seqno_t; //!< sequence number of a writeset, etc.
|
||||
#ifdef __cplusplus
|
||||
typedef bool wsrep_bool_t;
|
||||
#else
|
||||
typedef _Bool wsrep_bool_t; //!< should be the same as standard (C99) bool
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*! undefined seqno */
|
||||
#define WSREP_SEQNO_UNDEFINED (-1)
|
||||
|
|
|
|||
|
|
@ -388,4 +388,3 @@ int wsrep_dummy_loader(wsrep_t* w)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue