diff options
author | Nirbhay Choubey <nirbhay@skysql.com> | 2014-03-25 17:01:05 -0400 |
---|---|---|
committer | Nirbhay Choubey <nirbhay@skysql.com> | 2014-03-25 17:01:05 -0400 |
commit | 899f9801d4466a6ecccd32a34a38aaf19019e39a (patch) | |
tree | 67d0be09c93257a3eb9f687af2ffeca172a05bec /scripts/wsrep_sst_xtrabackup.sh | |
parent | 3088d52c20eca10e5b8689648edef8f7fd49830a (diff) | |
download | mariadb-git-899f9801d4466a6ecccd32a34a38aaf19019e39a.tar.gz |
bzr merge -r3946..3968 codership/5.5
Diffstat (limited to 'scripts/wsrep_sst_xtrabackup.sh')
-rw-r--r-- | scripts/wsrep_sst_xtrabackup.sh | 579 |
1 files changed, 416 insertions, 163 deletions
diff --git a/scripts/wsrep_sst_xtrabackup.sh b/scripts/wsrep_sst_xtrabackup.sh index 3eb747f50c3..3948b15c53b 100644 --- a/scripts/wsrep_sst_xtrabackup.sh +++ b/scripts/wsrep_sst_xtrabackup.sh @@ -34,6 +34,9 @@ # 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 +47,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 + if [[ $encrypt -eq 2 ]];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: Encryption cannot be enabled with tar format" + wsrep_log_info "NOTE: Xtrabackup-based encryption - encrypt=1 - cannot be enabled with tar format" + encrypt=0 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) + 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 +140,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}" - else - wsrep_log_error "Invalid role: $WSREP_SST_OPT_ROLE" - exit 22 + strmcmd="tar xfi - --recursive-unlink -h" + else + strmcmd="tar cf - \${INFO_FILE} \${IST_FILE}" fi fi @@ -118,6 +307,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 +320,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 +343,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 - -for TOOL_BIN in INNOBACKUPEX_BIN NC_BIN ; do - if ! which ${!TOOL_BIN} > /dev/null 2>&1 - then - echo "Can't find ${!TOOL_BIN} in the path" - exit 22 # EINVAL - fi -done - -#ROLE=$1 -#ADDR=$2 -readonly AUTH=(${WSREP_SST_OPT_AUTH//:/ }) -readonly DATA="${WSREP_SST_OPT_DATA}" -#CONF=$5 +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 +} -INFO_FILE="xtrabackup_galera_info" -IST_FILE="xtrabackup_ist" +if [[ ! -x `which innobackupex` ]];then + wsrep_log_error "innobackupex not in path: $PATH" + exit 2 +fi -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 - set +e - ${INNOBACKUPEX_BIN} ${INNOBACKUPEX_ARGS} ${TMPDIR} \ - 2> ${DATA}/innobackup.backup.log | \ - ${NC_BIN} ${REMOTEIP} ${NC_PORT} + check_extra - RC=( "${PIPESTATUS[@]}" ) + 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 + 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 +505,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 +516,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 +529,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 @@ -372,43 +619,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 @@ -416,33 +645,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 @@ -455,10 +698,21 @@ then 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 [[ $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" @@ -468,14 +722,13 @@ then wsrep_log_info "${IST_FILE} received from donor: Running IST" fi - cat "${MAGIC_FILE}" # output UUID:seqno - - #Cleanup not required here since EXIT trap should be called - #wsrep_cleanup_progress_file + if [[ ! -r ${MAGIC_FILE} ]];then + wsrep_log_error "SST magic file ${MAGIC_FILE} not found/readable" + exit 2 + fi -else - wsrep_log_error "Unrecognized role: ${WSREP_SST_OPT_ROLE}" - exit 22 # EINVAL + cat "${MAGIC_FILE}" # output UUID:seqno + wsrep_log_info "Total time on joiner: $totime seconds" fi exit 0 |