From e0324bf300a57e84e5fdeca995c91b9efa3dc62c Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Thu, 15 Apr 2021 13:53:28 +0200 Subject: wsrep sst scripts: removing extra blank lines and spaces Removed numerous extra blank lines and spaces that interfere with reading and understanding program code, making it more difficult to find errors in scripts. I also removed all extra trailing spaces at the ends of lines, which lead to marking extra lines as changes (in subsequent changes). The amount of indentation in some parts of the code has also been normalized. --- scripts/wsrep_sst_common.sh | 10 +- scripts/wsrep_sst_mariabackup.sh | 248 +++++++++++++++++-------------------- scripts/wsrep_sst_mysqldump.sh | 32 ++--- scripts/wsrep_sst_rsync.sh | 55 ++++---- scripts/wsrep_sst_xtrabackup-v2.sh | 214 ++++++++++++++------------------ scripts/wsrep_sst_xtrabackup.sh | 147 +++++++++++----------- 6 files changed, 329 insertions(+), 377 deletions(-) diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index 443cb26ab64..51f811bda78 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -194,9 +194,9 @@ case "$1" in shift ;; '--binlog-index') - WSREP_SST_OPT_BINLOG_INDEX="$2" - shift - ;; + WSREP_SST_OPT_BINLOG_INDEX="$2" + shift + ;; '--gtid-domain-id') readonly WSREP_SST_OPT_GTID_DOMAIN_ID="$2" shift @@ -298,11 +298,11 @@ fi wsrep_defaults="$WSREP_SST_OPT_DEFAULT" if [ -n "$wsrep_defaults" ]; then - wsrep_defaults="$wsrep_defaults " + wsrep_defaults="$wsrep_defaults " fi wsrep_defaults="$wsrep_defaults$WSREP_SST_OPT_EXTRA_DEFAULT" if [ -n "$wsrep_defaults" ]; then - wsrep_defaults="$wsrep_defaults " + wsrep_defaults="$wsrep_defaults " fi readonly WSREP_SST_OPT_CONF="$wsrep_defaults$WSREP_SST_OPT_SUFFIX_DEFAULT" readonly MY_PRINT_DEFAULTS="$MY_PRINT_DEFAULTS $WSREP_SST_OPT_CONF" diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index 29c527d8ff3..c9a990a661d 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -87,8 +87,8 @@ set +e INNOBACKUPEX_BIN=$(which mariabackup) if test -z $INNOBACKUPEX_BIN then - wsrep_log_error 'mariabackup binary not found in $PATH' - exit 42 + wsrep_log_error 'mariabackup binary not found in $PATH' + exit 42 fi set -e XBSTREAM_BIN=mbstream @@ -111,7 +111,7 @@ timeit(){ local cmd="$@" local x1 x2 took extcode - if [[ $ttime -eq 1 ]];then + if [[ $ttime -eq 1 ]];then x1=$(date +%s) wsrep_log_info "Evaluating $cmd" eval "$cmd" @@ -120,7 +120,7 @@ timeit(){ took=$(( x2-x1 )) wsrep_log_info "NOTE: $stage took $took seconds" totime=$(( totime+took )) - else + else wsrep_log_info "Evaluating $cmd" eval "$cmd" extcode=$? @@ -131,11 +131,11 @@ timeit(){ get_keys() { # $encrypt -eq 1 is for internal purposes only - if [[ $encrypt -ge 2 || $encrypt -eq -1 ]];then - return + if [[ $encrypt -ge 2 || $encrypt -eq -1 ]];then + return fi - if [[ $encrypt -eq 0 ]];then + if [[ $encrypt -eq 0 ]];then if $MY_PRINT_DEFAULTS 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 @@ -175,18 +175,18 @@ get_keys() get_transfer() { - if [[ -z $SST_PORT ]];then + if [[ -z $SST_PORT ]];then TSST_PORT=4444 - else + else TSST_PORT=$SST_PORT fi if [[ $tfmt == 'nc' ]];then - wsrep_check_programs nc - + wsrep_check_programs nc wsrep_log_info "Using netcat as streamer" + if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then - if nc -h 2>&1 | grep -q ncat;then + if nc -h 2>&1 | grep -q ncat;then # Ncat tcmd="nc -l ${TSST_PORT}" elif nc -h 2>&1 | grep -qw -- '-d\>';then @@ -215,9 +215,8 @@ get_transfer() tcmd_extra="" if nc -h 2>&1 | grep -qw -- -N; then tcmd_extra+="-N" - wsrep_log_info "Using nc -N" + wsrep_log_info "Using nc -N" fi - # netcat doesn't understand [] around IPv6 address if nc -h 2>&1 | grep -q ncat;then # Ncat @@ -235,7 +234,7 @@ get_transfer() fi else tfmt='socat' - wsrep_check_programs socat + wsrep_check_programs socat wsrep_log_info "Using socat as streamer" if [[ $encrypt -eq 2 || $encrypt -eq 3 ]] && ! socat -V | grep -q "WITH_OPENSSL 1";then @@ -243,9 +242,9 @@ get_transfer() exit 2 fi - if [[ $encrypt -eq 2 ]];then + if [[ $encrypt -eq 2 ]];then wsrep_log_info "Using openssl based encryption with socat: with crt and pem" - if [[ -z $tpem || -z $tcert ]];then + if [[ -z $tpem || -z $tcert ]];then wsrep_log_error "Both PEM and CRT files required" exit 22 fi @@ -281,8 +280,7 @@ get_transfer() tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${tpem},key=${tkey},cafile=${tcert}${sockopt}" fi fi - - else + else if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then tcmd="socat -u TCP-LISTEN:${TSST_PORT},reuseaddr${sockopt} stdio" else @@ -290,7 +288,6 @@ get_transfer() fi fi fi - } parse_cnf() @@ -302,7 +299,7 @@ parse_cnf() # then grep for needed variable # finally get the variable value (if variables has been specified multiple time use the last value only) reval=$($MY_PRINT_DEFAULTS $group | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2- | tail -1) - if [[ -z $reval ]];then + if [[ -z $reval ]];then [[ -n $3 ]] && reval=$3 fi echo $reval @@ -312,7 +309,7 @@ get_footprint() { pushd $WSREP_SST_OPT_DATA 1>/dev/null payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c | awk 'END { print $1 }') - if $MY_PRINT_DEFAULTS xtrabackup | grep -q -- "--compress";then + if $MY_PRINT_DEFAULTS 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 )) @@ -324,7 +321,6 @@ get_footprint() adjust_progress() { - if ! command -v pv >/dev/null;then wsrep_log_error "pv not found in path: $PATH" wsrep_log_error "Disabling all progress/rate-limiting" @@ -334,16 +330,16 @@ adjust_progress() return fi - if [[ -n $progress && $progress != '1' ]];then - if [[ -e $progress ]];then + if [[ -n $progress && $progress != '1' ]];then + if [[ -e $progress ]];then pcmd+=" 2>>$progress" - else + else pcmd+=" 2>$progress" fi - elif [[ -z $progress && -n $rlimit ]];then + elif [[ -z $progress && -n $rlimit ]];then # When rlimit is non-zero pcmd="pv -q" - fi + fi if [[ -n $rlimit && "$WSREP_SST_OPT_ROLE" == "donor" ]];then wsrep_log_info "Rate-limiting SST to $rlimit" @@ -371,7 +367,7 @@ read_cnf() scomp=$(parse_cnf sst compressor "") sdecomp=$(parse_cnf sst decompressor "") - # Refer to http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html + # 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 "") @@ -391,13 +387,13 @@ read_cnf() sstlogarchive=$(parse_cnf sst sst-log-archive 1) sstlogarchivedir=$(parse_cnf sst sst-log-archive-dir "/tmp/sst_log_archive") - if [[ $speciald -eq 0 ]];then + if [[ $speciald -eq 0 ]];then wsrep_log_error "sst-special-dirs equal to 0 is not supported, falling back to 1" speciald=1 - fi + fi - if [[ $ssyslog -ne -1 ]];then - if $MY_PRINT_DEFAULTS mysqld_safe | tr '_' '-' | grep -q -- "--syslog";then + if [[ $ssyslog -ne -1 ]];then + if $MY_PRINT_DEFAULTS mysqld_safe | tr '_' '-' | grep -q -- "--syslog";then ssyslog=1 fi fi @@ -426,7 +422,6 @@ get_stream() else strmcmd="tar cf - \${INFO_FILE} " fi - fi } @@ -448,33 +443,32 @@ cleanup_joiner() { # Since this is invoked just after exit NNN local estatus=$? - if [[ $estatus -ne 0 ]];then + if [[ $estatus -ne 0 ]];then wsrep_log_error "Cleanup after exit with status:$estatus" elif [ "${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 + if [[ -n $progress && -p $progress ]];then wsrep_log_info "Cleaning up fifo file $progress" rm $progress fi - if [[ -n ${STATDIR:-} ]];then + + if [[ -n ${STATDIR:-} ]];then [[ -d $STATDIR ]] && rm -rf $STATDIR fi - # Final cleanup + # Final cleanup pgid=$(ps -o pgid= $$ | grep -o '[0-9]*') # This means no setsid done in mysqld. # We don't want to kill mysqld here otherwise. if [[ $$ -eq $pgid ]];then - # This means a signal was delivered to the process. - # So, more cleanup. - if [[ $estatus -ge 128 ]];then + # So, more cleanup. + if [[ $estatus -ge 128 ]];then kill -KILL -$$ || true fi - fi exit $estatus @@ -490,52 +484,49 @@ cleanup_donor() { # Since this is invoked just after exit NNN local estatus=$? - if [[ $estatus -ne 0 ]];then + if [[ $estatus -ne 0 ]];then wsrep_log_error "Cleanup after exit with status:$estatus" fi - if [[ -n ${XTRABACKUP_PID:-} ]];then + if [[ -n ${XTRABACKUP_PID:-} ]];then if check_pid $XTRABACKUP_PID then wsrep_log_error "xtrabackup process is still running. Killing..." kill_xtrabackup fi - fi + rm -f ${DATA}/${IST_FILE} || true - if [[ -n $progress && -p $progress ]];then + if [[ -n $progress && -p $progress ]];then wsrep_log_info "Cleaning up fifo file $progress" rm -f $progress || true fi wsrep_log_info "Cleaning up temporary directories" - if [[ -n $xtmpdir ]];then + if [[ -n $xtmpdir ]];then [[ -d $xtmpdir ]] && rm -rf $xtmpdir || true fi - if [[ -n $itmpdir ]];then + if [[ -n $itmpdir ]];then [[ -d $itmpdir ]] && rm -rf $itmpdir || true fi - # Final cleanup + # Final cleanup pgid=$(ps -o pgid= $$ | grep -o '[0-9]*') # This means no setsid done in mysqld. # We don't want to kill mysqld here otherwise. if [[ $$ -eq $pgid ]];then - # This means a signal was delivered to the process. - # So, more cleanup. - if [[ $estatus -ge 128 ]];then + # So, more cleanup. + if [[ $estatus -ge 128 ]];then kill -KILL -$$ || true fi - fi exit $estatus - } kill_xtrabackup() @@ -565,7 +556,7 @@ wait_for_listen() local MODULE=$3 for i in {1..50} do - if [ "$OS" = "FreeBSD" ];then + if [ "$OS" = "FreeBSD" ];then sockstat -46lp $PORT | grep -qE "^[^ ]* *(socat|nc) *[^ ]* *[^ ]* *[^ ]* *[^ ]*:$PORT" && break else ss -p state listening "( sport = :$PORT )" | grep -qE 'socat|nc' && break @@ -578,20 +569,20 @@ wait_for_listen() check_extra() { local use_socket=1 - if [[ $uextra -eq 1 ]];then - if $MY_PRINT_DEFAULTS --mysqld | tr '_' '-' | grep -- "--thread-handling=" | grep -q 'pool-of-threads';then + if [[ $uextra -eq 1 ]];then + if $MY_PRINT_DEFAULTS --mysqld | tr '_' '-' | grep -- "--thread-handling=" | grep -q 'pool-of-threads';then local eport=$($MY_PRINT_DEFAULTS --mysqld | tr '_' '-' | grep -- "--extra-port=" | cut -d= -f2) - if [[ -n $eport ]];then + if [[ -n $eport ]];then # Xtrabackup works only locally. - # Hence, setting host to 127.0.0.1 unconditionally. + # 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 + else wsrep_log_error "Extra port $eport null, failing" exit 1 fi - else + else wsrep_log_info "Thread pool not set, ignore the option use_extra" fi fi @@ -603,7 +594,7 @@ check_extra() recv_joiner() { local dir=$1 - local msg=$2 + local msg=$2 local tmt=$3 local checkf=$4 local ltcmd @@ -617,27 +608,27 @@ recv_joiner() set +e if [[ $tmt -gt 0 ]] && command -v timeout >/dev/null;then - if timeout --help | grep -q -- '-k';then + if timeout --help | grep -q -- '-k';then ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd" - else + else ltcmd="timeout -s9 $tmt $tcmd" fi timeit "$msg" "$ltcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )" - else + else timeit "$msg" "$tcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )" fi set -e - popd 1>/dev/null + popd 1>/dev/null - if [[ ${RC[0]} -eq 124 ]];then + if [[ ${RC[0]} -eq 124 ]];then wsrep_log_error "Possible timeout in receiving first data from " - "donor in gtid stage: exit codes: ${RC[@]}" + "donor in gtid stage: exit codes: ${RC[@]}" exit 32 fi - for ecode in "${RC[@]}";do - if [[ $ecode -ne 0 ]];then + 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 @@ -647,33 +638,30 @@ recv_joiner() if [[ $checkf -eq 1 && ! -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 "Contents of datadir" wsrep_log_info "$(ls -l ${dir}/*)" exit 32 fi } - send_donor() { local dir=$1 - local msg=$2 + local msg=$2 pushd ${dir} 1>/dev/null set +e timeit "$msg" "$strmcmd | $tcmd; RC=( "\${PIPESTATUS[@]}" )" set -e - popd 1>/dev/null - + popd 1>/dev/null - for ecode in "${RC[@]}";do - if [[ $ecode -ne 0 ]];then + 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 - } monitor_process() @@ -681,18 +669,14 @@ monitor_process() local sst_stream_pid=$1 while true ; do - if ! ps -p "${WSREP_SST_OPT_PARENT}" &>/dev/null; then - wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly." + wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly." exit 32 fi - if ! ps -p "${sst_stream_pid}" &>/dev/null; then break fi - sleep 0.1 - done } @@ -700,7 +684,7 @@ wsrep_check_programs "$INNOBACKUPEX_BIN" rm -f "${MAGIC_FILE}" -if [[ ! ${WSREP_SST_OPT_ROLE} == 'joiner' && ! ${WSREP_SST_OPT_ROLE} == 'donor' ]];then +if [[ ! ${WSREP_SST_OPT_ROLE} == 'joiner' && ! ${WSREP_SST_OPT_ROLE} == 'donor' ]];then wsrep_log_error "Invalid role ${WSREP_SST_OPT_ROLE}" exit 22 fi @@ -708,13 +692,13 @@ fi read_cnf setup_ports -if ${INNOBACKUPEX_BIN} /tmp --help 2>/dev/null | grep -q -- '--version-check'; then +if ${INNOBACKUPEX_BIN} /tmp --help 2>/dev/null | grep -q -- '--version-check'; then disver="--no-version-check" fi iopts+=" --databases-exclude=\"lost+found\"" -if [[ ${FORCE_FTWRL:-0} -eq 1 ]];then +if [[ ${FORCE_FTWRL:-0} -eq 1 ]];then wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL" iopts+=" --no-backup-locks" fi @@ -746,24 +730,23 @@ else INNODB_DATA_HOME_DIR=$(cd $DATA; pwd -P) fi -if [[ $ssyslog -eq 1 ]];then +if [[ $ssyslog -eq 1 ]];then if ! command -v logger >/dev/null;then wsrep_log_error "logger not in path: $PATH. Ignoring" else - wsrep_log_info "Logging all stderr of SST/Innobackupex to syslog" exec 2> >(logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE) wsrep_log_error() { - logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" + logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" } wsrep_log_info() { - logger -p daemon.info -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" + logger -p daemon.info -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" } INNOAPPLY="${INNOBACKUPEX_BIN} --prepare $disver $iapts \$INNOEXTRA $rebuildcmd --target-dir=\${DATA} 2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply" @@ -794,7 +777,6 @@ then else newfile=${INNOAPPLYLOG}.${ARCHIVETIMESTAMP} fi - wsrep_log_info "Moving ${INNOAPPLYLOG} to ${newfile}" mv "${INNOAPPLYLOG}" "${newfile}" gzip "${newfile}" @@ -827,12 +809,12 @@ then mv "${INNOBACKUPLOG}" "${newfile}" gzip "${newfile}" fi - fi - + INNOAPPLY="${INNOBACKUPEX_BIN} --prepare $disver $iapts \$INNOEXTRA $rebuildcmd --target-dir=\${DATA} &> ${INNOAPPLYLOG}" INNOMOVE="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} --move-back $disver $impts --force-non-empty-directories --target-dir=\${DATA} &> ${INNOMOVELOG}" INNOBACKUP="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} --backup $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt --target-dir=\$itmpdir 2> ${INNOBACKUPLOG}" + fi get_stream @@ -845,7 +827,7 @@ then if [ $WSREP_SST_OPT_BYPASS -eq 0 ] then usrst=0 - if [[ -z $sst_ver ]];then + if [[ -z $sst_ver ]];then wsrep_log_error "Upgrade joiner to 5.6.21 or higher for backup locks support" wsrep_log_error "The joiner is not supported for this version of donor" exit 93 @@ -878,7 +860,7 @@ then if [[ $encrypt -eq 1 ]];then if [[ -n $ekey ]];then INNOEXTRA+=" --encrypt=$ealgo --encrypt-key=$ekey" - else + else INNOEXTRA+=" --encrypt=$ealgo --encrypt-key-file=$ekeyfile" fi fi @@ -894,22 +876,22 @@ then ttcmd="$tcmd" if [[ $encrypt -eq 1 ]];then - if [[ -n $scomp ]];then + if [[ -n $scomp ]];then tcmd=" $ecmd | $scomp | $tcmd " - else + else tcmd=" $ecmd | $tcmd " fi - elif [[ -n $scomp ]];then + elif [[ -n $scomp ]];then tcmd=" $scomp | $tcmd " fi send_donor $DATA "${stagemsg}-gtid" tcmd="$ttcmd" - if [[ -n $progress ]];then + if [[ -n $progress ]];then get_footprint tcmd="$pcmd | $tcmd" - elif [[ -n $rlimit ]];then + elif [[ -n $rlimit ]];then adjust_progress tcmd="$pcmd | $tcmd" fi @@ -919,7 +901,7 @@ then wsrep_log_info "Streaming the backup to joiner at ${REMOTEIP} ${SST_PORT:-4444}" - if [[ -n $scomp ]];then + if [[ -n $scomp ]];then tcmd="$scomp | $tcmd" fi @@ -931,7 +913,7 @@ then wsrep_log_error "${INNOBACKUPEX_BIN} finished with error: ${RC[0]}. " \ "Check syslog or ${INNOBACKUPLOG} for details" exit 22 - elif [[ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]];then + elif [[ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]];then wsrep_log_error "$tcmd finished with error: ${RC[1]}" exit 22 fi @@ -939,7 +921,6 @@ then # innobackupex implicitly writes PID to fixed location in $xtmpdir XTRABACKUP_PID="$xtmpdir/xtrabackup_pid" - else # BYPASS FOR IST wsrep_log_info "Bypassing the SST for IST" @@ -951,12 +932,12 @@ then echo "1" > "${DATA}/${IST_FILE}" get_keys if [[ $encrypt -eq 1 ]];then - if [[ -n $scomp ]];then + if [[ -n $scomp ]];then tcmd=" $ecmd | $scomp | $tcmd " else tcmd=" $ecmd | $tcmd " fi - elif [[ -n $scomp ]];then + elif [[ -n $scomp ]];then tcmd=" $scomp | $tcmd " fi strmcmd+=" \${IST_FILE}" @@ -1003,7 +984,6 @@ then stagemsg="Joiner-Recv" - sencrypted=1 nthreads=1 @@ -1030,30 +1010,29 @@ then trap sig_joiner_cleanup HUP PIPE INT TERM trap cleanup_joiner EXIT - if [[ -n $progress ]];then + if [[ -n $progress ]];then adjust_progress tcmd+=" | $pcmd" fi get_keys if [[ $encrypt -eq 1 && $sencrypted -eq 1 ]];then - if [[ -n $sdecomp ]];then + if [[ -n $sdecomp ]];then strmcmd=" $sdecomp | $ecmd | $strmcmd" - else + else strmcmd=" $ecmd | $strmcmd" fi - elif [[ -n $sdecomp ]];then + elif [[ -n $sdecomp ]];then strmcmd=" $sdecomp | $strmcmd" fi STATDIR=$(mktemp -d) MAGIC_FILE="${STATDIR}/${INFO_FILE}" - recv_joiner $STATDIR "${stagemsg}-gtid" $stimeout 1 - + recv_joiner $STATDIR "${stagemsg}-gtid" $stimeout 1 if ! ps -p ${WSREP_SST_OPT_PARENT} &>/dev/null then - wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly." + wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly." exit 32 fi @@ -1070,11 +1049,11 @@ then wsrep_log_info "Proceeding with SST" wsrep_log_info "Cleaning the existing datadir and innodb-data/log directories" - if [ "${OS}" = "FreeBSD" ]; then + if [ "${OS}" = "FreeBSD" ]; then find -E $ib_home_dir $ib_log_dir $ib_undo_dir $DATA -mindepth 1 -prune -regex $cpat -o -exec rm -rfv {} 1>&2 \+ else find $ib_home_dir $ib_log_dir $ib_undo_dir $DATA -mindepth 1 -prune -regex $cpat -o -exec rm -rfv {} 1>&2 \+ - fi + fi tempdir=$LOG_BIN_ARG if [ -z "$tempdir" ]; then @@ -1094,30 +1073,27 @@ then fi fi - - TDATA=${DATA} DATA="${DATA}/.sst" - MAGIC_FILE="${DATA}/${INFO_FILE}" wsrep_log_info "Waiting for SST streaming to complete!" monitor_process $jpid get_proc - if [[ ! -s ${DATA}/xtrabackup_checkpoints ]];then + if [[ ! -s ${DATA}/xtrabackup_checkpoints ]];then wsrep_log_error "xtrabackup_checkpoints missing, failed innobackupex/SST on donor" exit 2 fi # Rebuild indexes for compact backups - if grep -q 'compact = 1' ${DATA}/xtrabackup_checkpoints;then + if grep -q 'compact = 1' ${DATA}/xtrabackup_checkpoints;then wsrep_log_info "Index compaction detected" rebuild=1 fi - if [[ $rebuild -eq 1 ]];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" @@ -1127,7 +1103,7 @@ then wsrep_log_info "Compressed qpress files found" - if ! command -v qpress >/dev/null;then + if ! command -v qpress >/dev/null;then wsrep_log_error "qpress not found in path: $PATH" exit 22 fi @@ -1135,28 +1111,27 @@ then 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 + 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 + else pvopts="-f -s $count -l -N Decompression" fi pcmd="pv $pvopts" adjust_progress dcmd="$pcmd | xargs -n 2 qpress -T${nproc}d" - else + else dcmd="xargs -n 2 qpress -T${nproc}d" fi - - # Decompress the qpress files + # 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 + 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 @@ -1165,13 +1140,12 @@ then fi fi - if [[ ! -z $WSREP_SST_OPT_BINLOG ]];then BINLOG_DIRNAME=$(dirname $WSREP_SST_OPT_BINLOG) BINLOG_FILENAME=$(basename $WSREP_SST_OPT_BINLOG) - # To avoid comparing data directory and BINLOG_DIRNAME + # To avoid comparing data directory and BINLOG_DIRNAME mv $DATA/${BINLOG_FILENAME}.* $BINLOG_DIRNAME/ 2>/dev/null || true pushd $BINLOG_DIRNAME &>/dev/null @@ -1187,7 +1161,7 @@ then if [ $? -ne 0 ]; then - wsrep_log_error "${INNOBACKUPEX_BIN} apply finished with errors. Check syslog or ${INNOAPPLYLOG} for details" + wsrep_log_error "${INNOBACKUPEX_BIN} apply finished with errors. Check syslog or ${INNOAPPLYLOG} for details" exit 22 fi @@ -1196,27 +1170,29 @@ then set -e wsrep_log_info "Moving the backup to ${TDATA}" timeit "Xtrabackup move stage" "$INNOMOVE" - if [[ $? -eq 0 ]];then + if [[ $? -eq 0 ]];then wsrep_log_info "Move successful, removing ${DATA}" rm -rf $DATA DATA=${TDATA} - else + else wsrep_log_error "Move failed, keeping ${DATA} for further diagnosis" wsrep_log_error "Check syslog or ${INNOMOVELOG} for details" exit 22 fi + else - else wsrep_log_info "${IST_FILE} received from donor: Running IST" + fi - if [[ ! -r ${MAGIC_FILE} ]];then + if [[ ! -r ${MAGIC_FILE} ]];then wsrep_log_error "SST magic file ${MAGIC_FILE} not found/readable" exit 2 fi wsrep_log_info "Galera co-ords from recovery: $(cat ${MAGIC_FILE})" cat "${MAGIC_FILE}" # Output : UUID:seqno wsrep_gtid_domain_id + wsrep_log_info "Total time on joiner: $totime seconds" fi diff --git a/scripts/wsrep_sst_mysqldump.sh b/scripts/wsrep_sst_mysqldump.sh index 664fd2c04f9..19fca2df024 100644 --- a/scripts/wsrep_sst_mysqldump.sh +++ b/scripts/wsrep_sst_mysqldump.sh @@ -100,12 +100,12 @@ SET_START_POSITION="SET GLOBAL wsrep_start_position='$WSREP_SST_OPT_GTID';" SET_WSREP_GTID_DOMAIN_ID="" if [ -n $WSREP_SST_OPT_GTID_DOMAIN_ID ] then - SET_WSREP_GTID_DOMAIN_ID=" - SET @val = (SELECT GLOBAL_VALUE FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE VARIABLE_NAME = 'WSREP_GTID_STRICT_MODE' AND GLOBAL_VALUE > 0); - SET @stmt = IF (@val IS NOT NULL, 'SET GLOBAL WSREP_GTID_DOMAIN_ID=$WSREP_SST_OPT_GTID_DOMAIN_ID', 'SET @dummy = 0'); - PREPARE stmt FROM @stmt; - EXECUTE stmt; - DROP PREPARE stmt;" + SET_WSREP_GTID_DOMAIN_ID=" + SET @val = (SELECT GLOBAL_VALUE FROM INFORMATION_SCHEMA.SYSTEM_VARIABLES WHERE VARIABLE_NAME = 'WSREP_GTID_STRICT_MODE' AND GLOBAL_VALUE > 0); + SET @stmt = IF (@val IS NOT NULL, 'SET GLOBAL WSREP_GTID_DOMAIN_ID=$WSREP_SST_OPT_GTID_DOMAIN_ID', 'SET @dummy = 0'); + PREPARE stmt FROM @stmt; + EXECUTE stmt; + DROP PREPARE stmt;" fi MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF "\ @@ -132,16 +132,16 @@ SQL_LOG_BIN_OFF="" # Safety check if [ "${SERVER_VERSION%%.*}" != '5' ] then - # If binary logging is enabled on the joiner node, we need to copy donor's - # gtid_binlog_state to joiner. In order to do that, a RESET MASTER must be - # executed to erase binary logs (if any). Binary logging should also be - # turned off for the session so that gtid state does not get altered while - # the dump gets replayed on joiner. - if [[ "$LOG_BIN" == 'ON' ]]; then - RESET_MASTER="RESET MASTER;" - SET_GTID_BINLOG_STATE="SET @@global.gtid_binlog_state='$GTID_BINLOG_STATE';" - SQL_LOG_BIN_OFF="SET @@session.sql_log_bin=OFF;" - fi + # If binary logging is enabled on the joiner node, we need to copy donor's + # gtid_binlog_state to joiner. In order to do that, a RESET MASTER must be + # executed to erase binary logs (if any). Binary logging should also be + # turned off for the session so that gtid state does not get altered while + # the dump gets replayed on joiner. + if [[ "$LOG_BIN" == 'ON' ]]; then + RESET_MASTER="RESET MASTER;" + SET_GTID_BINLOG_STATE="SET @@global.gtid_binlog_state='$GTID_BINLOG_STATE';" + SQL_LOG_BIN_OFF="SET @@session.sql_log_bin=OFF;" + fi fi # NOTE: we don't use --routines here because we're dumping mysql.proc table diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index 7e3f7b73301..ec64a6b5d8f 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -74,8 +74,8 @@ check_pid_and_port() ;; *) if ! which lsof > /dev/null; then - wsrep_log_error "lsof tool not found in PATH! Make sure you have it installed." - exit 2 # ENOENT + wsrep_log_error "lsof tool not found in PATH! Make sure you have it installed." + exit 2 # ENOENT fi local port_info="$(lsof -i :$rsync_port -Pn 2>/dev/null | \ @@ -107,15 +107,15 @@ is_local_ip() local get_addr_bin=`which ifconfig` if [ -z "$get_addr_bin" ] then - get_addr_bin=`which ip` - get_addr_bin="$get_addr_bin address show" - # Add an slash at the end, so we don't get false positive : 172.18.0.4 matches 172.18.0.41 - # ip output format is "X.X.X.X/mask" - address="${address}/" + get_addr_bin=`which ip` + get_addr_bin="$get_addr_bin address show" + # Add an slash at the end, so we don't get false positive : 172.18.0.4 matches 172.18.0.41 + # ip output format is "X.X.X.X/mask" + address="${address}/" else - # Add an space at the end, so we don't get false positive : 172.18.0.4 matches 172.18.0.41 - # ifconfig output format is "X.X.X.X " - address="$address " + # Add an space at the end, so we don't get false positive : 172.18.0.4 matches 172.18.0.41 + # ifconfig output format is "X.X.X.X " + address="$address " fi $get_addr_bin | grep -F "$address" > /dev/null @@ -373,11 +373,13 @@ EOF fi else # BYPASS + wsrep_log_info "Bypassing state dump." # Store donor's wsrep GTID (state ID) and wsrep_gtid_domain_id # (separated by a space). STATE="$WSREP_SST_OPT_GTID $WSREP_SST_OPT_GTID_DOMAIN_ID" + fi echo "continue" # now server can resume updating data @@ -461,22 +463,22 @@ EOF # If the IP is local listen only in it if is_local_ip "$RSYNC_ADDR" then - RSYNC_EXTRA_ARGS="--address $RSYNC_ADDR" - STUNNEL_ACCEPT="$RSYNC_ADDR:$RSYNC_PORT" + RSYNC_EXTRA_ARGS="--address $RSYNC_ADDR" + STUNNEL_ACCEPT="$RSYNC_ADDR:$RSYNC_PORT" else - # Not local, possibly a NAT, listen on all interfaces - RSYNC_EXTRA_ARGS="" - STUNNEL_ACCEPT="$RSYNC_PORT" - # Overwrite address with all - RSYNC_ADDR="*" + # Not local, possibly a NAT, listen on all interfaces + RSYNC_EXTRA_ARGS="" + STUNNEL_ACCEPT="$RSYNC_PORT" + # Overwrite address with all + RSYNC_ADDR="*" fi if [ -z "$STUNNEL" ] then - rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" ${RSYNC_EXTRA_ARGS} & - RSYNC_REAL_PID=$! + rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" ${RSYNC_EXTRA_ARGS} & + RSYNC_REAL_PID=$! else - cat << EOF > "$STUNNEL_CONF" + cat << EOF > "$STUNNEL_CONF" key = $SSTKEY cert = $SSTCERT foreground = yes @@ -488,9 +490,9 @@ accept = $STUNNEL_ACCEPT exec = $(which rsync) execargs = rsync --server --daemon --config=$RSYNC_CONF . EOF - stunnel "$STUNNEL_CONF" & - RSYNC_REAL_PID=$! - RSYNC_PID=$STUNNEL_PID + stunnel "$STUNNEL_CONF" & + RSYNC_REAL_PID=$! + RSYNC_PID=$STUNNEL_PID fi until check_pid_and_port "$RSYNC_PID" "$RSYNC_REAL_PID" "$RSYNC_ADDR" "$RSYNC_PORT" @@ -518,7 +520,6 @@ EOF if ! [ -z $WSREP_SST_OPT_BINLOG ] then - OLD_PWD="$(pwd)" cd $BINLOG_DIRNAME @@ -532,14 +533,15 @@ EOF do if ! [ -z $WSREP_SST_OPT_BINLOG_INDEX ] echo ${BINLOG_DIRNAME}/${ii} >> ${BINLOG_FILENAME}.index - then + then echo ${BINLOG_DIRNAME}/${ii} >> ${BINLOG_INDEX_DIRNAME}/${BINLOG_INDEX_FILENAME}.index fi done fi - cd "$OLD_PWD" + cd "$OLD_PWD" fi + if [ -r "$MAGIC_FILE" ] then # UUID:seqno & wsrep_gtid_domain_id is received here. @@ -548,6 +550,7 @@ EOF # this message should cause joiner to abort echo "rsync process ended without creating '$MAGIC_FILE'" fi + wsrep_cleanup_progress_file # cleanup_joiner else diff --git a/scripts/wsrep_sst_xtrabackup-v2.sh b/scripts/wsrep_sst_xtrabackup-v2.sh index 8c8af9a0219..7c3859237e0 100644 --- a/scripts/wsrep_sst_xtrabackup-v2.sh +++ b/scripts/wsrep_sst_xtrabackup-v2.sh @@ -15,12 +15,9 @@ # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston # MA 02110-1335 USA. -# Documentation: http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html +# 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="" @@ -73,7 +70,7 @@ ssl_cert="" ssl_ca="" ssl_key="" -if which pv &>/dev/null && pv --help | grep -q FORMAT;then +if which pv &>/dev/null && pv --help | grep -q FORMAT;then pvopts+=$pvformat fi pcmd="pv $pvopts" @@ -101,7 +98,7 @@ timeit(){ local cmd="$@" local x1 x2 took extcode - if [[ $ttime -eq 1 ]];then + if [[ $ttime -eq 1 ]];then x1=$(date +%s) wsrep_log_info "Evaluating $cmd" eval "$cmd" @@ -110,7 +107,7 @@ timeit(){ took=$(( x2-x1 )) wsrep_log_info "NOTE: $stage took $took seconds" totime=$(( totime+took )) - else + else wsrep_log_info "Evaluating $cmd" eval "$cmd" extcode=$? @@ -121,11 +118,11 @@ timeit(){ get_keys() { # $encrypt -eq 1 is for internal purposes only - if [[ $encrypt -ge 2 || $encrypt -eq -1 ]];then - return + if [[ $encrypt -ge 2 || $encrypt -eq -1 ]];then + return fi - if [[ $encrypt -eq 0 ]];then + if [[ $encrypt -eq 0 ]];then if $MY_PRINT_DEFAULTS 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 @@ -252,7 +249,7 @@ get_transfer() TSST_PORT=${WSREP_SST_OPT_PORT:-4444} if [[ $tfmt == 'nc' ]];then - if [[ ! -x `which nc` ]];then + if [[ ! -x `which nc` ]];then wsrep_log_error "nc(netcat) not found in path: $PATH" exit 2 fi @@ -292,7 +289,7 @@ get_transfer() else tfmt='socat' wsrep_log_info "Using socat as streamer" - if [[ ! -x `which socat` ]];then + if [[ ! -x `which socat` ]];then wsrep_log_error "socat not found in path: $PATH" exit 2 fi @@ -389,7 +386,6 @@ get_transfer() wsrep_log_info "Encrypting with CERT: $ssl_cert, KEY: $ssl_key, CA: $ssl_ca" tcmd="socat -u stdio openssl-connect:${WSREP_SST_OPT_HOST}:${TSST_PORT},cert=${ssl_cert},key=${ssl_key},cafile=${ssl_ca},verify=1${donor_extra}${sockopt}" fi - else if [[ $encrypt -eq 1 ]]; then wsrep_log_warning "**** WARNING **** encrypt=1 is deprecated and will be removed in a future release" @@ -408,7 +404,7 @@ get_footprint() { pushd $WSREP_SST_OPT_DATA 1>/dev/null payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c -s | awk 'END { print $1 }') - if $MY_PRINT_DEFAULTS xtrabackup | grep -q -- "--compress";then + if $MY_PRINT_DEFAULTS 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 )) @@ -420,8 +416,7 @@ get_footprint() adjust_progress() { - - if [[ ! -x `which pv` ]];then + if [[ ! -x `which pv` ]];then wsrep_log_error "pv not found in path: $PATH" wsrep_log_error "Disabling all progress/rate-limiting" pcmd="" @@ -430,16 +425,16 @@ adjust_progress() return fi - if [[ -n $progress && $progress != '1' ]];then - if [[ -e $progress ]];then + if [[ -n $progress && $progress != '1' ]];then + if [[ -e $progress ]];then pcmd+=" 2>>$progress" - else + else pcmd+=" 2>$progress" fi - elif [[ -z $progress && -n $rlimit ]];then + elif [[ -z $progress && -n $rlimit ]];then # When rlimit is non-zero pcmd="pv -q" - fi + fi if [[ -n $rlimit && "$WSREP_SST_OPT_ROLE" == "donor" ]];then wsrep_log_info "Rate-limiting SST to $rlimit" @@ -470,8 +465,7 @@ read_cnf() scomp=$(parse_cnf sst compressor "") sdecomp=$(parse_cnf sst decompressor "") - - # Refer to http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html + # 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 "") @@ -502,7 +496,7 @@ read_cnf() ssystag=$(parse_cnf mysqld_safe syslog-tag "${SST_SYSLOG_TAG:-}") ssystag+="-" - if [[ $ssyslog -ne -1 ]];then + if [[ $ssyslog -ne -1 ]];then if $MY_PRINT_DEFAULTS mysqld_safe | grep -q -- "--syslog";then ssyslog=1 fi @@ -511,7 +505,7 @@ read_cnf() get_stream() { - if [[ $sfmt == 'xbstream' ]];then + if [[ $sfmt == 'xbstream' ]];then wsrep_log_info "Streaming with xbstream" if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then strmcmd="xbstream -x" @@ -526,7 +520,6 @@ get_stream() else strmcmd="tar cf - \${INFO_FILE} " fi - fi } @@ -548,33 +541,32 @@ cleanup_joiner() { # Since this is invoked just after exit NNN local estatus=$? - if [[ $estatus -ne 0 ]];then + if [[ $estatus -ne 0 ]];then wsrep_log_error "Cleanup after exit with status:$estatus" elif [ "${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 + if [[ -n $progress && -p $progress ]];then wsrep_log_info "Cleaning up fifo file $progress" rm $progress fi - if [[ -n ${STATDIR:-} ]];then + + if [[ -n ${STATDIR:-} ]];then [[ -d $STATDIR ]] && rm -rf $STATDIR fi - # Final cleanup + # Final cleanup pgid=$(ps -o pgid= $$ | grep -o '[0-9]*') # This means no setsid done in mysqld. # We don't want to kill mysqld here otherwise. if [[ $$ -eq $pgid ]];then - # This means a signal was delivered to the process. - # So, more cleanup. - if [[ $estatus -ge 128 ]];then + # So, more cleanup. + if [[ $estatus -ge 128 ]];then kill -KILL -$$ || true fi - fi exit $estatus @@ -590,11 +582,11 @@ cleanup_donor() { # Since this is invoked just after exit NNN local estatus=$? - if [[ $estatus -ne 0 ]];then + if [[ $estatus -ne 0 ]];then wsrep_log_error "Cleanup after exit with status:$estatus" fi - if [[ -n ${XTRABACKUP_PID:-} ]];then + if [[ -n ${XTRABACKUP_PID:-} ]];then if check_pid $XTRABACKUP_PID then wsrep_log_error "xtrabackup process is still running. Killing... " @@ -602,24 +594,25 @@ cleanup_donor() fi fi + rm -f ${DATA}/${IST_FILE} || true - if [[ -n $progress && -p $progress ]];then + if [[ -n $progress && -p $progress ]];then wsrep_log_info "Cleaning up fifo file $progress" rm -f $progress || true fi wsrep_log_info "Cleaning up temporary directories" - if [[ -n $xtmpdir ]];then + if [[ -n $xtmpdir ]];then [[ -d $xtmpdir ]] && rm -rf $xtmpdir || true fi - if [[ -n $itmpdir ]];then + if [[ -n $itmpdir ]];then [[ -d $itmpdir ]] && rm -rf $itmpdir || true fi - # Final cleanup + # Final cleanup pgid=$(ps -o pgid= $$ | grep -o '[0-9]*') # This means no setsid done in mysqld. @@ -627,15 +620,14 @@ cleanup_donor() if [[ $$ -eq $pgid ]];then # This means a signal was delivered to the process. - # So, more cleanup. - if [[ $estatus -ge 128 ]];then + # So, more cleanup. + if [[ $estatus -ge 128 ]];then kill -KILL -$$ || true fi fi exit $estatus - } kill_xtrabackup() @@ -668,20 +660,20 @@ wait_for_listen() check_extra() { local use_socket=1 - if [[ $uextra -eq 1 ]];then + if [[ $uextra -eq 1 ]];then if [ $(parse_cnf --mysqld thread-handling) = 'pool-of-threads'];then local eport=$(parse_cnf --mysqld extra-port) - if [[ -n $eport ]];then + if [[ -n $eport ]];then # Xtrabackup works only locally. - # Hence, setting host to 127.0.0.1 unconditionally. + # 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 + else wsrep_log_error "Extra port $eport null, failing" exit 1 fi - else + else wsrep_log_info "Thread pool not set, ignore the option use_extra" fi fi @@ -693,7 +685,7 @@ check_extra() recv_joiner() { local dir=$1 - local msg=$2 + local msg=$2 local tmt=$3 local checkf=$4 local ltcmd @@ -706,27 +698,27 @@ recv_joiner() pushd ${dir} 1>/dev/null set +e - if [[ $tmt -gt 0 && -x `which timeout` ]];then - if timeout --help | grep -q -- '-k';then + if [[ $tmt -gt 0 && -x `which timeout` ]];then + if timeout --help | grep -q -- '-k';then ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd" - else + else ltcmd="timeout -s9 $tmt $tcmd" fi timeit "$msg" "$ltcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )" - else + else timeit "$msg" "$tcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )" fi set -e - popd 1>/dev/null + popd 1>/dev/null - if [[ ${RC[0]} -eq 124 ]];then + if [[ ${RC[0]} -eq 124 ]];then wsrep_log_error "Possible timeout in receving first data from donor in gtid stage" exit 32 fi - for ecode in "${RC[@]}";do - if [[ $ecode -ne 0 ]];then + 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 @@ -736,33 +728,30 @@ recv_joiner() if [[ $checkf -eq 1 && ! -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 "Contents of datadir" wsrep_log_info "$(ls -l ${dir}/*)" exit 32 fi } - send_donor() { local dir=$1 - local msg=$2 + local msg=$2 pushd ${dir} 1>/dev/null set +e timeit "$msg" "$strmcmd | $tcmd; RC=( "\${PIPESTATUS[@]}" )" set -e - popd 1>/dev/null - + popd 1>/dev/null - for ecode in "${RC[@]}";do - if [[ $ecode -ne 0 ]];then + 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 - } # Returns the version string in a standardized format @@ -774,7 +763,7 @@ normalize_version() local minor=0 local patch=0 - # Only parses purely numeric version numbers, 1.2.3 + # Only parses purely numeric version numbers, 1.2.3 # Everything after the first three values are ignored if [[ $1 =~ ^([0-9]+)\.([0-9]+)\.?([0-9]*)([\.0-9])*$ ]]; then major=${BASH_REMATCH[1]} @@ -808,12 +797,12 @@ monitor_process() while true ; do if ! ps --pid "${WSREP_SST_OPT_PARENT}" &>/dev/null; then - wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly." + wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly." kill -- -"${WSREP_SST_OPT_PARENT}" exit 32 fi - if ! ps --pid "${sst_stream_pid}" &>/dev/null; then + if ! ps --pid "${sst_stream_pid}" &>/dev/null; then break fi @@ -822,8 +811,7 @@ monitor_process() done } - -if [[ ! -x `which $INNOBACKUPEX_BIN` ]];then +if [[ ! -x `which $INNOBACKUPEX_BIN` ]];then wsrep_log_error "innobackupex not in path: $PATH" exit 2 fi @@ -843,46 +831,43 @@ if ! check_for_version $XB_VERSION $XB_REQUIRED_VERSION; then exit 2 fi - rm -f "${MAGIC_FILE}" -if [[ ! ${WSREP_SST_OPT_ROLE} == 'joiner' && ! ${WSREP_SST_OPT_ROLE} == 'donor' ]];then +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 -if ${INNOBACKUPEX_BIN} /tmp --help 2>/dev/null | grep -q -- '--version-check'; then +if ${INNOBACKUPEX_BIN} /tmp --help 2>/dev/null | grep -q -- '--version-check'; then disver="--no-version-check" fi -if [[ ${FORCE_FTWRL:-0} -eq 1 ]];then +if [[ ${FORCE_FTWRL:-0} -eq 1 ]];then wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL" iopts+=" --no-backup-locks " fi - INNOEXTRA="" -if [[ $ssyslog -eq 1 ]];then +if [[ $ssyslog -eq 1 ]];then - if [[ ! -x `which logger` ]];then + if [[ ! -x `which logger` ]];then wsrep_log_error "logger not in path: $PATH. Ignoring" else - wsrep_log_info "Logging all stderr of SST/Innobackupex to syslog" exec 2> >(logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE) wsrep_log_error() { - logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" + logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" } wsrep_log_info() { - logger -p daemon.info -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" + logger -p daemon.info -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" } INNOAPPLY="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply " @@ -890,7 +875,7 @@ if [[ $ssyslog -eq 1 ]];then INNOBACKUP="2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)" fi -else +else INNOAPPLY="&>\${DATA}/innobackup.prepare.log" INNOMOVE="&>\${DATA}/innobackup.move.log" INNOBACKUP="2>\${DATA}/innobackup.backup.log" @@ -976,12 +961,12 @@ then ttcmd="$tcmd" if [[ $encrypt -eq 1 ]];then - if [[ -n $scomp ]];then + if [[ -n $scomp ]];then tcmd=" \$ecmd | $scomp | $tcmd " - else + else tcmd=" \$ecmd | $tcmd " fi - elif [[ -n $scomp ]];then + elif [[ -n $scomp ]];then tcmd=" $scomp | $tcmd " fi @@ -989,10 +974,10 @@ then # Restore the transport commmand to its original state tcmd="$ttcmd" - if [[ -n $progress ]];then + if [[ -n $progress ]];then get_footprint tcmd="$pcmd | $tcmd" - elif [[ -n $rlimit ]];then + elif [[ -n $rlimit ]];then adjust_progress tcmd="$pcmd | $tcmd" fi @@ -1020,7 +1005,7 @@ 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 + elif [[ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]];then wsrep_log_error "$tcmd finished with error: ${RC[1]}" exit 22 fi @@ -1028,7 +1013,6 @@ then # innobackupex implicitly writes PID to fixed location in $xtmpdir XTRABACKUP_PID="$xtmpdir/xtrabackup_pid" - else # BYPASS FOR IST wsrep_log_info "Bypassing the SST for IST" @@ -1040,12 +1024,12 @@ then echo "1" > "${DATA}/${IST_FILE}" get_keys if [[ $encrypt -eq 1 ]];then - if [[ -n $scomp ]];then + if [[ -n $scomp ]];then tcmd=" \$ecmd | $scomp | $tcmd " else tcmd=" \$ecmd | $tcmd " fi - elif [[ -n $scomp ]];then + elif [[ -n $scomp ]];then tcmd=" $scomp | $tcmd " fi strmcmd+=" \${IST_FILE}" @@ -1099,19 +1083,19 @@ then trap sig_joiner_cleanup HUP PIPE INT TERM trap cleanup_joiner EXIT - if [[ -n $progress ]];then + if [[ -n $progress ]];then adjust_progress tcmd+=" | $pcmd" fi get_keys if [[ $encrypt -eq 1 && $sencrypted -eq 1 ]];then - if [[ -n $sdecomp ]];then + if [[ -n $sdecomp ]];then strmcmd=" $sdecomp | \$ecmd | $strmcmd" - else + else strmcmd=" \$ecmd | $strmcmd" fi - elif [[ -n $sdecomp ]];then + elif [[ -n $sdecomp ]];then strmcmd=" $sdecomp | $strmcmd" fi @@ -1119,10 +1103,9 @@ then MAGIC_FILE="${STATDIR}/${INFO_FILE}" recv_joiner $STATDIR "${stagemsg}-gtid" $stimeout 1 - if ! ps -p ${WSREP_SST_OPT_PARENT} &>/dev/null then - wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly." + wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly." exit 32 fi @@ -1138,7 +1121,6 @@ then jpid=$! wsrep_log_info "Proceeding with SST" - wsrep_log_info "Cleaning the existing datadir and innodb-data/log directories" if [ "${OS}" = "FreeBSD" ]; then find -E $ib_home_dir $ib_log_dir $ib_undo_dir $DATA -mindepth 1 -prune -regex $cpat -o -exec rm -rfv {} 1>&2 \+ @@ -1164,30 +1146,27 @@ then fi fi - - TDATA=${DATA} DATA="${DATA}/.sst" - MAGIC_FILE="${DATA}/${INFO_FILE}" wsrep_log_info "Waiting for SST streaming to complete!" monitor_process $jpid get_proc - if [[ ! -s ${DATA}/xtrabackup_checkpoints ]];then + if [[ ! -s ${DATA}/xtrabackup_checkpoints ]];then wsrep_log_error "xtrabackup_checkpoints missing, failed innobackupex/SST on donor" exit 2 fi # Rebuild indexes for compact backups - if grep -q 'compact = 1' ${DATA}/xtrabackup_checkpoints;then + if grep -q 'compact = 1' ${DATA}/xtrabackup_checkpoints;then wsrep_log_info "Index compaction detected" rebuild=1 fi - if [[ $rebuild -eq 1 ]];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" @@ -1197,7 +1176,7 @@ then wsrep_log_info "Compressed qpress files found" - if [[ ! -x `which qpress` ]];then + if [[ ! -x `which qpress` ]];then wsrep_log_error "qpress not found in path: $PATH" exit 22 fi @@ -1205,28 +1184,27 @@ then 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 + 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 + else pvopts="-f -s $count -l -N Decompression" fi pcmd="pv $pvopts" adjust_progress dcmd="$pcmd | xargs -n 2 qpress -T${nproc}d" - else + else dcmd="xargs -n 2 qpress -T${nproc}d" fi - - # Decompress the qpress files + # 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 + 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 @@ -1235,13 +1213,12 @@ then fi fi - if [[ ! -z $WSREP_SST_OPT_BINLOG ]];then BINLOG_DIRNAME=$(dirname $WSREP_SST_OPT_BINLOG) BINLOG_FILENAME=$(basename $WSREP_SST_OPT_BINLOG) - # To avoid comparing data directory and BINLOG_DIRNAME + # To avoid comparing data directory and BINLOG_DIRNAME mv $DATA/${BINLOG_FILENAME}.* $BINLOG_DIRNAME/ 2>/dev/null || true pushd $BINLOG_DIRNAME &>/dev/null @@ -1257,7 +1234,7 @@ then if [ $? -ne 0 ]; then - wsrep_log_error "${INNOBACKUPEX_BIN} apply finished with errors. Check ${DATA}/innobackup.prepare.log" + wsrep_log_error "${INNOBACKUPEX_BIN} apply finished with errors. Check ${DATA}/innobackup.prepare.log" exit 22 fi @@ -1267,22 +1244,21 @@ then set -e wsrep_log_info "Moving the backup to ${TDATA}" timeit "Xtrabackup move stage" "$INNOMOVE" - if [[ $? -eq 0 ]];then + if [[ $? -eq 0 ]];then wsrep_log_info "Move successful, removing ${DATA}" rm -rf $DATA DATA=${TDATA} - else + else wsrep_log_error "Move failed, keeping ${DATA} for further diagnosis" wsrep_log_error "Check ${DATA}/innobackup.move.log for details" exit 22 fi - - else + else wsrep_log_info "${IST_FILE} received from donor: Running IST" fi - if [[ ! -r ${MAGIC_FILE} ]];then + if [[ ! -r ${MAGIC_FILE} ]];then wsrep_log_error "SST magic file ${MAGIC_FILE} not found/readable" exit 2 fi diff --git a/scripts/wsrep_sst_xtrabackup.sh b/scripts/wsrep_sst_xtrabackup.sh index c4feac2a135..d0083a8eea0 100644 --- a/scripts/wsrep_sst_xtrabackup.sh +++ b/scripts/wsrep_sst_xtrabackup.sh @@ -15,12 +15,9 @@ # Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston # MA 02110-1335 USA. -# Optional dependencies and options documented here: http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html +# 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 ealgo="" @@ -52,7 +49,7 @@ 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 +if which pv &>/dev/null && pv --help | grep -q FORMAT;then pvopts+=$pvformat fi pcmd="pv $pvopts" @@ -73,7 +70,7 @@ timeit(){ local cmd="$@" local x1 x2 took extcode - if [[ $ttime -eq 1 ]];then + if [[ $ttime -eq 1 ]];then x1=$(date +%s) wsrep_log_info "Evaluating $cmd" eval "$cmd" @@ -82,7 +79,7 @@ timeit(){ took=$(( x2-x1 )) wsrep_log_info "NOTE: $stage took $took seconds" totime=$(( totime+took )) - else + else wsrep_log_info "Evaluating $cmd" eval "$cmd" extcode=$? @@ -92,11 +89,11 @@ timeit(){ get_keys() { - if [[ $encrypt -eq 2 ]];then - return + if [[ $encrypt -eq 2 ]];then + return fi - if [[ $encrypt -eq 0 ]];then + if [[ $encrypt -eq 0 ]];then if $MY_PRINT_DEFAULTS 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 @@ -137,13 +134,13 @@ get_transfer() TSST_PORT=${WSREP_SST_OPT_PORT:-4444} if [[ $tfmt == 'nc' ]];then - if [[ ! -x `which 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 - if nc -h 2>&1 | grep -q ncat;then + if nc -h 2>&1 | grep -q ncat;then # Ncat tcmd="nc -l ${TSST_PORT}" elif nc -h 2>&1 | grep -q -- '-d\>';then @@ -168,19 +165,19 @@ get_transfer() else tfmt='socat' wsrep_log_info "Using socat as streamer" - if [[ ! -x `which socat` ]];then + 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 + 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 + if [[ $encrypt -eq 2 ]];then wsrep_log_info "Using openssl based encryption with socat" - if [[ -z $tpem || -z $tcert ]];then + if [[ -z $tpem || -z $tcert ]];then wsrep_log_error "Both PEM and CRT files required" exit 22 fi @@ -191,7 +188,7 @@ get_transfer() wsrep_log_info "Encrypting with PEM $tpem, CA: $tcert" tcmd="socat -u stdio openssl-connect:${WSREP_SST_OPT_HOST}:${TSST_PORT},cert=$tpem,cafile=${tcert}${sockopt}" fi - else + else if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then tcmd="socat -u TCP-LISTEN:${TSST_PORT},reuseaddr${sockopt} stdio" else @@ -199,14 +196,13 @@ get_transfer() fi fi fi - } get_footprint() { pushd $WSREP_SST_OPT_DATA 1>/dev/null payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c -s | awk 'END { print $1 }') - if $MY_PRINT_DEFAULTS xtrabackup | grep -q -- "--compress";then + if $MY_PRINT_DEFAULTS 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 )) @@ -218,16 +214,16 @@ get_footprint() adjust_progress() { - if [[ -n $progress && $progress != '1' ]];then - if [[ -e $progress ]];then + if [[ -n $progress && $progress != '1' ]];then + if [[ -e $progress ]];then pcmd+=" 2>>$progress" - else + else pcmd+=" 2>$progress" fi - elif [[ -z $progress && -n $rlimit ]];then + elif [[ -z $progress && -n $rlimit ]];then # When rlimit is non-zero pcmd="pv -q" - fi + fi if [[ -n $rlimit && "$WSREP_SST_OPT_ROLE" == "donor" ]];then wsrep_log_info "Rate-limiting SST to $rlimit" @@ -251,7 +247,7 @@ read_cnf() 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 + # 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 "") @@ -263,7 +259,7 @@ read_cnf() get_stream() { - if [[ $sfmt == 'xbstream' ]];then + if [[ $sfmt == 'xbstream' ]];then wsrep_log_info "Streaming with xbstream" if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then strmcmd="xbstream -x" @@ -278,7 +274,6 @@ get_stream() else strmcmd="tar cf - \${INFO_FILE} \${IST_FILE}" fi - fi } @@ -300,14 +295,14 @@ cleanup_joiner() { # Since this is invoked just after exit NNN local estatus=$? - if [[ $estatus -ne 0 ]];then + 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 + if [[ -n $progress && -p $progress ]];then wsrep_log_info "Cleaning up fifo file $progress" rm $progress fi @@ -323,22 +318,22 @@ cleanup_donor() { # Since this is invoked just after exit NNN local estatus=$? - if [[ $estatus -ne 0 ]];then + if [[ $estatus -ne 0 ]];then wsrep_log_error "Cleanup after exit with status:$estatus" fi - if [[ -n $XTRABACKUP_PID ]];then + 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 + rm -f $XTRABACKUP_PID fi + rm -f ${DATA}/${IST_FILE} - if [[ -n $progress && -p $progress ]];then + if [[ -n $progress && -p $progress ]];then wsrep_log_info "Cleaning up fifo file $progress" rm $progress fi @@ -363,9 +358,9 @@ wait_for_listen() ss -p state listening "( sport = :$PORT )" | grep -qE 'socat|nc' && break sleep 0.2 done - if [[ $incremental -eq 1 ]];then + if [[ $incremental -eq 1 ]];then echo "ready ${ADDR}/${MODULE}/$lsn" - else + else echo "ready ${ADDR}/${MODULE}" fi } @@ -373,20 +368,20 @@ wait_for_listen() check_extra() { local use_socket=1 - if [[ $uextra -eq 1 ]];then + if [[ $uextra -eq 1 ]];then if [ $(parse_cnf --mysqld thread-handling) = 'pool-of-threads'];then local eport=$(parse_cnf --mysqld extra-port) - if [[ -n $eport ]];then + if [[ -n $eport ]];then # Xtrabackup works only locally. - # Hence, setting host to 127.0.0.1 unconditionally. + # 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 + else wsrep_log_error "Extra port $eport null, failing" exit 1 fi - else + else wsrep_log_info "Thread pool not set, ignore the option use_extra" fi fi @@ -395,14 +390,14 @@ check_extra() fi } -if [[ ! -x `which innobackupex` ]];then +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 +if [[ ! ${WSREP_SST_OPT_ROLE} == 'joiner' && ! ${WSREP_SST_OPT_ROLE} == 'donor' ]];then wsrep_log_error "Invalid role ${WSREP_SST_OPT_ROLE}" exit 22 fi @@ -440,12 +435,12 @@ then if [[ $encrypt -eq 1 ]];then if [[ -n $ekey ]];then INNOEXTRA+=" --encrypt=$ealgo --encrypt-key=$ekey" - else + else INNOEXTRA+=" --encrypt=$ealgo --encrypt-key-file=$ekeyfile" fi fi - if [[ -n $lsn ]];then + if [[ -n $lsn ]];then INNOEXTRA+=" --incremental --incremental-lsn=$lsn" fi @@ -453,10 +448,10 @@ then wsrep_log_info "Streaming the backup to joiner at ${WSREP_SST_OPT_HOST} ${WSREP_SST_OPT_PORT}" - if [[ -n $progress ]];then + if [[ -n $progress ]];then get_footprint tcmd="$pcmd | $tcmd" - elif [[ -n $rlimit ]];then + elif [[ -n $rlimit ]];then adjust_progress tcmd="$pcmd | $tcmd" fi @@ -469,7 +464,7 @@ 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 + elif [[ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]];then wsrep_log_error "$tcmd finished with error: ${RC[1]}" exit 22 fi @@ -496,13 +491,14 @@ then set -e popd 1>/dev/null - for ecode in "${RC[@]}";do - if [[ $ecode -ne 0 ]];then + for ecode in "${RC[@]}";do + if [[ $ecode -ne 0 ]];then wsrep_log_error "Error while streaming data to joiner node: " \ "exit codes: ${RC[@]}" exit 1 fi done + fi echo "done ${WSREP_SST_OPT_GTID}" @@ -513,11 +509,11 @@ 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 + if [[ ! -e ${DATA}/ibdata1 ]];then incremental=0 fi - if [[ $incremental -eq 1 ]];then + if [[ $incremental -eq 1 ]];then wsrep_log_info "Incremental SST enabled" #lsn=$(/pxc/bin/mysqld $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 ' ') @@ -539,12 +535,12 @@ then trap sig_joiner_cleanup HUP PIPE INT TERM trap cleanup_joiner EXIT - if [[ -n $progress ]];then + if [[ -n $progress ]];then adjust_progress tcmd+=" | $pcmd" fi - if [[ $incremental -eq 1 ]];then + if [[ $incremental -eq 1 ]];then BDATA=$DATA DATA=$(mktemp -d) MAGIC_FILE="${DATA}/${INFO_FILE}" @@ -558,13 +554,13 @@ then pushd ${DATA} 1>/dev/null timeit "Joiner-Recv-Unencrypted" "$tcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )" - popd 1>/dev/null + popd 1>/dev/null set -e - if [[ $sfmt == 'xbstream' ]];then + if [[ $sfmt == 'xbstream' ]];then # Special handling till lp:1193240 is fixed" - if [[ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]];then + if [[ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]];then wsrep_log_error "Xbstream failed" wsrep_log_error "Data directory ${DATA} may not be empty: lp:1193240" \ "Manual intervention required in that case" @@ -574,8 +570,8 @@ then wait %% # join for wait_for_listen thread - for ecode in "${RC[@]}";do - if [[ $ecode -ne 0 ]];then + 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 @@ -586,22 +582,23 @@ 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 "Contents of datadir" wsrep_log_info "$(ls -l ${DATA}/**/*)" exit 32 fi if ! ps -p ${WSREP_SST_OPT_PARENT} &>/dev/null then - wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly." + wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly." exit 32 fi if [ ! -r "${DATA}/${IST_FILE}" ] then wsrep_log_info "Proceeding with SST" + wsrep_log_info "Removing existing ib_logfile files" - if [[ $incremental -ne 1 ]];then + if [[ $incremental -ne 1 ]];then rm -f ${DATA}/ib_logfile* else rm -f ${BDATA}/ib_logfile* @@ -610,12 +607,12 @@ then get_proc # Rebuild indexes for compact backups - if grep -q 'compact = 1' ${DATA}/xtrabackup_checkpoints;then + if grep -q 'compact = 1' ${DATA}/xtrabackup_checkpoints;then wsrep_log_info "Index compaction detected" rebuild=1 fi - if [[ $rebuild -eq 1 ]];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" @@ -625,7 +622,7 @@ then wsrep_log_info "Compressed qpress files found" - if [[ ! -x `which qpress` ]];then + if [[ ! -x `which qpress` ]];then wsrep_log_error "qpress not found in path: $PATH" exit 22 fi @@ -633,30 +630,30 @@ then 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 + 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 + else pvopts="-f -s $count -l -N Decompression" fi pcmd="pv $pvopts" adjust_progress dcmd="$pcmd | xargs -n 2 qpress -T${nproc}d" - else + 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 + # Decompress the qpress files wsrep_log_info "Decompression with $nproc threads" timeit "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 + 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 @@ -665,7 +662,7 @@ then fi fi - if [[ $incremental -eq 1 ]];then + if [[ $incremental -eq 1 ]];then # Added --ibbackup=xtrabackup_55 because it fails otherwise citing connection issues. INNOAPPLY="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} \ --ibbackup=xtrabackup_55 --apply-log $rebuildcmd --redo-only $BDATA --incremental-dir=${DATA} &>>${BDATA}/innobackup.prepare.log" @@ -674,7 +671,7 @@ then wsrep_log_info "Preparing the backup at ${DATA}" timeit "Xtrabackup prepare stage" "$INNOAPPLY" - if [[ $incremental -eq 1 ]];then + if [[ $incremental -eq 1 ]];then wsrep_log_info "Cleaning up ${DATA} after incremental SST" [[ -d ${DATA} ]] && rm -rf ${DATA} DATA=$BDATA @@ -682,10 +679,10 @@ then if [ $? -ne 0 ]; then - wsrep_log_error "${INNOBACKUPEX_BIN} finished with errors. Check ${DATA}/innobackup.prepare.log" + wsrep_log_error "${INNOBACKUPEX_BIN} finished with errors. Check ${DATA}/innobackup.prepare.log" exit 22 fi - else + else wsrep_log_info "${IST_FILE} received from donor: Running IST" fi -- cgit v1.2.1 From 1ae7673aae7f82c4e659b1337177f2696c8e45ba Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Wed, 28 Apr 2021 01:39:31 +0200 Subject: MDEV-24962: Galera SST innobackupex-move ignores Environment settings After switching to the new mariabackup interface (instead of the outdated innobackupex interface, which is supported for compatibility), we need to explicitly pass a path to the datadir directory as a parameter, since in the new interface the value of this option is not automatically set in such a way that it always matches the SST/IST logic. This commit adds passing this option as an explicit parameter to mariabackup. This commit also removed unnecessary options that are not used and not supported by mariabackup. Also, numerous flaws in the common wsrep_sst_common script have been fixed: 1) There are many bash-specific constructs in the script that may not be supported by other interpreters, which can lead to the most unexpected errors during SST, because failures in the interpretation of bash-specific constructs lead to incorrect parsing of arguments; 2) There is parse_cnf() function which is often called by other scripts for the "mysqld" or "--mysqld" group, but it does not take into account the default group suffix, which leads to reading values only from the default group, which then leads to errors due to reading the default values instead of the values for a specific group; 3) Some options such as --user, --innodb-data-home-dir or --datadir are not removed from the --mysqld-args list, although they are processed inside scripts (and passing of these options funther may cause problems for mariabackup); 4) If an argument that the script understands is present in the --mysqld-args list twice, then this causes SST to fail, instead of reading the most recent value; 5) The "--host" parameter is technically still supported among the arguments of the SST scripts, but in reality scripts do not work with it as expected, especially if it has an IPv6 address; 6) If the port number is absent in the --address parameter value, but the port number is explicitly passed through the --port argument, then the scripts for mariabackup and xtrabackup-v2 fail; 7) If a new address interface is used (with the --address parameter), then automatic default port substitution is not performed, although it is supported for the legacy --host/--port interface. 8) If there are spaces in the parameter values after --mysqld_args, then their further transfer does not occur correctly, which causes mariabackup to fail during SST - the space splits the argument in such a way that it breaks the parsing of the following parameters; 9) If most of the parameters that are names or paths to the files or directories contain spaces, then SST scripts fail in an unpredictable way due to incorrect variable substitutions; 10) If the --log-bin option is passed among the arguments of myqlds (--mysqld-args) without a parameter, and the --binlog option is not specified, then the script cannot substitute the default name for binlog and cannot construct binlog name using the --log-basename argument (which is against server specifications); 11) Tail slashes are not removed from the directory names, which, upon further substitution, leads to the appearance of a double slash in the file paths; 12) The explicit --binlog parameter (which is now always transmitted from the server side) and the "hidden" --log-bin parameter in the list of arguments after --mysqld-args are perceived as two different parameters in different parts of the scripts, and if they are do not match for some reason, this will lead to failures during SST; Also, all new changes from the 10.6 branch have been migrated here, including the latest pull requests for authentication (only the part that concerns SST scripts). It also fixes dozens of other bugs in all SST scripts. --- mysql-test/suite/galera/disabled.def | 7 +- .../r/galera_ist_innodb_flush_logs,debug.rdiff | 13 +- .../suite/galera/r/galera_ist_xtrabackup-v2.result | 2 +- .../suite/galera/r/galera_ssl_upgrade.result | 17 +- .../galera/t/galera_ist_innodb_flush_logs.cnf | 2 +- .../galera/t/galera_ist_innodb_flush_logs.test | 2 +- mysql-test/suite/galera/t/galera_ssl_upgrade.test | 22 +- .../galera_sst_xtrabackup-v2_encrypt_with_key.cnf | 4 +- mysql-test/suite/galera_3nodes/disabled.def | 6 +- scripts/wsrep_sst_common.sh | 623 ++++++++++++---- scripts/wsrep_sst_mariabackup.sh | 783 +++++++++++---------- scripts/wsrep_sst_mysqldump.sh | 6 +- scripts/wsrep_sst_rsync.sh | 333 +++++---- scripts/wsrep_sst_xtrabackup-v2.sh | 387 +++++----- scripts/wsrep_sst_xtrabackup.sh | 15 +- 15 files changed, 1376 insertions(+), 846 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index d9483864844..176b83d56b2 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -5,7 +5,7 @@ # Separate the test case name and the comment with ':'. # # : MDEV- -# +# # Do not use any TAB characters for whitespace. # ############################################################################## @@ -17,7 +17,7 @@ galera_as_slave_replication_bundle : MDEV-15785 OPTION_GTID_BEGIN is set in Gtid galera_concurrent_ctas : MDEV-24842 Galera test failure on galera_concurrent_ctas galera_gcache_recover_manytrx : MDEV-18834 Galera test failure galera_mdl_race : MDEV-21524: galera.galera_mdl_race MTR failed: query 'reap' succeeded - should have failed with errno 1213 -galera_parallel_simple : MDEV-20318 galera.galera_parallel_simple fails +galera_parallel_simple : MDEV-20318 galera.galera_parallel_simple fails galera_partition : MDEV-21806: galera.galera_partition MTR failed: failed to recover from DONOR state galera_shutdown_nonprim : MDEV-21493 galera.galera_shutdown_nonprim galera_var_node_address : MDEV-20485 Galera test failure @@ -28,3 +28,6 @@ sql_log_bin : MDEV-21491 galera.sql_log_bin versioning_trx_id: MDEV-18590: galera.versioning_trx_id: Test failure: mysqltest: Result content mismatch galera_wsrep_provider_unset_set: wsrep_provider is read-only for security reasons pxc-421: wsrep_provider is read-only for security reasons +galera_sst_xtrabackup-v2: Test fails due to innodb issues +galera_sst_xtrabackup-v2_encrypt_with_key: Test fails due to innodb issues +galera_sst_xtrabackup-v2_data_dir: Test fails due to innodb issues diff --git a/mysql-test/suite/galera/r/galera_ist_innodb_flush_logs,debug.rdiff b/mysql-test/suite/galera/r/galera_ist_innodb_flush_logs,debug.rdiff index fa1b67e7ef3..55f1150c930 100644 --- a/mysql-test/suite/galera/r/galera_ist_innodb_flush_logs,debug.rdiff +++ b/mysql-test/suite/galera/r/galera_ist_innodb_flush_logs,debug.rdiff @@ -1,11 +1,12 @@ --- r/galera_ist_innodb_flush_logs.result 2018-09-05 10:34:36.192439933 +0300 +++ r/galera_ist_innodb_flush_logs.reject 2018-09-17 10:20:06.039150838 +0300 -@@ -86,3 +86,100 @@ +@@ -86,3 +86,111 @@ DROP TABLE t1; COMMIT; SET AUTOCOMMIT=ON; +Performing State Transfer on a server that has been killed and restarted +while a DDL was in progress on it ++connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; @@ -14,6 +15,7 @@ +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); ++connection node_2; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); @@ -22,9 +24,12 @@ +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +SET GLOBAL debug_dbug = 'd,sync.alter_opened_table'; ++connection node_1; +ALTER TABLE t1 ADD COLUMN f2 INTEGER; ++connection node_2; +SET wsrep_sync_wait = 0; +Killing server ... ++connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); @@ -39,6 +44,7 @@ +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); ++connect node_1a_galera_st_kill_slave_ddl, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); @@ -46,7 +52,9 @@ +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); ++connection node_2; +Performing --wsrep-recover ... ++connection node_2; +Starting server ... +Using --wsrep-start-position when starting mysqld ... +SET AUTOCOMMIT=OFF; @@ -57,6 +65,7 @@ +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +COMMIT; ++connection node_1; +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); @@ -71,6 +80,7 @@ +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +COMMIT; ++connection node_1a_galera_st_kill_slave_ddl; +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); @@ -88,6 +98,7 @@ +1 +COMMIT; +SET AUTOCOMMIT=ON; ++connection node_1; +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +COUNT(*) = 2 +1 diff --git a/mysql-test/suite/galera/r/galera_ist_xtrabackup-v2.result b/mysql-test/suite/galera/r/galera_ist_xtrabackup-v2.result index 8a7c02ab1b6..80a28d349ba 100644 --- a/mysql-test/suite/galera/r/galera_ist_xtrabackup-v2.result +++ b/mysql-test/suite/galera/r/galera_ist_xtrabackup-v2.result @@ -21,7 +21,7 @@ INSERT INTO t1 VALUES ('node2_committed_before'); INSERT INTO t1 VALUES ('node2_committed_before'); COMMIT; Unloading wsrep provider ... -SET GLOBAL wsrep_provider = 'none'; +SET GLOBAL wsrep_cluster_address = ''; connection node_1; SET AUTOCOMMIT=OFF; START TRANSACTION; diff --git a/mysql-test/suite/galera/r/galera_ssl_upgrade.result b/mysql-test/suite/galera/r/galera_ssl_upgrade.result index 8aab135c6a2..1443e34d041 100644 --- a/mysql-test/suite/galera/r/galera_ssl_upgrade.result +++ b/mysql-test/suite/galera/r/galera_ssl_upgrade.result @@ -1,10 +1,3 @@ -call mtr.add_suppression("WSREP: write_handler(): protocol is shutdown"); -SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; -VARIABLE_VALUE = 'Synced' -1 -SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; -VARIABLE_VALUE = 2 -1 connection node_1; call mtr.add_suppression("WSREP: write_handler(): protocol is shutdown.*"); connection node_2; @@ -12,6 +5,14 @@ call mtr.add_suppression("WSREP: write_handler(): protocol is shutdown.*"); connection node_1; connection node_2; connection node_1; +connection node_2; +SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; +VARIABLE_VALUE = 'Synced' +1 +SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +VARIABLE_VALUE = 2 +1 +connection node_1; SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 2 1 @@ -23,3 +24,5 @@ connection node_1; SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; VARIABLE_VALUE = 2 1 +disconnect node_2; +disconnect node_1; diff --git a/mysql-test/suite/galera/t/galera_ist_innodb_flush_logs.cnf b/mysql-test/suite/galera/t/galera_ist_innodb_flush_logs.cnf index b91c897e66e..a93c291b47c 100644 --- a/mysql-test/suite/galera/t/galera_ist_innodb_flush_logs.cnf +++ b/mysql-test/suite/galera/t/galera_ist_innodb_flush_logs.cnf @@ -1,7 +1,7 @@ !include ../galera_2nodes.cnf [mysqld] -wsrep_sst_method=xtrabackup-v2 +wsrep_sst_method=mariabackup wsrep_sst_auth=root: innodb_safe_truncate=OFF diff --git a/mysql-test/suite/galera/t/galera_ist_innodb_flush_logs.test b/mysql-test/suite/galera/t/galera_ist_innodb_flush_logs.test index 839383ebfc1..fd362a26840 100644 --- a/mysql-test/suite/galera/t/galera_ist_innodb_flush_logs.test +++ b/mysql-test/suite/galera/t/galera_ist_innodb_flush_logs.test @@ -7,7 +7,7 @@ --source include/big_test.inc --source include/galera_cluster.inc --source include/have_innodb.inc ---source include/have_xtrabackup.inc +--source include/have_mariabackup.inc --source suite/galera/include/galera_st_kill_slave.inc --source suite/galera/include/galera_st_kill_slave_ddl.inc diff --git a/mysql-test/suite/galera/t/galera_ssl_upgrade.test b/mysql-test/suite/galera/t/galera_ssl_upgrade.test index 33c5a43df9d..4d6b9159c78 100644 --- a/mysql-test/suite/galera/t/galera_ssl_upgrade.test +++ b/mysql-test/suite/galera/t/galera_ssl_upgrade.test @@ -8,16 +8,16 @@ --source include/have_innodb.inc --source include/have_ssl_communication.inc -call mtr.add_suppression("WSREP: write_handler(): protocol is shutdown"); - -SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; -SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; - --connection node_1 call mtr.add_suppression("WSREP: write_handler(): protocol is shutdown.*"); --connection node_2 call mtr.add_suppression("WSREP: write_handler(): protocol is shutdown.*"); +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--source include/auto_increment_offset_save.inc + # Setup galera ports --connection node_1 --source suite/galera/include/galera_base_port.inc @@ -27,6 +27,9 @@ call mtr.add_suppression("WSREP: write_handler(): protocol is shutdown.*"); --source suite/galera/include/galera_base_port.inc --let $NODE_GALERAPORT_2 = $_NODE_GALERAPORT +SELECT VARIABLE_VALUE = 'Synced' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_state_comment'; +SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; + # 2. Restart node #1 with a socket.ssl_ca that includes both the new and the old certificate --connection node_1 @@ -40,7 +43,7 @@ call mtr.add_suppression("WSREP: write_handler(): protocol is shutdown.*"); --source include/wait_condition.inc SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; -# 3. Restart node #2 with the new socket.ssl_ca , socket.ssl_cert and socket.ssl_key +# 3. Restart node #2 with the new socket.ssl_ca , socket.ssl_cert and socket.ssl_key --connection node_2 --source include/shutdown_mysqld.inc @@ -52,7 +55,7 @@ SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_N --source include/wait_condition.inc SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; -# 4. Restart node #1 with the new socket.ssl_ca , socket.ssl_cert and socket.ssl_key +# 4. Restart node #1 with the new socket.ssl_ca , socket.ssl_cert and socket.ssl_key --connection node_1 --source include/shutdown_mysqld.inc @@ -65,3 +68,8 @@ SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_N SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; # Upgrade complete. Both nodes now use the new key and certificate + +# Restore original auto_increment_offset values. +--source include/auto_increment_offset_restore.inc + +--source include/galera_end.inc diff --git a/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2_encrypt_with_key.cnf b/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2_encrypt_with_key.cnf index 792b0d15ac4..7a98fd2aa58 100644 --- a/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2_encrypt_with_key.cnf +++ b/mysql-test/suite/galera/t/galera_sst_xtrabackup-v2_encrypt_with_key.cnf @@ -7,7 +7,7 @@ wsrep_debug=ON innodb_safe_truncate=OFF [SST] -tkey=@ENV.MYSQL_TEST_DIR/std_data/galera-key.pem -tcert=@ENV.MYSQL_TEST_DIR/std_data/galera-cert.pem +tkey=@ENV.MYSQL_TEST_DIR/std_data/cakey.pem +tcert=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem encrypt=3 transferfmt=@ENV.MTR_GALERA_TFMT diff --git a/mysql-test/suite/galera_3nodes/disabled.def b/mysql-test/suite/galera_3nodes/disabled.def index 87eca207d5a..7c4d16f98f5 100644 --- a/mysql-test/suite/galera_3nodes/disabled.def +++ b/mysql-test/suite/galera_3nodes/disabled.def @@ -5,17 +5,13 @@ # Separate the test case name and the comment with ':'. # # : MDEV- -# +# # Do not use any TAB characters for whitespace. # ############################################################################## GAL-501 : MDEV-24645 galera_3nodes.GAL-501 MTR failed: failed to open gcomm backend connection: 110 galera_gtid_2_cluster : MDEV-23775 Galera test failure on galera_3nodes.galera_gtid_2_cluster -galera_ipv6_mariabackup : MDEV-24440: galera_3nodes.galera_ipv6_mariabackup MTR fails sporadically: Failed to read from: wsrep_sst_mariabackup --role 'donor' --address '[::1]:16028/xtrabackup_sst//1' -galera_ipv6_mariabackup_section : MDEV-22195: galera_3nodes.galera_ipv6_mariabackup_section MTR failed: assert_grep.inc failed -galera_ipv6_mysqldump : MDEV-24036: galera_3nodes.galera_ipv6_mysqldump: rare random crashes during shutdown -galera_ipv6_rsync_section : MDEV-23580: galera_3nodes.galera_ipv6_rsync_section MTR failed: WSREP_SST: [ERROR] rsync daemon port '16008' has been taken galera_ist_gcache_rollover : MDEV-23578 WSREP: exception caused by message: {v=0,t=1,ut=255,o=4,s=0,sr=0,as=1,f=6,src=50524cfe,srcvid=view_id(REG,50524cfe,4),insvid=view_id(UNKNOWN,00000000,0),ru=00000000,r=[-1,-1],fs=75,nl=(} galera_load_data_ist : MDEV-24639 galera_3nodes.galera_load_data_ist MTR failed with SIGABRT: query 'reap' failed: 2013: Lost connection to MySQL server during query galera_load_data_ist : MDEV-24639 galera_3nodes.galera_load_data_ist MTR failed with SIGABRT: query 'reap' failed: 2013: Lost connection to MySQL server during query diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index 51f811bda78..9e6807e20a3 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -1,4 +1,5 @@ # Copyright (C) 2012-2015 Codership Oy +# Copyright (C) 2017-2021 MariaDB # # 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 @@ -21,24 +22,32 @@ set -u WSREP_SST_OPT_BYPASS=0 WSREP_SST_OPT_BINLOG="" WSREP_SST_OPT_BINLOG_INDEX="" +WSREP_SST_OPT_LOG_BASENAME="" WSREP_SST_OPT_DATA="" -WSREP_SST_OPT_AUTH=${WSREP_SST_OPT_AUTH:-} -WSREP_SST_OPT_USER=${WSREP_SST_OPT_USER:-} -WSREP_SST_OPT_PSWD=${WSREP_SST_OPT_PSWD:-} +WSREP_SST_OPT_AUTH="${WSREP_SST_OPT_AUTH:-}" +WSREP_SST_OPT_USER="${WSREP_SST_OPT_USER:-}" +WSREP_SST_OPT_PSWD="${WSREP_SST_OPT_PSWD:-}" +WSREP_SST_OPT_REMOTE_AUTH="${WSREP_SST_OPT_REMOTE_AUTH:-}" WSREP_SST_OPT_DEFAULT="" WSREP_SST_OPT_EXTRA_DEFAULT="" WSREP_SST_OPT_SUFFIX_DEFAULT="" WSREP_SST_OPT_SUFFIX_VALUE="" WSREP_SST_OPT_MYSQLD="" -INNODB_DATA_HOME_DIR_ARG="" -INNODB_LOG_GROUP_HOME_ARG="" -INNODB_UNDO_DIR_ARG="" -LOG_BIN_ARG="" +WSREP_SST_OPT_PORT="" +WSREP_SST_OPT_ADDR="" +WSREP_SST_OPT_ADDR_PORT="" +WSREP_SST_OPT_HOST="" +WSREP_SST_OPT_HOST_UNESCAPED="" +WSREP_SST_OPT_HOST_ESCAPED="" +INNODB_DATA_HOME_DIR="${INNODB_DATA_HOME_DIR:-}" +INNODB_LOG_GROUP_HOME="${INNODB_LOG_GROUP_HOME:-}" +INNODB_UNDO_DIR="${INNODB_UNDO_DIR:-}" +INNOEXTRA="" while [ $# -gt 0 ]; do case "$1" in '--address') - readonly WSREP_SST_OPT_ADDR="$2" + WSREP_SST_OPT_ADDR="$2" # # Break address string into host:port/path parts # @@ -46,60 +55,61 @@ case "$1" in \[*) # IPv6 # Remove the starting and ending square brackets, if present: - addr_no_bracket=${WSREP_SST_OPT_ADDR#\[} - readonly WSREP_SST_OPT_HOST_UNESCAPED=${addr_no_bracket%%\]*} - # Square brackets are needed in most cases: - readonly WSREP_SST_OPT_HOST="[${WSREP_SST_OPT_HOST_UNESCAPED}]" + addr_no_bracket="${WSREP_SST_OPT_ADDR#\[}" # Some utilities and subsequent code require an address # without square brackets: + readonly WSREP_SST_OPT_HOST_UNESCAPED="${addr_no_bracket%%\]*}" + # Square brackets are needed in most cases: + readonly WSREP_SST_OPT_HOST="[${WSREP_SST_OPT_HOST_UNESCAPED}]" readonly WSREP_SST_OPT_HOST_ESCAPED="\\[${WSREP_SST_OPT_HOST_UNESCAPED}\\]" + # Mark this address as IPv6: readonly WSREP_SST_OPT_HOST_IPv6=1 ;; *) - readonly WSREP_SST_OPT_HOST=${WSREP_SST_OPT_ADDR%%[:/]*} - readonly WSREP_SST_OPT_HOST_UNESCAPED=$WSREP_SST_OPT_HOST - readonly WSREP_SST_OPT_HOST_ESCAPED=$WSREP_SST_OPT_HOST + readonly WSREP_SST_OPT_HOST="${WSREP_SST_OPT_ADDR%%[:/]*}" + readonly WSREP_SST_OPT_HOST_UNESCAPED="$WSREP_SST_OPT_HOST" + readonly WSREP_SST_OPT_HOST_ESCAPED="$WSREP_SST_OPT_HOST" readonly WSREP_SST_OPT_HOST_IPv6=0 ;; esac # Let's remove the leading part that contains the host address: - remain=${WSREP_SST_OPT_ADDR#${WSREP_SST_OPT_HOST_ESCAPED}} + remain="${WSREP_SST_OPT_ADDR#$WSREP_SST_OPT_HOST_ESCAPED}" # Let's remove the ":" character that separates the port number # from the hostname: - remain=${remain#:} + remain="${remain#:}" # Extract the port number from the address - all characters # up to "/" (if present): - readonly WSREP_SST_OPT_ADDR_PORT=${remain%%/*} + WSREP_SST_OPT_ADDR_PORT="${remain%%/*}" # If the "/" character is present, then the path is not empty: if [ "${remain#*/}" != "${remain}" ]; then # This operation removes everything up to the "/" character, # effectively removing the port number from the string: - readonly WSREP_SST_OPT_PATH=${remain#*/} + readonly WSREP_SST_OPT_PATH="${remain#*/}" else readonly WSREP_SST_OPT_PATH="" fi # The rest of the string is the same as the path (for now): - remain=${WSREP_SST_OPT_PATH} + remain="${WSREP_SST_OPT_PATH}" # If there is one more "/" in the string, then everything before # it will be the module name, otherwise the module name is empty: if [ "${remain%%/*}" != "${remain}" ]; then # This operation removes the tail after the very first # occurrence of the "/" character (inclusively): - readonly WSREP_SST_OPT_MODULE=${remain%%/*} + readonly WSREP_SST_OPT_MODULE="${remain%%/*}" else readonly WSREP_SST_OPT_MODULE="" fi # Remove the module name part from the string, which ends with "/": - remain=${WSREP_SST_OPT_PATH#*/} + remain="${WSREP_SST_OPT_PATH#*/}" # If the rest of the string does not match the original, then there # was something else besides the module name: if [ "$remain" != "${WSREP_SST_OPT_PATH}" ]; then # Extract the part that matches the LSN by removing all # characters starting from the very first "/": - readonly WSREP_SST_OPT_LSN=${remain%%/*} + readonly WSREP_SST_OPT_LSN="${remain%%/*}" # Exctract everything after the first occurrence of # the "/" character in the string: - remain=${remain#*/} + remain="${remain#*/}" # If the remainder does not match the original string, # then there is something else (the version number in # our case): @@ -107,7 +117,7 @@ case "$1" in # Let's extract the version number by removing the tail # after the very first occurence of the "/" character # (inclusively): - readonly WSREP_SST_OPT_SST_VER=${remain%%/*} + readonly WSREP_SST_OPT_SST_VER="${remain%%/*}" else readonly WSREP_SST_OPT_SST_VER="" fi @@ -121,23 +131,23 @@ case "$1" in WSREP_SST_OPT_BYPASS=1 ;; '--datadir') - readonly WSREP_SST_OPT_DATA="$2" + # Let's remove the trailing slash: + readonly WSREP_SST_OPT_DATA="${2%/}" shift ;; '--innodb-data-home-dir') - readonly INNODB_DATA_HOME_DIR_ARG="$2" + # Let's remove the trailing slash: + readonly INNODB_DATA_HOME_DIR="${2%/}" shift ;; '--innodb-log-group-home-dir') - readonly INNODB_LOG_GROUP_HOME_ARG="$2" + # Let's remove the trailing slash: + readonly INNODB_LOG_GROUP_HOME="${2%/}" shift ;; '--innodb-undo-directory') - readonly INNODB_UNDO_DIR_ARG="$2" - shift - ;; - '--log-bin') - readonly LOG_BIN_ARG="$2" + # Let's remove the trailing slash: + readonly INNODB_UNDO_DIR="${2%/}" shift ;; '--defaults-file') @@ -154,7 +164,28 @@ case "$1" in shift ;; '--host') - readonly WSREP_SST_OPT_HOST="$2" + case "$2" in + \[*) + # IPv6 + # Remove the starting and ending square brackets, if present: + addr_no_bracket="${2#\[}" + # Some utilities and subsequent code require an address + # without square brackets: + readonly WSREP_SST_OPT_HOST_UNESCAPED="${addr_no_bracket%%\]*}" + # Square brackets are needed in most cases: + readonly WSREP_SST_OPT_HOST="[${WSREP_SST_OPT_HOST_UNESCAPED}]" + readonly WSREP_SST_OPT_HOST_ESCAPED="\\[${WSREP_SST_OPT_HOST_UNESCAPED}\\]" + # Mark this address as IPv6: + readonly WSREP_SST_OPT_HOST_IPv6=1 + ;; + *) + readonly WSREP_SST_OPT_HOST="$2" + readonly WSREP_SST_OPT_HOST_UNESCAPED="$2" + readonly WSREP_SST_OPT_HOST_ESCAPED="$2" + readonly WSREP_SST_OPT_HOST_IPv6=0 + ;; + esac + WSREP_SST_OPT_ADDR="$WSREP_SST_OPT_HOST" shift ;; '--local-port') @@ -189,12 +220,16 @@ case "$1" in readonly WSREP_SST_OPT_GTID="$2" shift ;; - '--binlog') - WSREP_SST_OPT_BINLOG="$2" + '--binlog'|'--log-bin') + readonly WSREP_SST_OPT_BINLOG="$2" shift ;; - '--binlog-index') - WSREP_SST_OPT_BINLOG_INDEX="$2" + '--binlog-index'|'--log-bin-index') + readonly WSREP_SST_OPT_BINLOG_INDEX="$2" + shift + ;; + '--log-basename') + readonly WSREP_SST_OPT_LOG_BASENAME="$2" shift ;; '--gtid-domain-id') @@ -205,45 +240,114 @@ case "$1" in original_cmd="" shift while [ $# -gt 0 ]; do - option=${1%%=*} - if [[ "$option" != "--defaults-file" && \ - "$option" != "--defaults-extra-file" && \ - "$option" != "--defaults-group-suffix" && \ - "$option" != "--port" && \ - "$option" != "--socket" ]]; then - value=${1#*=} - if [ "$value" == "$1" ]; then - value="" - fi - case "$option" in - '--innodb-data-home-dir') - if [ -z "$INNODB_DATA_HOME_DIR_ARG" ]; then - readonly INNODB_DATA_HOME_DIR_ARG="$value" - fi - ;; - '--innodb-log-group-home-dir') - if [ -z "$INNODB_LOG_GROUP_HOME_ARG" ]; then - readonly INNODB_LOG_GROUP_HOME_ARG="$value" - fi - ;; - '--innodb-undo-directory') - if [ -z "$INNODB_UNDO_DIR_ARG" ]; then - readonly INNODB_UNDO_DIR_ARG="$value" - fi - ;; - '--log-bin') - if [ -z "$LOG_BIN_ARG" ]; then - readonly LOG_BIN_ARG="$value" - fi - ;; - esac - if [ -z "$original_cmd" ]; then - original_cmd="$1" - else - original_cmd="$original_cmd $1" - fi + # check if the argument is the short option + # (starting with "-" instead of "--"): + if [ "${1#--}" = "$1" -a "${1#-}" != "$1" ]; then + option="${1#-}" + value="" + # check that the option value follows the name, + # without a space: + if [ ${#option} -gt 1 ]; then + # let's separate the first character as the option name, + # and the subsequent characters consider its value: + value="${1#-?}" + option="${1%$value}" + # check that the option name consists of one letter + # and there are the following arguments: + elif [ ${#option} -eq 1 -a $# -gt 1 ]; then + # if the next argument does not start with a "-" character, + # then this is the value of the current option: + if [ "${2#-}" = "$2" ]; then + value="$2" + shift + fi + fi + shift + if [ "$option" = 'h' ]; then + if [ -z "$WSREP_SST_OPT_DATA" ]; then + MYSQLD_OPT_DATADIR="${value%/}" + fi + elif [ "$option" != 'u' -a \ + "$option" != 'P' ]; then + if [ -z "$original_cmd" ]; then + original_cmd="'-$option$value'" + else + original_cmd="$original_cmd '-$option$value'" + fi + fi + continue; fi - shift + option="${1%%=*}" + if [ "$option" != '--defaults-file' -a \ + "$option" != '--defaults-extra-file' -a \ + "$option" != '--defaults-group-suffix' -a \ + "$option" != '--user' -a \ + "$option" != '--port' -a \ + "$option" != '--socket' ]; then + value="${1#*=}" + if [ "$value" = "$1" ]; then + value="" + fi + # Let's fill in the variables containing important paths + # that might not have been passed through explicit parameters + # (+ removing the trailing slash in these paths). Many of these + # options are processed internally within scripts or passed + # explicitly to other programs, so we need to remove them + # from mysqld's argument list: + skip_mysqld_arg=0 + case "$option" in + '--innodb-data-home-dir') + if [ -z "$INNODB_DATA_HOME_DIR" ]; then + MYSQLD_OPT_INNODB_DATA_HOME_DIR="${value%/}" + fi + skip_mysqld_arg=1 + ;; + '--innodb-log-group-home-dir') + if [ -z "$INNODB_LOG_GROUP_HOME" ]; then + MYSQLD_OPT_INNODB_LOG_GROUP_HOME="${value%/}" + fi + skip_mysqld_arg=1 + ;; + '--innodb-undo-directory') + if [ -z "$INNODB_UNDO_DIR" ]; then + MYSQLD_OPT_INNODB_UNDO_DIR="${value%/}" + fi + skip_mysqld_arg=1 + ;; + '--log-bin') + if [ -z "$WSREP_SST_OPT_BINLOG" ]; then + MYSQLD_OPT_LOG_BIN="$value" + fi + skip_mysqld_arg=1 + ;; + '--log-bin-index') + if [ -z "$WSREP_SST_OPT_BINLOG_INDEX" ]; then + MYSQLD_OPT_LOG_BIN_INDEX="$value" + fi + skip_mysqld_arg=1 + ;; + '--log-basename') + if [ -z "$WSREP_SST_OPT_LOG_BASENAME" ]; then + MYSQLD_OPT_LOG_BASENAME="$value" + fi + skip_mysqld_arg=1 + ;; + '--datadir') + if [ -z "$WSREP_SST_OPT_DATA" ]; then + MYSQLD_OPT_DATADIR="${value%/}" + fi + skip_mysqld_arg=1 + ;; + esac + if [ $skip_mysqld_arg -eq 0 ]; then + if [ -z "$original_cmd" ]; then + original_cmd="'$1'" + else + original_cmd="$original_cmd '$1'" + fi + fi + fi + shift done readonly WSREP_SST_OPT_MYSQLD="$original_cmd" break @@ -256,20 +360,169 @@ esac shift done readonly WSREP_SST_OPT_BYPASS -readonly WSREP_SST_OPT_BINLOG -readonly WSREP_SST_OPT_BINLOG_INDEX - -if [ -n "${WSREP_SST_OPT_ADDR_PORT:-}" ]; then - if [ -n "${WSREP_SST_OPT_PORT:-}" ]; then - if [ "$WSREP_SST_OPT_PORT" != "$WSREP_SST_OPT_ADDR_PORT" ]; then - echo "WSREP_SST: [ERROR] port in --port=$WSREP_SST_OPT_PORT differs from port in --address=$WSREP_SST_OPT_ADDR" >&2 - exit 2 + +# The same argument can be present on the command line several +# times, in this case we must take its last value: +if [ -n "${MYSQLD_OPT_INNODB_DATA_HOME_DIR:-}" -a \ + -z "$INNODB_DATA_HOME_DIR" ]; then + readonly INNODB_DATA_HOME_DIR="$MYSQLD_OPT_INNODB_DATA_HOME_DIR" +fi +if [ -n "${MYSQLD_OPT_INNODB_LOG_GROUP_HOME:-}" -a \ + -z "$INNODB_LOG_GROUP_HOME" ]; then + readonly INNODB_LOG_GROUP_HOME="$MYSQLD_OPT_INNODB_LOG_GROUP_HOME" +fi +if [ -n "${MYSQLD_OPT_INNODB_UNDO_DIR:-}" -a \ + -z "$INNODB_UNDO_DIR" ]; then + readonly INNODB_UNDO_DIR="$MYSQLD_OPT_INNODB_UNDO_DIR" +fi +if [ -n "${MYSQLD_OPT_LOG_BIN:-}" -a \ + -z "$WSREP_SST_OPT_BINLOG" ]; then + readonly WSREP_SST_OPT_BINLOG="$MYSQLD_OPT_LOG_BIN" +fi +if [ -n "${MYSQLD_OPT_LOG_BIN_INDEX:-}" -a \ + -z "$WSREP_SST_OPT_BINLOG_INDEX" ]; then + readonly WSREP_SST_OPT_BINLOG_INDEX="$MYSQLD_OPT_LOG_BIN_INDEX" +fi +if [ -n "${MYSQLD_OPT_DATADIR:-}" -a \ + -z "$WSREP_SST_OPT_DATA" ]; then + readonly WSREP_SST_OPT_DATA="$MYSQLD_OPT_DATADIR" +fi +if [ -n "${MYSQLD_OPT_LOG_BASENAME:-}" -a \ + -z "$WSREP_SST_OPT_LOG_BASENAME" ]; then + readonly WSREP_SST_OPT_LOG_BASENAME="$MYSQLD_OPT_LOG_BASENAME" +fi + +# If the --log-bin option is present without a value, then +# setting WSREP_SST_OPT_BINLOG by using other arguments: +if [ -z "$WSREP_SST_OPT_BINLOG" -a -n "${MYSQLD_OPT_LOG_BIN+x}" ]; then + if [ -n "$WSREP_SST_OPT_LOG_BASENAME" ]; then + # If the WSREP_SST_OPT_BINLOG variable is not set, but + # --log-basename is present among the arguments to mysqld, + # then set WSREP_SST_OPT_BINLOG equal to the base name with + # the "-bin" suffix: + readonly WSREP_SST_OPT_BINLOG="$WSREP_SST_OPT_LOG_BASENAME-bin" + else + # Take the default name: + readonly WSREP_SST_OPT_BINLOG='mysql-bin' fi - else - readonly WSREP_SST_OPT_PORT="$WSREP_SST_OPT_ADDR_PORT" - fi fi +# Reconstructing the command line arguments that control the innodb +# and binlog options: +if [ -n "$WSREP_SST_OPT_LOG_BASENAME" ]; then + INNOEXTRA="$INNOEXTRA --log-basename='$WSREP_SST_OPT_LOG_BASENAME'" +fi +if [ -n "$INNODB_DATA_HOME_DIR" ]; then + INNOEXTRA="$INNOEXTRA --innodb-data-home-dir='$INNODB_DATA_HOME_DIR'" +fi +if [ -n "$INNODB_LOG_GROUP_HOME" ]; then + INNOEXTRA="$INNOEXTRA --innodb-log-group-home-dir='$INNODB_LOG_GROUP_HOME'" +fi +if [ -n "$INNODB_UNDO_DIR" ]; then + INNOEXTRA="$INNOEXTRA --innodb-undo-directory='$INNODB_UNDO_DIR'" +fi +if [ -n "$WSREP_SST_OPT_BINLOG" ]; then + INNOEXTRA="$INNOEXTRA --log-bin='$WSREP_SST_OPT_BINLOG'" + if [ -n "$WSREP_SST_OPT_BINLOG_INDEX" ]; then + INNOEXTRA="$INNOEXTRA --log-bin-index='$WSREP_SST_OPT_BINLOG_INDEX'" + fi +fi + +get_binlog() +{ + # if no command line argument and WSREP_SST_OPT_BINLOG is not set, + # try to get it from my.cnf: + if [ -z "$WSREP_SST_OPT_BINLOG" ]; then + WSREP_SST_OPT_BINLOG=$(parse_cnf '--mysqld' 'log-bin') + fi + # if no command line argument and WSREP_SST_OPT_BINLOG_INDEX is not set, + # try to get it from my.cnf: + if [ -z "$WSREP_SST_OPT_BINLOG_INDEX" ]; then + WSREP_SST_OPT_BINLOG_INDEX=$(parse_cnf '--mysqld' 'log-bin-index') + fi + # if no command line argument and WSREP_SST_OPT_LOG_BASENAME is not set, + # try to get it from my.cnf: + if [ -z "$WSREP_SST_OPT_LOG_BASENAME" ]; then + WSREP_SST_OPT_LOG_BASENAME=$(parse_cnf '--mysqld' 'log-basename') + fi + if [ -z "$WSREP_SST_OPT_BINLOG" ]; then + # If the --log-bin option is specified without a parameter, + # then we need to build the name of the index file according + # to the rules described in the server documentation: + if [ -n "${MYSQLD_OPT_LOG_BIN+x}" -o \ + $(in_config '--mysqld' 'log-bin') -eq 1 ] + then + if [ -n "$WSREP_SST_OPT_LOG_BASENAME" ]; then + # If the WSREP_SST_OPT_BINLOG variable is not set, but + # --log-basename is present among the arguments of mysqld, + # then set WSREP_SST_OPT_BINLOG equal to the base name with + # the "-bin" suffix: + readonly WSREP_SST_OPT_BINLOG="$WSREP_SST_OPT_LOG_BASENAME-bin" + else + # If the --log-bin option is present without a value, then + # we take the default name: + readonly WSREP_SST_OPT_BINLOG='mysql-bin' + fi + fi + fi + if [ -n "$WSREP_SST_OPT_BINLOG" ]; then + # If the name of the index file is not specified, then we will build + # it according to the specifications for the server: + if [ -z "$WSREP_SST_OPT_BINLOG_INDEX" ]; then + if [ -n "$WSREP_SST_OPT_LOG_BASENAME" ]; then + # If the WSREP_SST_OPT_BINLOG variable is not set, but + # --log-basename is present among the arguments of mysqld, + # then set WSREP_SST_OPT_BINLOG equal to the base name with + # the "-bin" suffix: + readonly WSREP_SST_OPT_BINLOG_INDEX="$WSREP_SST_OPT_LOG_BASENAME-bin.index" + else + # If the base name not specified, then we take + # the default name: + readonly WSREP_SST_OPT_BINLOG_INDEX='mysql-bin.index' + fi + fi + fi +} + +# Check the presence of the port value and, if necessary, transfer +# the port number from the address to the WSREP_SST_OPT_PORT variable +# or vice versa, and also, if necessary, substitute the missing port +# value into the address value: +if [ -n "$WSREP_SST_OPT_ADDR_PORT" ]; then + if [ -n "$WSREP_SST_OPT_PORT" ]; then + if [ "$WSREP_SST_OPT_PORT" != "$WSREP_SST_OPT_ADDR_PORT" ]; then + echo "WSREP_SST: [ERROR] port in --port=$WSREP_SST_OPT_PORT differs from port in --address=$WSREP_SST_OPT_ADDR" >&2 + exit 2 + fi + else + # If the address contains a port number, assign it to + # the corresponding variable: + readonly WSREP_SST_OPT_PORT="$WSREP_SST_OPT_ADDR_PORT" + fi +elif [ -n "$WSREP_SST_OPT_ADDR" ]; then + # If the port is missing, take the default port: + if [ -z "$WSREP_SST_OPT_PORT" ]; then + readonly WSREP_SST_OPT_PORT=4444 + fi + WSREP_SST_OPT_ADDR_PORT="$WSREP_SST_OPT_PORT" + # Let's remove the leading part that contains the host address: + remain="${WSREP_SST_OPT_ADDR#$WSREP_SST_OPT_HOST_ESCAPED}" + # Let's remove the ":" character that separates the port number + # from the hostname: + remain="${remain#:}" + # Let's remove all characters upto first "/" character that + # separates the hostname with port number from the path: + remain="${remain#/}" + # Let's construct a new value for the address with the port: + WSREP_SST_OPT_ADDR="$WSREP_SST_OPT_HOST:$WSREP_SST_OPT_PORT" + if [ -n "$remain" ]; then + WSREP_SST_OPT_ADDR="$WSREP_SST_OPT_ADDR/$remain" + fi +fi + +readonly WSREP_SST_OPT_ADDR +readonly WSREP_SST_OPT_ADDR_PORT + # try to use my_print_defaults, mysql and mysqldump that come with the sources # (for MTR suite) SCRIPTS_DIR="$(cd $(dirname "$0"); pwd -P)" @@ -279,13 +532,13 @@ CLIENT_DIR="$SCRIPTS_DIR/../client" if [ -x "$CLIENT_DIR/mysql" ]; then MYSQL_CLIENT="$CLIENT_DIR/mysql" else - MYSQL_CLIENT=$(which mysql) + MYSQL_CLIENT="$(command -v mysql)" fi if [ -x "$CLIENT_DIR/mysqldump" ]; then MYSQLDUMP="$CLIENT_DIR/mysqldump" else - MYSQLDUMP=$(which mysqldump) + MYSQLDUMP="$(command -v mysqldump)" fi if [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then @@ -293,7 +546,7 @@ if [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults" else - MY_PRINT_DEFAULTS=$(which my_print_defaults) + MY_PRINT_DEFAULTS="$(command -v my_print_defaults)" fi wsrep_defaults="$WSREP_SST_OPT_DEFAULT" @@ -307,29 +560,133 @@ fi readonly WSREP_SST_OPT_CONF="$wsrep_defaults$WSREP_SST_OPT_SUFFIX_DEFAULT" readonly MY_PRINT_DEFAULTS="$MY_PRINT_DEFAULTS $WSREP_SST_OPT_CONF" -wsrep_auth_not_set() +# +# User can specify mariabackup specific settings that will be used during sst +# process like encryption, etc. Parse such configuration option. +# +# 1st parameter: group (config file section like sst) or +# my_print_defaults argument (like --mysqld) +# 2nd parameter: var : name of the variable in the section, e.g. server-id +# 3rd parameter: default value for the parameter +# +parse_cnf() { - [ -z "$WSREP_SST_OPT_AUTH" -o "$WSREP_SST_OPT_AUTH" = "(null)" ] + local group="$1" + local var="$2" + local reval="" + + # normalize the variable names specified in cnf file (user can use _ or - for example log-bin or log_bin) + # then search for needed variable + # finally get the variable value (if variables has been specified multiple time use the last value only) + + if [ "$group" = '--mysqld' -o \ + "$group" = 'mysqld' ]; then + if [ -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then + reval=$($MY_PRINT_DEFAULTS "mysqld$WSREP_SST_OPT_SUFFIX_VALUE" | awk 'BEGIN {OFS=FS="="} {sub(/^--loose/,"-",$0); gsub(/_/,"-",$1); if ($1=="--'"$var"'") lastval=substr($0,length($1)+2)} END {print lastval}') + fi + fi + + if [ -z "$reval" ]; then + reval=$($MY_PRINT_DEFAULTS "$group" | awk 'BEGIN {OFS=FS="="} {sub(/^--loose/,"-",$0); gsub(/_/,"-",$1); if ($1=="--'"$var"'") lastval=substr($0,length($1)+2)} END {print lastval}') + fi + + # use default if we haven't found a value + if [ -z "$reval" ]; then + [ -n "${3:-}" ] && reval="$3" + fi + echo $reval } -# State Snapshot Transfer authentication password was displayed in the ps output. Bug fixed #1200727. -if $MY_PRINT_DEFAULTS sst | grep -q "wsrep_sst_auth"; then - if wsrep_auth_not_set; then - WSREP_SST_OPT_AUTH=$($MY_PRINT_DEFAULTS sst | grep -- "--wsrep_sst_auth" | cut -d= -f2) +# +# This function simply checks for the presence of the parameter +# in the config file, but does not return its value. It returns "1" +# (true) even if the parameter is present in the configuration file +# without a value: +# +in_config() +{ + local group="$1" + local var="$2" + local found=0 + if [ "$group" = '--mysqld' -o \ + "$group" = 'mysqld' ]; then + if [ -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then + found=$($MY_PRINT_DEFAULTS "mysqld$WSREP_SST_OPT_SUFFIX_VALUE" | awk 'BEGIN {OFS=FS="="; found=0} {sub(/^--loose/,"-",$0); gsub(/_/,"-",$1); if ($1=="--'"$var"'") found=1} END {print found}') + fi + fi + if [ $found -eq 0 ]; then + found=$($MY_PRINT_DEFAULTS "$group" | awk 'BEGIN {OFS=FS="="; found=0} {sub(/^--loose/,"-",$0); gsub(/_/,"-",$1); if ($1=="--'"$var"'") found=1} END {print found}') fi + echo $found +} + +wsrep_auth_not_set() +{ + [ -z "$WSREP_SST_OPT_AUTH" ] +} + +# Get rid of incorrect values resulting from substitution +# in programs external to the script: +if [ "$WSREP_SST_OPT_USER" = '(null)' ]; then + WSREP_SST_OPT_USER="" +fi +if [ "$WSREP_SST_OPT_PSWD" = '(null)' ]; then + WSREP_SST_OPT_PSWD="" +fi +if [ "$WSREP_SST_OPT_AUTH" = '(null)' ]; then + WSREP_SST_OPT_AUTH="" +fi + +# Let's read the value of the authentication string from the +# configuration file so that it does not go to the command line +# and does not appear in the ps output: +if wsrep_auth_not_set; then + WSREP_SST_OPT_AUTH=$(parse_cnf 'sst' 'wsrep-sst-auth') fi -readonly WSREP_SST_OPT_AUTH -# Splitting AUTH into potential user:password pair +# Splitting WSREP_SST_OPT_AUTH as "user:password" pair: if ! wsrep_auth_not_set then - WSREP_SST_OPT_USER="${WSREP_SST_OPT_AUTH%%:*}" - WSREP_SST_OPT_PSWD="${WSREP_SST_OPT_AUTH##*:}" + # Extract username as shortest prefix up to first ':' character: + WSREP_SST_OPT_AUTH_USER="${WSREP_SST_OPT_AUTH%%:*}" + if [ -z "$WSREP_SST_OPT_USER" ]; then + # if the username is not in the command line arguments, + # set the username and password using WSREP_SST_OPT_AUTH + # from the environment: + WSREP_SST_OPT_USER="$WSREP_SST_OPT_AUTH_USER" + WSREP_SST_OPT_PSWD="${WSREP_SST_OPT_AUTH#*:}" + elif [ "$WSREP_SST_OPT_USER" = "$WSREP_SST_OPT_AUTH_USER" ]; then + # If the username in the command line arguments and in + # the environment variable are the same, set the password + # if it was not specified in the command line: + if [ -z "$WSREP_SST_OPT_PSWD" ]; then + WSREP_SST_OPT_PSWD="${WSREP_SST_OPT_AUTH#*:}" + fi + else + # The username is passed through the command line and does + # not match the username in the environment variable - ignore + # the environment and rebuild the authentication parameters: + WSREP_SST_OPT_AUTH="$WSREP_SST_OPT_USER:$WSREP_SST_OPT_PSWD" + fi fi + readonly WSREP_SST_OPT_USER readonly WSREP_SST_OPT_PSWD +readonly WSREP_SST_OPT_AUTH + +if [ -n "$WSREP_SST_OPT_REMOTE_AUTH" ] +then + # Split auth string at the last ':' + readonly WSREP_SST_OPT_REMOTE_USER="${WSREP_SST_OPT_REMOTE_AUTH%%:*}" + readonly WSREP_SST_OPT_REMOTE_PSWD="${WSREP_SST_OPT_REMOTE_AUTH#*:}" +else + readonly WSREP_SST_OPT_REMOTE_USER= + readonly WSREP_SST_OPT_REMOTE_PSWD= +fi + +readonly WSREP_SST_OPT_REMOTE_AUTH -if [ -n "${WSREP_SST_OPT_DATA:-}" ] +if [ -n "$WSREP_SST_OPT_DATA" ] then SST_PROGRESS_FILE="$WSREP_SST_OPT_DATA/sst_in_progress" else @@ -361,15 +718,14 @@ wsrep_log_info() wsrep_cleanup_progress_file() { - [ -n "${SST_PROGRESS_FILE:-}" ] && rm -f "$SST_PROGRESS_FILE" 2>/dev/null || true + [ -n "$SST_PROGRESS_FILE" ] && rm -f "$SST_PROGRESS_FILE" 2>/dev/null || true } wsrep_check_program() { - local prog=$1 - - if ! which $prog >/dev/null - then + local prog="$1" + local cmd=$(command -v "$prog") + if [ ! -x "$cmd" ]; then echo "'$prog' not found in PATH" return 2 # no such file or directory fi @@ -388,29 +744,42 @@ wsrep_check_programs() return $ret } -# -# user can specify mariabackup specific settings that will be used during sst -# process like encryption, etc..... -# parse such configuration option. (group for xb settings is [sst] in my.cnf -# -# 1st param: group (config file section like sst) or my_print_defaults argument (like --mysqld) -# 2nd param: var : name of the variable in the section, e.g. server-id -# 3rd param: - : default value for the param -parse_cnf() +wsrep_check_datadir() { - local group=$1 - local var=$2 - local reval="" - - # normalize the variable names specified in cnf file (user can use _ or - for example log-bin or log_bin) - # then search for needed variable - # finally get the variable value (if variables has been specified multiple time use the last value only) + if [ -z "$WSREP_SST_OPT_DATA" ] + then + wsrep_log_error "The '--datadir' parameter must be passed to the SST script" + exit 2 + fi +} - reval=$($MY_PRINT_DEFAULTS "${group}" | awk -v var="${var}" 'BEGIN { OFS=FS="=" } { gsub(/_/,"-",$1); if ( $1=="--"var) lastval=substr($0,length($1)+2) } END { print lastval}') +get_openssl() +{ + # If the OPENSSL_BINARY variable is already defined, just return: + if [ -n "${OPENSSL_BINARY+x}" ]; then + return + fi + # Let's look for openssl: + OPENSSL_BINARY="$(command -v openssl)" + if [ ! -x "$OPENSSL_BINARY" ]; then + OPENSSL_BINARY='/usr/bin/openssl' + if [ ! -x "$OPENSSL_BINARY" ]; then + OPENSSL_BINARY="" + fi + fi + readonly OPENSSL_BINARY +} - # use default if we haven't found a value - if [ -z "$reval" ]; then - [ -n "$3" ] && reval=$3 +# Generate a string equivalent to 16 random bytes +wsrep_gen_secret() +{ + get_openssl + if [ -n "$OPENSSL_BINARY" ] + then + echo $("$OPENSSL_BINARY" rand -hex 16) + else + printf "%04x%04x%04x%04x%04x%04x%04x%04x" \ + $RANDOM $RANDOM $RANDOM $RANDOM \ + $RANDOM $RANDOM $RANDOM $RANDOM fi - echo $reval } diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index c9a990a661d..8b05217b2fa 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -1,6 +1,6 @@ #!/bin/bash -ue # Copyright (C) 2013 Percona Inc -# Copyright (C) 2017-2020 MariaDB +# Copyright (C) 2017-2021 MariaDB # # 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 @@ -21,6 +21,7 @@ # Make sure to read that before proceeding! . $(dirname $0)/wsrep_sst_common +wsrep_check_datadir OS=$(uname) ealgo="" @@ -37,6 +38,7 @@ REMOTEIP="" tcert="" tpem="" tkey="" +tmode="DISABLED" sockopt="" progress="" ttime=0 @@ -56,8 +58,6 @@ 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 " @@ -72,6 +72,8 @@ xtmpdir="" scomp="" sdecomp="" +readonly SECRET_TAG="secret" + # Required for backup locks # For backup locks it is 1 sent by joiner # 5.6.21 PXC and later can't donate to an older joiner @@ -84,29 +86,28 @@ pcmd="pv $pvopts" declare -a RC set +e -INNOBACKUPEX_BIN=$(which mariabackup) -if test -z $INNOBACKUPEX_BIN -then +MARIABACKUP_BIN="$(command -v mariabackup)" +if [ -z "$MARIABACKUP_BIN" ]; then wsrep_log_error 'mariabackup binary not found in $PATH' exit 42 fi set -e -XBSTREAM_BIN=mbstream +MBSTREAM_BIN=mbstream XBCRYPT_BIN=xbcrypt # Not available in MariaBackup DATA="${WSREP_SST_OPT_DATA}" INFO_FILE="xtrabackup_galera_info" IST_FILE="xtrabackup_ist" -MAGIC_FILE="${DATA}/${INFO_FILE}" -INNOAPPLYLOG="${DATA}/mariabackup.prepare.log" -INNOMOVELOG="${DATA}/mariabackup.move.log" -INNOBACKUPLOG="${DATA}/mariabackup.backup.log" +MAGIC_FILE="$DATA/$INFO_FILE" +INNOAPPLYLOG="$DATA/mariabackup.prepare.log" +INNOMOVELOG="$DATA/mariabackup.move.log" +INNOBACKUPLOG="$DATA/mariabackup.backup.log" # Setting the path for ss and ip export PATH="/usr/sbin:/sbin:$PATH" timeit(){ - local stage=$1 + local stage="$1" shift local cmd="$@" local x1 x2 took extcode @@ -131,18 +132,18 @@ timeit(){ get_keys() { # $encrypt -eq 1 is for internal purposes only - if [[ $encrypt -ge 2 || $encrypt -eq -1 ]];then + if [ $encrypt -ge 2 -o $encrypt -eq -1 ]; then return fi - if [[ $encrypt -eq 0 ]];then - if $MY_PRINT_DEFAULTS xtrabackup | grep -q encrypt;then + if [ $encrypt -eq 0 ]; then + if $MY_PRINT_DEFAULTS 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 + if [ $sfmt = 'tar' ]; then wsrep_log_info "NOTE: Xtrabackup-based encryption - encrypt=1 - cannot be enabled with tar format" encrypt=-1 return @@ -150,24 +151,24 @@ get_keys() wsrep_log_info "Xtrabackup based encryption enabled in my.cnf - Supported only from Xtrabackup 2.1.4" - if [[ -z $ealgo ]];then + 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 + if [ -z "$ekey" -a ! -r "$ekeyfile" ]; then wsrep_log_error "FATAL: Either key or keyfile must be readable" exit 3 fi - if [[ -z $ekey ]];then - ecmd="${XBCRYPT_BIN} --encrypt-algo=$ealgo --encrypt-key-file=$ekeyfile" + if [ -z "$ekey" ]; then + ecmd="$XBCRYPT_BIN --encrypt-algo='$ealgo' --encrypt-key-file='$ekeyfile'" else - ecmd="${XBCRYPT_BIN} --encrypt-algo=$ealgo --encrypt-key=$ekey" + ecmd="$XBCRYPT_BIN --encrypt-algo='$ealgo' --encrypt-key='$ekey'" fi - if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then - ecmd+=" -d" + if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then + ecmd="$ecmd -d" fi stagemsg+="-XB-Encrypted" @@ -175,33 +176,29 @@ get_keys() get_transfer() { - if [[ -z $SST_PORT ]];then - TSST_PORT=4444 - else - TSST_PORT=$SST_PORT - fi + TSST_PORT="$SST_PORT" - if [[ $tfmt == 'nc' ]];then + if [ $tfmt = 'nc' ]; then wsrep_check_programs nc wsrep_log_info "Using netcat as streamer" - if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then - if nc -h 2>&1 | grep -q ncat;then + if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then + if nc -h 2>&1 | grep -q ncat; then # Ncat - tcmd="nc -l ${TSST_PORT}" - elif nc -h 2>&1 | grep -qw -- '-d\>';then + tcmd="nc -l $TSST_PORT" + elif nc -h 2>&1 | grep -qw -- '-d\>'; then # Debian netcat - if [ $WSREP_SST_OPT_HOST_IPv6 -eq 1 ];then + if [ $WSREP_SST_OPT_HOST_IPv6 -eq 1 ]; then # When host is not explicitly specified (when only the port # is specified) netcat can only bind to an IPv4 address if # the "-6" option is not explicitly specified: - tcmd="nc -dl -6 ${TSST_PORT}" + tcmd="nc -dl -6 $TSST_PORT" else - tcmd="nc -dl ${TSST_PORT}" + tcmd="nc -dl $TSST_PORT" fi else # traditional netcat - tcmd="nc -l -p ${TSST_PORT}" + tcmd="nc -l -p $TSST_PORT" fi else # Check to see if netcat supports the '-N' flag. @@ -214,22 +211,22 @@ get_transfer() # tcmd_extra="" if nc -h 2>&1 | grep -qw -- -N; then - tcmd_extra+="-N" + tcmd_extra="-N" wsrep_log_info "Using nc -N" fi # netcat doesn't understand [] around IPv6 address - if nc -h 2>&1 | grep -q ncat;then + if nc -h 2>&1 | grep -q ncat; then # Ncat wsrep_log_info "Using Ncat as streamer" - tcmd="nc ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}" - elif nc -h 2>&1 | grep -qw -- '-d\>';then + tcmd="nc $tcmd_extra $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT" + elif nc -h 2>&1 | grep -qw -- '-d\>'; then # Debian netcat wsrep_log_info "Using Debian netcat as streamer" - tcmd="nc ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}" + tcmd="nc $tcmd_extra $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT" else # traditional netcat wsrep_log_info "Using traditional netcat as streamer" - tcmd="nc -q0 ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}" + tcmd="nc -q0 $tcmd_extra $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT" fi fi else @@ -242,72 +239,63 @@ get_transfer() exit 2 fi - if [[ $encrypt -eq 2 ]];then + if [ $encrypt -eq 2 ]; then wsrep_log_info "Using openssl based encryption with socat: with crt and pem" - if [[ -z $tpem || -z $tcert ]];then + if [ -z "$tpem" -o -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 + if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then wsrep_log_info "Decrypting with cert=${tpem}, cafile=${tcert}" - tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tpem},cafile=${tcert}${sockopt} stdio" + tcmd="socat -u openssl-listen:$TSST_PORT,reuseaddr,cert='$tpem',cafile='$tcert'$sockopt stdio" else wsrep_log_info "Encrypting with cert=${tpem}, cafile=${tcert}" - tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${tpem},cafile=${tcert}${sockopt}" + tcmd="socat -u stdio openssl-connect:$REMOTEIP:$TSST_PORT,cert='$tpem',cafile='$tcert'$sockopt" fi - elif [[ $encrypt -eq 3 ]];then + elif [ $encrypt -eq 3 ]; then wsrep_log_info "Using openssl based encryption with socat: with key and crt" - if [[ -z $tpem || -z $tkey ]];then + if [ -z "$tpem" -o -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 - if [[ -z $tcert ]];then + if [ -z "$tcert" ]; then + # no verification + if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, verify=0" - tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tpem},key=${tkey},verify=0${sockopt} stdio" + tcmd="socat -u openssl-listen:$TSST_PORT,reuseaddr,cert='$tpem',key='$tkey',verify=0$sockopt stdio" else - wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}" - tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tpem},key=${tkey},cafile=${tcert}${sockopt} stdio" + wsrep_log_info "Encrypting with cert=${tpem}, key=${tkey}, verify=0" + tcmd="socat -u stdio openssl-connect:$REMOTEIP:$TSST_PORT,cert='$tpem',key='$tkey',verify=0$sockopt" fi else - if [[ -z $tcert ]];then - wsrep_log_info "Encrypting with cert=${tpem}, key=${tkey}, verify=0" - tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${tpem},key=${tkey},verify=0${sockopt}" + # CA verification + if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then + wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}" + tcmd="socat -u openssl-listen:$TSST_PORT,reuseaddr,cert='$tpem',key='$tkey',cafile='$tcert'$sockopt stdio" else + CN_option="" + if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then + CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'" + fi wsrep_log_info "Encrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}" - tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${tpem},key=${tkey},cafile=${tcert}${sockopt}" + tcmd="socat -u stdio openssl-connect:$REMOTEIP:$TSST_PORT,cert='$tpem',key='$tkey',cafile='$tcert'$CN_option$sockopt" fi fi else - if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then - tcmd="socat -u TCP-LISTEN:${TSST_PORT},reuseaddr${sockopt} stdio" + 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}" + tcmd="socat -u stdio TCP:$REMOTEIP:$TSST_PORT$sockopt" fi fi fi } -parse_cnf() -{ - local group=$1 - local var=$2 - # print the default settings for given group using my_print_default. - # normalize the variable names specified in cnf file (user can use _ or - for example log-bin or log_bin) - # then grep for needed variable - # finally get the variable value (if variables has been specified multiple time use the last value only) - reval=$($MY_PRINT_DEFAULTS $group | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2- | tail -1) - if [[ -z $reval ]];then - [[ -n $3 ]] && reval=$3 - fi - echo $reval -} - get_footprint() { - pushd $WSREP_SST_OPT_DATA 1>/dev/null + pushd "$WSREP_SST_OPT_DATA" 1>/dev/null payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c | awk 'END { print $1 }') if $MY_PRINT_DEFAULTS xtrabackup | grep -q -- "--compress";then # QuickLZ has around 50% compression ratio @@ -321,7 +309,7 @@ get_footprint() adjust_progress() { - if ! command -v pv >/dev/null;then + if [ ! -x "$(command -v pv)" ]; then wsrep_log_error "pv not found in path: $PATH" wsrep_log_error "Disabling all progress/rate-limiting" pcmd="" @@ -330,50 +318,94 @@ adjust_progress() return fi - if [[ -n $progress && $progress != '1' ]];then - if [[ -e $progress ]];then - pcmd+=" 2>>$progress" + if [ -n "$progress" -a "$progress" != '1' ]; then + if [ -e "$progress" ]; then + pcmd+=" 2>>'$progress'" else - pcmd+=" 2>$progress" + pcmd+=" 2>'$progress'" fi - elif [[ -z $progress && -n $rlimit ]];then + elif [ -z "$progress" -a -n "$rlimit" ]; then # When rlimit is non-zero pcmd="pv -q" fi - if [[ -n $rlimit && "$WSREP_SST_OPT_ROLE" == "donor" ]];then + if [ -n "$rlimit" -a "$WSREP_SST_OPT_ROLE" = 'donor' ]; then wsrep_log_info "Rate-limiting SST to $rlimit" pcmd+=" -L \$rlimit" fi } +check_server_ssl_config() +{ + local section="$1" + tcert=$(parse_cnf "$section" 'ssl-ca') + tpem=$(parse_cnf "$section" 'ssl-cert') + tkey=$(parse_cnf "$section" 'ssl-key') +} + read_cnf() { - sfmt=$(parse_cnf sst streamfmt "xbstream") + sfmt=$(parse_cnf sst streamfmt "mbstream") 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) + + encrypt=$(parse_cnf 'sst' 'encrypt' 0) + tmode=$(parse_cnf 'sst' 'ssl-mode' 'DISABLED' | tr [:lower:] [:upper:]) + + if [ $encrypt -eq 0 -o $encrypt -ge 2 ] + then + if [ "$tmode" != 'DISABLED' -o $encrypt -ge 2 ] + then + tcert=$(parse_cnf 'sst' 'tca') + tpem=$(parse_cnf 'sst' 'tcert') + tkey=$(parse_cnf 'sst' 'tkey') + fi + if [ "$tmode" != 'DISABLED' ] + then # backward-incompatible behavior + if [ -z "$tpem" -a -z "$tkey" -a -z "$tcert" ] + then # no old-style SSL config in [sst] + check_server_ssl_config 'sst' + if [ -z "$tpem" -a -z "$tkey" -a -z "$tcert" ] + then # no new-stype SSL config in [sst], try server-wide SSL config + check_server_ssl_config '--mysqld' + fi + fi + if [ 0 -eq $encrypt -a -n "$tpem" -a -n "$tkey" ] + then + encrypt=3 # enable cert/key SSL encyption + + # avoid CA verification if not set explicitly: + # nodes may happen to have different CA if self-generated + # zeroing up tcert does the trick + local mode=$(parse_cnf 'sst' 'ssl-mode') + [ "${tmode#VERIFY}" != "$tmode" ] || tcert="" + fi + fi + fi + + if [ $encrypt -eq 1 ]; then + # Refer to http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html + ealgo=$(parse_cnf xtrabackup encrypt "") + if [ -z "$ealgo" ]; then + ealgo=$(parse_cnf sst encrypt-algo "") + ekey=$(parse_cnf sst encrypt-key "") + ekeyfile=$(parse_cnf sst encrypt-key-file "") + else + ekey=$(parse_cnf xtrabackup encrypt-key "") + ekeyfile=$(parse_cnf xtrabackup encrypt-key-file "") + fi + fi + + wsrep_log_info "SSL configuration: CA='"$tcert"', CERT='"$tpem"'," \ + "KEY='"$tkey"', MODE='"$tmode"', encrypt="$encrypt + 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$\|.*\.sst$\|.*gvwstate\.dat$\|.*grastate\.dat$\|.*\.err$\|.*\.log$\|.*RPM_UPGRADE_MARKER$\|.*RPM_UPGRADE_HISTORY$') [[ $OS == "FreeBSD" ]] && cpat=$(parse_cnf sst cpat '.*galera\.cache$|.*sst_in_progress$|.*\.sst$|.*gvwstate\.dat$|.*grastate\.dat$|.*\.err$|.*\.log$|.*RPM_UPGRADE_MARKER$|.*RPM_UPGRADE_HISTORY$') - 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) @@ -393,7 +425,7 @@ read_cnf() fi if [[ $ssyslog -ne -1 ]];then - if $MY_PRINT_DEFAULTS mysqld_safe | tr '_' '-' | grep -q -- "--syslog";then + if $MY_PRINT_DEFAULTS mysqld_safe | grep -q -- "--syslog";then ssyslog=1 fi fi @@ -407,20 +439,20 @@ read_cnf() get_stream() { - if [[ $sfmt == 'mbstream' || $sfmt == 'xbstream' ]];then + if [ "$sfmt" = 'mbstream' -o "$sfmt" = 'xbstream' ]; then wsrep_log_info "Streaming with ${sfmt}" - if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then - strmcmd="${XBSTREAM_BIN} -x" + if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then + strmcmd="$MBSTREAM_BIN -x" else - strmcmd="${XBSTREAM_BIN} -c \${INFO_FILE}" + strmcmd="$MBSTREAM_BIN -c '$INFO_FILE'" fi else sfmt="tar" wsrep_log_info "Streaming with tar" - if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then - strmcmd="tar xfi - " + if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]]; then + strmcmd="tar xfi -" else - strmcmd="tar cf - \${INFO_FILE} " + strmcmd="tar cf - '$INFO_FILE'" fi fi } @@ -443,19 +475,19 @@ cleanup_joiner() { # Since this is invoked just after exit NNN local estatus=$? - if [[ $estatus -ne 0 ]];then + if [ $estatus -ne 0 ]; then wsrep_log_error "Cleanup after exit with status:$estatus" - elif [ "${WSREP_SST_OPT_ROLE}" = "joiner" ];then + elif [ "${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 + if [ -n "$progress" -a -p "$progress" ]; then wsrep_log_info "Cleaning up fifo file $progress" - rm $progress + rm "$progress" fi - if [[ -n ${STATDIR:-} ]];then - [[ -d $STATDIR ]] && rm -rf $STATDIR + if [ -n "$STATDIR" ]; then + [ -d "$STATDIR" ] && rm -rf "$STATDIR" fi # Final cleanup @@ -484,11 +516,11 @@ cleanup_donor() { # Since this is invoked just after exit NNN local estatus=$? - if [[ $estatus -ne 0 ]];then + if [ $estatus -ne 0 ]; then wsrep_log_error "Cleanup after exit with status:$estatus" fi - if [[ -n ${XTRABACKUP_PID:-} ]];then + if [ -n "$XTRABACKUP_PID" ]; then if check_pid $XTRABACKUP_PID then wsrep_log_error "xtrabackup process is still running. Killing..." @@ -496,21 +528,21 @@ cleanup_donor() fi fi - rm -f ${DATA}/${IST_FILE} || true + rm -f "$DATA/$IST_FILE" || true - if [[ -n $progress && -p $progress ]];then + if [ -n "$progress" -a -p "$progress" ]; then wsrep_log_info "Cleaning up fifo file $progress" - rm -f $progress || true + rm -f "$progress" || true fi wsrep_log_info "Cleaning up temporary directories" - if [[ -n $xtmpdir ]];then - [[ -d $xtmpdir ]] && rm -rf $xtmpdir || true + if [ -n "$xtmpdir" ]; then + [ -d "$xtmpdir" ] && rm -rf "$xtmpdir" || true fi - if [[ -n $itmpdir ]];then - [[ -d $itmpdir ]] && rm -rf $itmpdir || true + if [ -n "$itmpdir" ]; then + [ -d "$itmpdir" ] && rm -rf "$itmpdir" || true fi # Final cleanup @@ -531,7 +563,7 @@ cleanup_donor() kill_xtrabackup() { - local PID=$(cat $XTRABACKUP_PID) + local PID=$(cat "$XTRABACKUP_PID") [ -n "$PID" -a "0" != "$PID" ] && kill $PID && (kill $PID && kill -9 $PID) || : wsrep_log_info "Removing xtrabackup pid file $XTRABACKUP_PID" rm -f "$XTRABACKUP_PID" || true @@ -539,11 +571,11 @@ kill_xtrabackup() setup_ports() { - SST_PORT=${WSREP_SST_OPT_ADDR_PORT} - if [[ "$WSREP_SST_OPT_ROLE" == "donor" ]];then - REMOTEIP=${WSREP_SST_OPT_HOST} - lsn=${WSREP_SST_OPT_LSN} - sst_ver=${WSREP_SST_OPT_SST_VER} + SST_PORT="$WSREP_SST_OPT_PORT" + if [ "$WSREP_SST_OPT_ROLE" = "donor" ]; then + REMOTEIP="${WSREP_SST_OPT_HOST}" + lsn="${WSREP_SST_OPT_LSN}" + sst_ver="${WSREP_SST_OPT_SST_VER}" fi } @@ -551,9 +583,9 @@ setup_ports() # (regardless of timeout) wait_for_listen() { - local PORT=$1 - local ADDR=$2 - local MODULE=$3 + local PORT="$1" + local ADDR="$2" + local MODULE="$3" for i in {1..50} do if [ "$OS" = "FreeBSD" ];then @@ -569,10 +601,11 @@ wait_for_listen() check_extra() { local use_socket=1 - if [[ $uextra -eq 1 ]];then - if $MY_PRINT_DEFAULTS --mysqld | tr '_' '-' | grep -- "--thread-handling=" | grep -q 'pool-of-threads';then - local eport=$($MY_PRINT_DEFAULTS --mysqld | tr '_' '-' | grep -- "--extra-port=" | cut -d= -f2) - if [[ -n $eport ]];then + if [ $uextra -eq 1 ]; then + local thread_handling=$(parse_cnf '--mysqld' 'thread-handling') + if [ "$thread_handling" = 'pool-of-threads' ]; then + local eport=$(parse_cnf '--mysqld' 'extra-port') + 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" @@ -586,29 +619,29 @@ check_extra() 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" + if [ $use_socket -eq 1 -a -n "$WSREP_SST_OPT_SOCKET" ]; then + INNOEXTRA+=" --socket='$WSREP_SST_OPT_SOCKET'" fi } recv_joiner() { - local dir=$1 - local msg=$2 + local dir="$1" + local msg="$2" local tmt=$3 local checkf=$4 local ltcmd - if [[ ! -d ${dir} ]];then + if [ ! -d "$dir" ]; then # This indicates that IST is in progress return fi - pushd ${dir} 1>/dev/null + pushd "$dir" 1>/dev/null set +e - if [[ $tmt -gt 0 ]] && command -v timeout >/dev/null;then - if timeout --help | grep -q -- '-k';then + if [ $tmt -gt 0 -a -x "$(command -v timeout)" ]; then + if timeout --help | grep -q -- '-k'; then ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd" else ltcmd="timeout -s9 $tmt $tcmd" @@ -622,7 +655,7 @@ recv_joiner() popd 1>/dev/null if [[ ${RC[0]} -eq 124 ]];then - wsrep_log_error "Possible timeout in receiving first data from " + wsrep_log_error "Possible timeout in receiving first data from " \ "donor in gtid stage: exit codes: ${RC[@]}" exit 32 fi @@ -635,21 +668,36 @@ recv_joiner() fi done - if [[ $checkf -eq 1 && ! -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 + if [ $checkf -eq 1 ]; then + if [ ! -r "$MAGIC_FILE" ]; then + # this message should cause joiner to abort + wsrep_log_error "receiving process ended without creating " \ + "'${MAGIC_FILE}'" + wsrep_log_info "Contents of datadir" + wsrep_log_info "$(ls -l ${dir}/*)" + exit 32 + fi + + # check donor supplied secret + SECRET=$(grep "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2) + if [ "$SECRET" != "$MY_SECRET" ]; then + wsrep_log_error "Donor does not know my secret!" + wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'" + exit 32 + fi + + # remove secret from magic file + grep -v "$SECRET_TAG " "$MAGIC_FILE" > "$MAGIC_FILE.new" + mv "$MAGIC_FILE.new" "$MAGIC_FILE" fi } send_donor() { - local dir=$1 - local msg=$2 + local dir="$1" + local msg="$2" - pushd ${dir} 1>/dev/null + pushd "$dir" 1>/dev/null set +e timeit "$msg" "$strmcmd | $tcmd; RC=( "\${PIPESTATUS[@]}" )" set -e @@ -657,7 +705,7 @@ send_donor() for ecode in "${RC[@]}";do if [[ $ecode -ne 0 ]];then - wsrep_log_error "Error while getting data from donor node: " \ + wsrep_log_error "Error while sending data to joiner node: " \ "exit codes: ${RC[@]}" exit 32 fi @@ -680,11 +728,11 @@ monitor_process() done } -wsrep_check_programs "$INNOBACKUPEX_BIN" +wsrep_check_programs "$MARIABACKUP_BIN" rm -f "${MAGIC_FILE}" -if [[ ! ${WSREP_SST_OPT_ROLE} == 'joiner' && ! ${WSREP_SST_OPT_ROLE} == 'donor' ]];then +if [ "$WSREP_SST_OPT_ROLE" != 'joiner' -a "$WSREP_SST_OPT_ROLE" != 'donor' ]; then wsrep_log_error "Invalid role ${WSREP_SST_OPT_ROLE}" exit 22 fi @@ -692,68 +740,59 @@ fi read_cnf setup_ports -if ${INNOBACKUPEX_BIN} /tmp --help 2>/dev/null | grep -q -- '--version-check'; then - disver="--no-version-check" +if "${MARIABACKUP_BIN}" --help 2>/dev/null | grep -q -- '--version-check'; then + disver='--no-version-check' fi -iopts+=" --databases-exclude=\"lost+found\"" +iopts+=" --databases-exclude='lost+found'" -if [[ ${FORCE_FTWRL:-0} -eq 1 ]];then +if [ ${FORCE_FTWRL:-0} -eq 1 ]; then wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL" - iopts+=" --no-backup-locks" + iopts+=' --no-backup-locks' fi -INNOEXTRA=$WSREP_SST_OPT_MYSQLD - -INNODB_DATA_HOME_DIR=${INNODB_DATA_HOME_DIR:-""} -# Try to set INNODB_DATA_HOME_DIR from the command line: -if [ ! -z "$INNODB_DATA_HOME_DIR_ARG" ]; then - INNODB_DATA_HOME_DIR=$INNODB_DATA_HOME_DIR_ARG -fi -# if no command line arg and INNODB_DATA_HOME_DIR environment variable +# if no command line argument and INNODB_DATA_HOME_DIR environment variable # is not set, try to get it from my.cnf: if [ -z "$INNODB_DATA_HOME_DIR" ]; then - INNODB_DATA_HOME_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-data-home-dir '') -fi -if [ -z "$INNODB_DATA_HOME_DIR" ]; then - INNODB_DATA_HOME_DIR=$(parse_cnf --mysqld innodb-data-home-dir '') -fi -if [ ! -z "$INNODB_DATA_HOME_DIR" ]; then - INNOEXTRA+=" --innodb-data-home-dir=$INNODB_DATA_HOME_DIR" + INNODB_DATA_HOME_DIR=$(parse_cnf '--mysqld' 'innodb-data-home-dir') fi +OLD_PWD="$(pwd)" + if [ -n "$INNODB_DATA_HOME_DIR" ]; then # handle both relative and absolute paths - INNODB_DATA_HOME_DIR=$(cd $DATA; mkdir -p "$INNODB_DATA_HOME_DIR"; cd $INNODB_DATA_HOME_DIR; pwd -P) + INNODB_DATA_HOME_DIR=$(cd "$DATA"; mkdir -p "$INNODB_DATA_HOME_DIR"; cd "$INNODB_DATA_HOME_DIR"; pwd -P) else # default to datadir - INNODB_DATA_HOME_DIR=$(cd $DATA; pwd -P) + INNODB_DATA_HOME_DIR=$(cd "$DATA"; pwd -P) fi +cd "$OLD_PWD" + if [[ $ssyslog -eq 1 ]];then - if ! command -v logger >/dev/null;then + if [ ! -x "$(command -v logger)" ]; then wsrep_log_error "logger not in path: $PATH. Ignoring" else - wsrep_log_info "Logging all stderr of SST/Innobackupex to syslog" + wsrep_log_info "Logging all stderr of SST/mariabackup to syslog" exec 2> >(logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE) wsrep_log_error() { - logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" + logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" } wsrep_log_info() { - logger -p daemon.info -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" + logger -p daemon.info -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" } - - INNOAPPLY="${INNOBACKUPEX_BIN} --prepare $disver $iapts \$INNOEXTRA $rebuildcmd --target-dir=\${DATA} 2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply" - INNOMOVE="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} --move-back $disver $impts --force-non-empty-directories --target-dir=\${DATA} 2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move" - INNOBACKUP="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} --backup $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt --target-dir=\$itmpdir 2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)" fi + INNOAPPLY="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply" + INNOMOVE="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move" + INNOBACKUP="2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)" + else if [[ "$sstlogarchive" -eq 1 ]] @@ -761,62 +800,71 @@ then ARCHIVETIMESTAMP=$(date "+%Y.%m.%d-%H.%M.%S.%N") newfile="" - if [[ ! -z "$sstlogarchivedir" ]] + if [ -n "$sstlogarchivedir" ] then - if [[ ! -d "$sstlogarchivedir" ]] + if [ ! -d "$sstlogarchivedir" ] then mkdir -p "$sstlogarchivedir" fi fi - if [ -e "${INNOAPPLYLOG}" ] + if [ -e "$INNOAPPLYLOG" ] then - if [[ ! -z "$sstlogarchivedir" ]] + if [ -n "$sstlogarchivedir" ] then - newfile=$sstlogarchivedir/$(basename "${INNOAPPLYLOG}").${ARCHIVETIMESTAMP} + newfile="$sstlogarchivedir/$(basename '$INNOAPPLYLOG').$ARCHIVETIMESTAMP" else - newfile=${INNOAPPLYLOG}.${ARCHIVETIMESTAMP} + newfile="$INNOAPPLYLOG.$ARCHIVETIMESTAMP" fi wsrep_log_info "Moving ${INNOAPPLYLOG} to ${newfile}" - mv "${INNOAPPLYLOG}" "${newfile}" - gzip "${newfile}" + mv "$INNOAPPLYLOG" "$newfile" + gzip "$newfile" fi - if [ -e "${INNOMOVELOG}" ] + if [ -e "$INNOMOVELOG" ] then - if [[ ! -z "$sstlogarchivedir" ]] + if [ -n "$sstlogarchivedir" ] then - newfile=$sstlogarchivedir/$(basename "${INNOMOVELOG}").${ARCHIVETIMESTAMP} + newfile="$sstlogarchivedir/$(basename '$INNOMOVELOG').$ARCHIVETIMESTAMP" else - newfile=${INNOMOVELOG}.${ARCHIVETIMESTAMP} + newfile="$INNOMOVELOG.$ARCHIVETIMESTAMP" fi - wsrep_log_info "Moving ${INNOMOVELOG} to ${newfile}" - mv "${INNOMOVELOG}" "${newfile}" - gzip "${newfile}" + mv "$INNOMOVELOG" "$newfile" + gzip "$newfile" fi - if [ -e "${INNOBACKUPLOG}" ] + if [ -e "$INNOBACKUPLOG" ] then - if [[ ! -z "$sstlogarchivedir" ]] + if [ -n "$sstlogarchivedir" ] then - newfile=$sstlogarchivedir/$(basename "${INNOBACKUPLOG}").${ARCHIVETIMESTAMP} + newfile="$sstlogarchivedir/$(basename '$INNOBACKUPLOG').$ARCHIVETIMESTAMP" else - newfile=${INNOBACKUPLOG}.${ARCHIVETIMESTAMP} + newfile="$INNOBACKUPLOG.$ARCHIVETIMESTAMP" fi - wsrep_log_info "Moving ${INNOBACKUPLOG} to ${newfile}" - mv "${INNOBACKUPLOG}" "${newfile}" - gzip "${newfile}" + mv "$INNOBACKUPLOG" "$newfile" + gzip "$newfile" fi fi - INNOAPPLY="${INNOBACKUPEX_BIN} --prepare $disver $iapts \$INNOEXTRA $rebuildcmd --target-dir=\${DATA} &> ${INNOAPPLYLOG}" - INNOMOVE="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} --move-back $disver $impts --force-non-empty-directories --target-dir=\${DATA} &> ${INNOMOVELOG}" - INNOBACKUP="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} --backup $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt --target-dir=\$itmpdir 2> ${INNOBACKUPLOG}" + INNOAPPLY="&> '$INNOAPPLYLOG'" + INNOMOVE="&> '$INNOMOVELOG'" + INNOBACKUP="2> '$INNOBACKUPLOG'" fi +setup_commands() +{ + local mysqld_args="" + if [ -n "$WSREP_SST_OPT_MYSQLD" ]; then + mysqld_args="--mysqld-args $WSREP_SST_OPT_MYSQLD" + fi + INNOAPPLY="$MARIABACKUP_BIN --prepare $disver $iapts $INNOEXTRA --target-dir='$DATA' --datadir='$DATA' $mysqld_args $INNOAPPLY" + INNOMOVE="$MARIABACKUP_BIN $WSREP_SST_OPT_CONF --move-back $disver $impts --force-non-empty-directories --target-dir='$DATA' --datadir='${TDATA:-$DATA}' $INNOMOVE" + INNOBACKUP="$MARIABACKUP_BIN $WSREP_SST_OPT_CONF --backup $disver $iopts $tmpopts $INNOEXTRA --galera-info --stream='$sfmt' --target-dir='$itmpdir' --datadir='$DATA' $mysqld_args $INNOBACKUP" +} + get_stream get_transfer @@ -827,71 +875,66 @@ then if [ $WSREP_SST_OPT_BYPASS -eq 0 ] then usrst=0 - if [[ -z $sst_ver ]];then + if [ -z "$sst_ver" ]; then wsrep_log_error "Upgrade joiner to 5.6.21 or higher for backup locks support" wsrep_log_error "The joiner is not supported for this version of donor" exit 93 fi - if [[ -z $(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE tmpdir "") && \ - -z $(parse_cnf --mysqld tmpdir "") && \ - -z $(parse_cnf xtrabackup tmpdir "") ]]; then + if [ -z "$(parse_cnf --mysqld tmpdir)" -a \ + -z "$(parse_cnf xtrabackup tmpdir)" ]; then xtmpdir=$(mktemp -d) - tmpopts="--tmpdir=$xtmpdir" + tmpopts="--tmpdir='$xtmpdir'" wsrep_log_info "Using $xtmpdir as xtrabackup temporary directory" fi itmpdir=$(mktemp -d) - wsrep_log_info "Using $itmpdir as innobackupex temporary directory" + wsrep_log_info "Using $itmpdir as mariabackup temporary directory" - if [[ -n "${WSREP_SST_OPT_USER:-}" && "$WSREP_SST_OPT_USER" != "(null)" ]]; then - INNOEXTRA+=" --user=$WSREP_SST_OPT_USER" + if [ -n "$WSREP_SST_OPT_USER" ]; then + INNOEXTRA+=" --user='$WSREP_SST_OPT_USER'" usrst=1 fi - if [ -n "${WSREP_SST_OPT_PSWD:-}" ]; then - export MYSQL_PWD=$WSREP_SST_OPT_PSWD - elif [[ $usrst -eq 1 ]];then + if [ -n "$WSREP_SST_OPT_PSWD" ]; then + export MYSQL_PWD="$WSREP_SST_OPT_PSWD" + elif [ $usrst -eq 1 ]; then # Empty password, used for testing, debugging etc. unset MYSQL_PWD 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 - check_extra wsrep_log_info "Streaming GTID file before SST" # Store donor's wsrep GTID (state ID) and wsrep_gtid_domain_id # (separated by a space). - echo "${WSREP_SST_OPT_GTID} ${WSREP_SST_OPT_GTID_DOMAIN_ID}" > "${MAGIC_FILE}" + echo "$WSREP_SST_OPT_GTID $WSREP_SST_OPT_GTID_DOMAIN_ID" > "$MAGIC_FILE" + + if [ -n "$WSREP_SST_OPT_REMOTE_PSWD" ]; then + # Let joiner know that we know its secret + echo "$SECRET_TAG $WSREP_SST_OPT_REMOTE_PSWD" >> "$MAGIC_FILE" + fi 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 " + if [ -n "$scomp" ]; then + tcmd="$scomp | $tcmd" + fi + + get_keys + if [ $encrypt -eq 1 ]; then + tcmd="$ecmd | $tcmd" fi - send_donor $DATA "${stagemsg}-gtid" + send_donor "$DATA" "${stagemsg}-gtid" tcmd="$ttcmd" - if [[ -n $progress ]];then + + if [ -n "$progress" ]; then get_footprint tcmd="$pcmd | $tcmd" - elif [[ -n $rlimit ]];then + elif [ -n "$rlimit" ]; then adjust_progress tcmd="$pcmd | $tcmd" fi @@ -899,26 +942,27 @@ then wsrep_log_info "Sleeping before data transfer for SST" sleep 10 - wsrep_log_info "Streaming the backup to joiner at ${REMOTEIP} ${SST_PORT:-4444}" + wsrep_log_info "Streaming the backup to joiner at ${REMOTEIP}:${SST_PORT}" - if [[ -n $scomp ]];then + if [ -n "$scomp" ]; then tcmd="$scomp | $tcmd" fi + setup_commands 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 syslog or ${INNOBACKUPLOG} for details" - exit 22 - elif [[ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]];then - wsrep_log_error "$tcmd finished with error: ${RC[1]}" - exit 22 + wsrep_log_error "${MARIABACKUP_BIN} finished with error: ${RC[0]}. " \ + "Check syslog or ${INNOBACKUPLOG} for details" + 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 $xtmpdir + # mariabackup implicitly writes PID to fixed location in $xtmpdir XTRABACKUP_PID="$xtmpdir/xtrabackup_pid" else # BYPASS FOR IST @@ -928,21 +972,21 @@ then # Store donor's wsrep GTID (state ID) and wsrep_gtid_domain_id # (separated by a space). - echo "${WSREP_SST_OPT_GTID} ${WSREP_SST_OPT_GTID_DOMAIN_ID}" > "${MAGIC_FILE}" - echo "1" > "${DATA}/${IST_FILE}" + echo "$WSREP_SST_OPT_GTID $WSREP_SST_OPT_GTID_DOMAIN_ID" > "$MAGIC_FILE" + echo "1" > "$DATA/$IST_FILE" + + if [ -n "$scomp" ]; then + tcmd="$scomp | $tcmd" + fi + 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 " + if [ $encrypt -eq 1 ]; then + tcmd="$ecmd | $tcmd" fi - strmcmd+=" \${IST_FILE}" - send_donor $DATA "${stagemsg}-IST" + strmcmd+=" '$IST_FILE'" + + send_donor "$DATA" "${stagemsg}-IST" fi @@ -951,37 +995,26 @@ then 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 + [[ -e "$SST_PROGRESS_FILE" ]] && wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE" + [[ -n "$SST_PROGRESS_FILE" ]] && touch "$SST_PROGRESS_FILE" - ib_home_dir=$INNODB_DATA_HOME_DIR + ib_home_dir="$INNODB_DATA_HOME_DIR" - WSREP_LOG_DIR=${WSREP_LOG_DIR:-""} - # Try to set WSREP_LOG_DIR from the command line: - if [ ! -z "$INNODB_LOG_GROUP_HOME_ARG" ]; then - WSREP_LOG_DIR=$INNODB_LOG_GROUP_HOME_ARG - fi - # if no command line arg and WSREP_LOG_DIR is not set, + # if no command line argument and INNODB_LOG_GROUP_HOME is not set, # try to get it from my.cnf: - if [ -z "$WSREP_LOG_DIR" ]; then - WSREP_LOG_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-log-group-home-dir '') - fi - if [ -z "$WSREP_LOG_DIR" ]; then - WSREP_LOG_DIR=$(parse_cnf --mysqld innodb-log-group-home-dir '') + if [ -z "$INNODB_LOG_GROUP_HOME" ]; then + INNODB_LOG_GROUP_HOME=$(parse_cnf '--mysqld' 'innodb-log-group-home-dir') fi - ib_log_dir=$WSREP_LOG_DIR + ib_log_dir="$INNODB_LOG_GROUP_HOME" - # Try to set ib_undo_dir from the command line: - ib_undo_dir=${INNODB_UNDO_DIR_ARG:-""} - # if no command line arg then try to get it from my.cnf: - if [ -z "$ib_undo_dir" ]; then - ib_undo_dir=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-undo-directory "") - fi - if [ -z "$ib_undo_dir" ]; then - ib_undo_dir=$(parse_cnf --mysqld innodb-undo-directory "") + # if no command line argument then try to get it from my.cnf: + if [ -z "$INNODB_UNDO_DIR" ]; then + INNODB_UNDO_DIR=$(parse_cnf '--mysqld' 'innodb-undo-directory') fi + ib_undo_dir="$INNODB_UNDO_DIR" + stagemsg="Joiner-Recv" sencrypted=1 @@ -989,46 +1022,59 @@ then MODULE="xtrabackup_sst" - rm -f "${DATA}/${IST_FILE}" + rm -f "$DATA/$IST_FILE" # May need xtrabackup_checkpoints later on - rm -f ${DATA}/xtrabackup_binary ${DATA}/xtrabackup_galera_info ${DATA}/ib_logfile0 + rm -f "$DATA/xtrabackup_binary" "$DATA/xtrabackup_galera_info" "$DATA/ib_logfile0" - ADDR=${WSREP_SST_OPT_ADDR} - if [ -z "${SST_PORT}" ] - then - SST_PORT=4444 - if [ "${ADDR#\[}" != "$ADDR" ]; then - ADDR="$(echo ${WSREP_SST_OPT_ADDR} | awk -F '\\]:' '{ print $1 }')]:${SST_PORT}" - else - ADDR="$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $1 }'):${SST_PORT}" + ADDR="$WSREP_SST_OPT_ADDR" + + if [ "${tmode#VERIFY}" != "$tmode" ] + then # backward-incompatible behavior + CN="" + if [ -n "$tpem" ] + then + # find out my Common Name + get_openssl + if [ -z "$OPENSSL_BINARY" ]; then + wsrep_log_error 'openssl not found but it is required for authentication' + exit 42 + fi + CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$tpem" | \ + tr "," "\n" | grep "CN =" | cut -d= -f2 | sed s/^\ // | \ + sed s/\ %//) fi + MY_SECRET=$(wsrep_gen_secret) + # Add authentication data to address + ADDR="$CN:$MY_SECRET@$ADDR" + else + MY_SECRET="" # for check down in recv_joiner() fi - wait_for_listen ${SST_PORT} ${ADDR} ${MODULE} & + wait_for_listen "$SST_PORT" "$ADDR" "$MODULE" & trap sig_joiner_cleanup HUP PIPE INT TERM trap cleanup_joiner EXIT - if [[ -n $progress ]];then + if [ -n "$progress" ]; then adjust_progress tcmd+=" | $pcmd" fi get_keys - if [[ $encrypt -eq 1 && $sencrypted -eq 1 ]];then - if [[ -n $sdecomp ]];then - strmcmd=" $sdecomp | $ecmd | $strmcmd" + if [ $encrypt -eq 1 -a $sencrypted -eq 1 ]; then + if [ -n "$sdecomp" ]; then + strmcmd="$sdecomp | $ecmd | $strmcmd" else - strmcmd=" $ecmd | $strmcmd" + strmcmd="$ecmd | $strmcmd" fi - elif [[ -n $sdecomp ]];then - strmcmd=" $sdecomp | $strmcmd" + elif [ -n "$sdecomp" ]; then + strmcmd="$sdecomp | $strmcmd" fi STATDIR=$(mktemp -d) - MAGIC_FILE="${STATDIR}/${INFO_FILE}" - recv_joiner $STATDIR "${stagemsg}-gtid" $stimeout 1 + MAGIC_FILE="$STATDIR/$INFO_FILE" + recv_joiner "$STATDIR" "${stagemsg}-gtid" $stimeout 1 if ! ps -p ${WSREP_SST_OPT_PARENT} &>/dev/null then @@ -1036,80 +1082,75 @@ then exit 32 fi - if [ ! -r "${STATDIR}/${IST_FILE}" ] + if [ ! -r "$STATDIR/$IST_FILE" ] then - if [[ -d ${DATA}/.sst ]];then + if [ -d "$DATA/.sst" ]; then wsrep_log_info "WARNING: Stale temporary SST directory: ${DATA}/.sst from previous state transfer. Removing" - rm -rf ${DATA}/.sst + rm -rf "$DATA/.sst" fi - mkdir -p ${DATA}/.sst - (recv_joiner $DATA/.sst "${stagemsg}-SST" 0 0) & + mkdir -p "$DATA/.sst" + (recv_joiner "$DATA/.sst" "${stagemsg}-SST" 0 0) & jpid=$! wsrep_log_info "Proceeding with SST" wsrep_log_info "Cleaning the existing datadir and innodb-data/log directories" if [ "${OS}" = "FreeBSD" ]; then - find -E $ib_home_dir $ib_log_dir $ib_undo_dir $DATA -mindepth 1 -prune -regex $cpat -o -exec rm -rfv {} 1>&2 \+ + find -E ${ib_home_dir:+"$ib_home_dir"} \ + ${ib_undo_dir:+"$ib_undo_dir"} \ + ${ib_log_dir:+"$ib_log_dir"} \ + "$DATA" -mindepth 1 -prune -regex "$cpat" -o -exec rm -rfv {} 1>&2 \+ else - find $ib_home_dir $ib_log_dir $ib_undo_dir $DATA -mindepth 1 -prune -regex $cpat -o -exec rm -rfv {} 1>&2 \+ + find ${ib_home_dir:+"$ib_home_dir"} \ + ${ib_undo_dir:+"$ib_undo_dir"} \ + ${ib_log_dir:+"$ib_log_dir"} \ + "$DATA" -mindepth 1 -prune -regex "$cpat" -o -exec rm -rfv {} 1>&2 \+ fi - tempdir=$LOG_BIN_ARG - if [ -z "$tempdir" ]; then - tempdir=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE log-bin "") - fi - if [ -z "$tempdir" ]; then - tempdir=$(parse_cnf --mysqld log-bin "") - fi - 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 \+ || true - rm $binlog_dir/*.index || true - fi + get_binlog + + if [ -n "$WSREP_SST_OPT_BINLOG" ]; then + binlog_dir=$(dirname "$WSREP_SST_OPT_BINLOG") + cd "$binlog_dir" + wsrep_log_info "Cleaning the binlog directory $binlog_dir as well" + rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || true + binlog_index="${WSREP_SST_OPT_BINLOG_INDEX%.index}.index" + [ -f "$binlog_index" ] && rm -fv "$binlog_index" 1>&2 \+ || true + cd "$OLD_PWD" fi - TDATA=${DATA} - DATA="${DATA}/.sst" + TDATA="$DATA" + DATA="$DATA/.sst" - MAGIC_FILE="${DATA}/${INFO_FILE}" + MAGIC_FILE="$DATA/$INFO_FILE" wsrep_log_info "Waiting for SST streaming to complete!" monitor_process $jpid get_proc - if [[ ! -s ${DATA}/xtrabackup_checkpoints ]];then - wsrep_log_error "xtrabackup_checkpoints missing, failed innobackupex/SST on donor" + if [[ ! -s "$DATA/xtrabackup_checkpoints" ]];then + wsrep_log_error "xtrabackup_checkpoints missing, failed mariabackup/SST on donor" exit 2 fi - # Rebuild indexes for compact backups - if grep -q 'compact = 1' ${DATA}/xtrabackup_checkpoints;then + # Compact backups are not supported by mariabackup + 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" + wsrel_log_error "Compact backups are not supported by mariabackup" + exit 2 fi - if test -n "$(find ${DATA} -maxdepth 1 -type f -name '*.qp' -print -quit)";then - + qpfiles=$(find "$DATA" -maxdepth 1 -type f -name '*.qp' -print -quit) + if [ -n "$qpfiles" ]; then wsrep_log_info "Compressed qpress files found" - if ! command -v qpress >/dev/null;then + if [ ! -x "$(command -v 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) + 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]'" @@ -1125,12 +1166,12 @@ then # 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" + 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 + find "$DATA" -type f -name '*.qp' -delete if [[ $? -ne 0 ]];then wsrep_log_error "Something went wrong with deletion of qpress files. Investigate" fi @@ -1140,40 +1181,38 @@ then fi fi - if [[ ! -z $WSREP_SST_OPT_BINLOG ]];then + if [ -n "$WSREP_SST_OPT_BINLOG" ]; then - BINLOG_DIRNAME=$(dirname $WSREP_SST_OPT_BINLOG) - BINLOG_FILENAME=$(basename $WSREP_SST_OPT_BINLOG) + BINLOG_DIRNAME=$(dirname "$WSREP_SST_OPT_BINLOG") + BINLOG_FILENAME=$(basename "$WSREP_SST_OPT_BINLOG") # To avoid comparing data directory and BINLOG_DIRNAME - mv $DATA/${BINLOG_FILENAME}.* $BINLOG_DIRNAME/ 2>/dev/null || true + mv "$DATA/$BINLOG_FILENAME".* "$BINLOG_DIRNAME/" 2>/dev/null || true - pushd $BINLOG_DIRNAME &>/dev/null - for bfiles in $(ls -1 ${BINLOG_FILENAME}.[0-9]*);do - echo ${BINLOG_DIRNAME}/${bfiles} >> ${BINLOG_FILENAME}.index + cd "$BINLOG_DIRNAME" + for bfile in $(ls -1 "$BINLOG_FILENAME".[0-9]*); do + echo "$BINLOG_DIRNAME/$bfile" >> "${WSREP_SST_OPT_BINLOG_INDEX%.index}.index" done - popd &> /dev/null + cd "$OLD_PWD" fi wsrep_log_info "Preparing the backup at ${DATA}" + setup_commands timeit "Xtrabackup prepare stage" "$INNOAPPLY" - if [ $? -ne 0 ]; - then - wsrep_log_error "${INNOBACKUPEX_BIN} apply finished with errors. Check syslog or ${INNOAPPLYLOG} for details" + if [ $? -ne 0 ]; then + wsrep_log_error "${MARIABACKUP_BIN} apply finished with errors. Check syslog or ${INNOAPPLYLOG} for details" exit 22 fi - MAGIC_FILE="${TDATA}/${INFO_FILE}" - set +e - set -e + MAGIC_FILE="$TDATA/$INFO_FILE" 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} + rm -rf "$DATA" + DATA="$TDATA" else wsrep_log_error "Move failed, keeping ${DATA} for further diagnosis" wsrep_log_error "Check syslog or ${INNOMOVELOG} for details" @@ -1186,12 +1225,12 @@ then fi - if [[ ! -r ${MAGIC_FILE} ]];then + if [ ! -r "$MAGIC_FILE" ]; then wsrep_log_error "SST magic file ${MAGIC_FILE} not found/readable" exit 2 fi - wsrep_log_info "Galera co-ords from recovery: $(cat ${MAGIC_FILE})" - cat "${MAGIC_FILE}" # Output : UUID:seqno wsrep_gtid_domain_id + wsrep_log_info "Galera co-ords from recovery: $(cat '${MAGIC_FILE}')" + cat "$MAGIC_FILE" # Output : UUID:seqno wsrep_gtid_domain_id wsrep_log_info "Total time on joiner: $totime seconds" fi diff --git a/scripts/wsrep_sst_mysqldump.sh b/scripts/wsrep_sst_mysqldump.sh index 19fca2df024..3cc52398caa 100644 --- a/scripts/wsrep_sst_mysqldump.sh +++ b/scripts/wsrep_sst_mysqldump.sh @@ -1,5 +1,6 @@ #!/bin/bash -ue # Copyright (C) 2009-2015 Codership Oy +# Copyright (C) 2017-2021 MariaDB # # 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 @@ -25,6 +26,7 @@ EINVAL=22 local_ip() { [ "$1" = "127.0.0.1" ] && return 0 + [ "$1" = "127.0.0.2" ] && return 0 [ "$1" = "localhost" ] && return 0 [ "$1" = "[::1]" ] && return 0 [ "$1" = "$(hostname -s)" ] && return 0 @@ -138,8 +140,8 @@ then # turned off for the session so that gtid state does not get altered while # the dump gets replayed on joiner. if [[ "$LOG_BIN" == 'ON' ]]; then - RESET_MASTER="RESET MASTER;" - SET_GTID_BINLOG_STATE="SET @@global.gtid_binlog_state='$GTID_BINLOG_STATE';" + RESET_MASTER="SET GLOBAL wsrep_on=OFF; RESET MASTER; SET GLOBAL wsrep_on=ON;" + SET_GTID_BINLOG_STATE="SET GLOBAL wsrep_on=OFF; SET @@global.gtid_binlog_state='$GTID_BINLOG_STATE'; SET GLOBAL wsrep_on=ON;" SQL_LOG_BIN_OFF="SET @@session.sql_log_bin=OFF;" fi fi diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index ec64a6b5d8f..92fdc28f643 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -1,6 +1,7 @@ #!/bin/bash -ue # Copyright (C) 2010-2014 Codership Oy +# Copyright (C) 2017-2021 MariaDB # # 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 @@ -23,12 +24,13 @@ RSYNC_CONF= # rsync configuration file RSYNC_REAL_PID= # rsync process id OS=$(uname) -[ "$OS" = "Darwin" ] && export -n LD_LIBRARY_PATH +[ "$OS" = 'Darwin' ] && export -n LD_LIBRARY_PATH # Setting the path for lsof on CentOS export PATH="/usr/sbin:/sbin:$PATH" . $(dirname $0)/wsrep_sst_common +wsrep_check_datadir wsrep_check_programs rsync @@ -54,13 +56,13 @@ cleanup_joiner() # Check whether rsync process is still running. check_pid() { - local pid_file=$1 - [ -r "$pid_file" ] && ps -p $(cat $pid_file) >/dev/null 2>&1 + local pid_file="$1" + [ -r "$pid_file" ] && ps -p $(cat "$pid_file") >/dev/null 2>&1 } check_pid_and_port() { - local pid_file=$1 + local pid_file="$1" local rsync_pid=$2 local rsync_addr=$3 local rsync_port=$4 @@ -73,11 +75,10 @@ check_pid_and_port() grep -E '[[:space:]]+(rsync|stunnel)[[:space:]]+'"$rsync_pid" 2>/dev/null)" ;; *) - if ! which lsof > /dev/null; then + if [ ! -x "$(command -v lsof)" ]; then wsrep_log_error "lsof tool not found in PATH! Make sure you have it installed." exit 2 # ENOENT fi - local port_info="$(lsof -i :$rsync_port -Pn 2>/dev/null | \ grep "(LISTEN)")" local is_rsync="$(echo $port_info | \ @@ -96,22 +97,21 @@ check_pid_and_port() exit 16 # EBUSY fi fi - check_pid $pid_file && \ + check_pid "$pid_file" && \ [ -n "$port_info" ] && [ -n "$is_rsync" ] && \ - [ $(cat $pid_file) -eq $rsync_pid ] + [ $(cat "$pid_file") -eq $rsync_pid ] } is_local_ip() { local address="$1" - local get_addr_bin=`which ifconfig` + local get_addr_bin="$(command -v ifconfig)" if [ -z "$get_addr_bin" ] then - get_addr_bin=`which ip` - get_addr_bin="$get_addr_bin address show" + get_addr_bin="$(command -v ip) address show" # Add an slash at the end, so we don't get false positive : 172.18.0.4 matches 172.18.0.41 # ip output format is "X.X.X.X/mask" - address="${address}/" + address="$address/" else # Add an space at the end, so we don't get false positive : 172.18.0.4 matches 172.18.0.41 # ifconfig output format is "X.X.X.X " @@ -134,64 +134,64 @@ BINLOG_TAR_FILE="$WSREP_SST_OPT_DATA/wsrep_sst_binlog.tar" BINLOG_N_FILES=1 rm -f "$BINLOG_TAR_FILE" || : -if ! [ -z $WSREP_SST_OPT_BINLOG ] -then - BINLOG_DIRNAME=$(dirname $WSREP_SST_OPT_BINLOG) - BINLOG_FILENAME=$(basename $WSREP_SST_OPT_BINLOG) - BINLOG_INDEX_DIRNAME=$(dirname $WSREP_SST_OPT_BINLOG) - BINLOG_INDEX_FILENAME=$(basename $WSREP_SST_OPT_BINLOG) -fi +get_binlog -if ! [ -z $WSREP_SST_OPT_BINLOG_INDEX ] -then - BINLOG_INDEX_DIRNAME=$(dirname $WSREP_SST_OPT_BINLOG_INDEX) - BINLOG_INDEX_FILENAME=$(basename $WSREP_SST_OPT_BINLOG_INDEX) +if [ -n "$WSREP_SST_OPT_BINLOG" ]; then + BINLOG_DIRNAME=$(dirname "$WSREP_SST_OPT_BINLOG") + BINLOG_FILENAME=$(basename "$WSREP_SST_OPT_BINLOG") fi -WSREP_LOG_DIR=${WSREP_LOG_DIR:-""} -# Try to set WSREP_LOG_DIR from the command line: -if [ ! -z "$INNODB_LOG_GROUP_HOME_ARG" ]; then - WSREP_LOG_DIR=$INNODB_LOG_GROUP_HOME_ARG -fi -# if no command line arg and WSREP_LOG_DIR is not set, +# if no command line argument and INNODB_LOG_GROUP_HOME is not set, # try to get it from my.cnf: -if [ -z "$WSREP_LOG_DIR" ]; then - WSREP_LOG_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-log-group-home-dir '') -fi -if [ -z "$WSREP_LOG_DIR" ]; then - WSREP_LOG_DIR=$(parse_cnf --mysqld innodb-log-group-home-dir '') +if [ -z "$INNODB_LOG_GROUP_HOME" ]; then + INNODB_LOG_GROUP_HOME=$(parse_cnf '--mysqld' 'innodb-log-group-home-dir') fi +OLD_PWD="$(pwd)" + +WSREP_LOG_DIR="$INNODB_LOG_GROUP_HOME" + if [ -n "$WSREP_LOG_DIR" ]; then # handle both relative and absolute paths - WSREP_LOG_DIR=$(cd $WSREP_SST_OPT_DATA; mkdir -p "$WSREP_LOG_DIR"; cd $WSREP_LOG_DIR; pwd -P) + WSREP_LOG_DIR=$(cd "$WSREP_SST_OPT_DATA"; mkdir -p "$WSREP_LOG_DIR"; cd "$WSREP_LOG_DIR"; pwd -P) else # default to datadir - WSREP_LOG_DIR=$(cd $WSREP_SST_OPT_DATA; pwd -P) + WSREP_LOG_DIR=$(cd "$WSREP_SST_OPT_DATA"; pwd -P) fi -INNODB_DATA_HOME_DIR=${INNODB_DATA_HOME_DIR:-""} -# Try to set INNODB_DATA_HOME_DIR from the command line: -if [ ! -z "$INNODB_DATA_HOME_DIR_ARG" ]; then - INNODB_DATA_HOME_DIR=$INNODB_DATA_HOME_DIR_ARG -fi -# if no command line arg and INNODB_DATA_HOME_DIR environment variable +cd "$OLD_PWD" + +# if no command line argument and INNODB_DATA_HOME_DIR environment variable # is not set, try to get it from my.cnf: if [ -z "$INNODB_DATA_HOME_DIR" ]; then - INNODB_DATA_HOME_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-data-home-dir '') -fi -if [ -z "$INNODB_DATA_HOME_DIR" ]; then - INNODB_DATA_HOME_DIR=$(parse_cnf --mysqld innodb-data-home-dir '') + INNODB_DATA_HOME_DIR=$(parse_cnf '--mysqld' 'innodb-data-home-dir') fi if [ -n "$INNODB_DATA_HOME_DIR" ]; then # handle both relative and absolute paths - INNODB_DATA_HOME_DIR=$(cd $WSREP_SST_OPT_DATA; mkdir -p "$INNODB_DATA_HOME_DIR"; cd $INNODB_DATA_HOME_DIR; pwd -P) + INNODB_DATA_HOME_DIR=$(cd "$WSREP_SST_OPT_DATA"; mkdir -p "$INNODB_DATA_HOME_DIR"; cd "$INNODB_DATA_HOME_DIR"; pwd -P) +else + # default to datadir + INNODB_DATA_HOME_DIR=$(cd "$WSREP_SST_OPT_DATA"; pwd -P) +fi + +cd "$OLD_PWD" + +# if no command line argument then try to get it from my.cnf: +if [ -z "$INNODB_UNDO_DIR" ]; then + INNODB_UNDO_DIR=$(parse_cnf '--mysqld' 'innodb-undo-directory') +fi + +if [ -n "$INNODB_UNDO_DIR" ]; then + # handle both relative and absolute paths + INNODB_UNDO_DIR=$(cd "$WSREP_SST_OPT_DATA"; mkdir -p "$INNODB_UNDO_DIR"; cd "$INNODB_UNDO_DIR"; pwd -P) else # default to datadir - INNODB_DATA_HOME_DIR=$(cd $WSREP_SST_OPT_DATA; pwd -P) + INNODB_UNDO_DIR=$(cd "$WSREP_SST_OPT_DATA"; pwd -P) fi +cd "$OLD_PWD" + # Old filter - include everything except selected # FILTER=(--exclude '*.err' --exclude '*.pid' --exclude '*.sock' \ # --exclude '*.conf' --exclude core --exclude 'galera.*' \ @@ -206,30 +206,99 @@ FILTER="-f '- /lost+found' -f '+ /wsrep_sst_binlog.tar' -f '- $INNODB_DATA_HOME_DIR/ib_lru_dump' -f '- $INNODB_DATA_HOME_DIR/ibdata*' - -f '+ /undo*' + -f '+ $INNODB_UNDO_DIR/undo*' -f '+ /*/' -f '- /*'" -SSTKEY=$(parse_cnf sst tkey "") -SSTCERT=$(parse_cnf sst tcert "") +# old-style SSL config +SSTKEY=$(parse_cnf 'sst' 'tkey') +SSTCERT=$(parse_cnf 'sst' 'tcert') +SSTCA=$(parse_cnf 'sst' 'tca') + +check_server_ssl_config() +{ + local section="$1" + SSTKEY=$(parse_cnf "$section" 'ssl-key') + SSTCERT=$(parse_cnf "$section" 'ssl-cert') + SSTCA=$(parse_cnf "$section" 'ssl-ca') +} + +SSLMODE=$(parse_cnf 'sst' 'ssl-mode' | tr [:lower:] [:upper:]) + +if [ -z "$SSTKEY" -a -z "$SSTCERT" ] +then + # no old-style SSL config in [sst], check for new one + check_server_ssl_config 'sst' + if [ -z "$SSTKEY" -a -z "$SSTCERT" ]; then + check_server_ssl_config '--mysqld' + fi +fi + +if [ -z "$SSLMODE" ]; then + # Implicit verification if CA is set and the SSL mode + # is not specified by user: + if [ -n "$SSTCA" ]; then + if [ -x "$(command -v stunnel)" ]; then + SSLMODE='VERIFY_CA' + fi + # Require SSL by default if SSL key and cert are present: + elif [ -n "$SSTKEY" -a -n "$SSTCERT" ]; then + SSLMODE='REQUIRED' + fi +fi + +if [ -n "$SSTCA" ] +then + CAFILE_OPT="CAfile = $SSTCA" +else + CAFILE_OPT="" +fi + +if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ] +then + case "$SSLMODE" in + 'VERIFY_IDENTITY') + VERIFY_OPT='verifyPeer = yes' + ;; + 'VERIFY_CA') + VERIFY_OPT='verifyChain = yes' + ;; + *) + wsrep_log_error "Unrecognized ssl-mode option: '$SSLMODE'" + exit 22 # EINVAL + esac + if [ -z "$CAFILE_OPT" ] + then + wsrep_log_error "Can't have ssl-mode=$SSLMODE without CA file" + exit 22 # EINVAL + fi +else + VERIFY_OPT="" +fi + STUNNEL="" -if [ -f "$SSTKEY" ] && [ -f "$SSTCERT" ] && wsrep_check_programs stunnel +if [ -n "$SSLMODE" -a "$SSLMODE" != 'DISABLED' ] && wsrep_check_programs stunnel then - STUNNEL="stunnel ${STUNNEL_CONF}" + wsrep_log_info "Using stunnel for SSL encryption: CAfile: $SSTCA, SSLMODE: $SSLMODE" + STUNNEL="stunnel $STUNNEL_CONF" fi -if [ "$WSREP_SST_OPT_ROLE" = "donor" ] +readonly SECRET_TAG="secret" + +if [ "$WSREP_SST_OPT_ROLE" = 'donor' ] then cat << EOF > "$STUNNEL_CONF" -CApath = ${SSTCERT%/*} +key = $SSTKEY +cert = $SSTCERT +${CAFILE_OPT} foreground = yes pid = $STUNNEL_PID debug = warning client = yes connect = ${WSREP_SST_OPT_ADDR%/*} TIMEOUTclose = 0 -verifyPeer = yes +${VERIFY_OPT} EOF if [ $WSREP_SST_OPT_BYPASS -eq 0 ] @@ -242,7 +311,7 @@ EOF rm -rf "$ERROR" # Use deltaxfer only for WAN - inv=$(basename $0) + inv=$(basename "$0") [ "$inv" = "wsrep_sst_rsync_wan" ] && WHOLE_FILE_OPT="" \ || WHOLE_FILE_OPT="--whole-file" @@ -266,48 +335,43 @@ EOF sleep 0.2 done - STATE="$(cat $FLUSHED)" + STATE=$(cat "$FLUSHED") rm -rf "$FLUSHED" sync - if ! [ -z $WSREP_SST_OPT_BINLOG ] + if [ -n "$WSREP_SST_OPT_BINLOG" ] then # Prepare binlog files - OLD_PWD="$(pwd)" - cd $BINLOG_DIRNAME + cd "$BINLOG_DIRNAME" - if ! [ -z $WSREP_SST_OPT_BINLOG_INDEX ] - binlog_files_full=$(tail -n $BINLOG_N_FILES ${BINLOG_FILENAME}.index) - then - cd $BINLOG_INDEX_DIRNAME - binlog_files_full=$(tail -n $BINLOG_N_FILES ${BINLOG_INDEX_FILENAME}.index) - fi + binlog_files_full=$(tail -n $BINLOG_N_FILES "${WSREP_SST_OPT_BINLOG_INDEX%.index}.index") - cd $BINLOG_DIRNAME binlog_files="" for ii in $binlog_files_full do - binlog_files="$binlog_files $(basename $ii)" + binlog_file=$(basename "$ii") + binlog_files="$binlog_files $binlog_file" done - if ! [ -z "$binlog_files" ] + if [ -n "$binlog_files" ] then wsrep_log_info "Preparing binlog files for transfer:" - tar -cvf $BINLOG_TAR_FILE $binlog_files >&2 + tar -cvf "$BINLOG_TAR_FILE" $binlog_files >&2 fi + cd "$OLD_PWD" fi # first, the normal directories, so that we can detect incompatible protocol RC=0 - eval rsync ${STUNNEL:+--rsh="$STUNNEL"} \ + eval rsync ${STUNNEL:+--rsh=\"$STUNNEL\"} \ --owner --group --perms --links --specials \ --ignore-times --inplace --dirs --delete --quiet \ $WHOLE_FILE_OPT ${FILTER} "$WSREP_SST_OPT_DATA/" \ rsync://$WSREP_SST_OPT_ADDR >&2 || RC=$? - if [ "$RC" -ne 0 ]; then + if [ $RC -ne 0 ]; then wsrep_log_error "rsync returned code $RC:" case $RC in @@ -341,7 +405,7 @@ EOF rsync ${STUNNEL:+--rsh="$STUNNEL"} \ --owner --group --perms --links --specials \ --ignore-times --inplace --dirs --delete --quiet \ - $WHOLE_FILE_OPT -f '+ /ib_logfile[0-9]*' -f '- **' "$WSREP_LOG_DIR/" \ + $WHOLE_FILE_OPT -f '+ /ib_logfile[0-9]*' -f '+ /aria_log.*' -f '+ /aria_log_control' -f '- **' "$WSREP_LOG_DIR/" \ rsync://$WSREP_SST_OPT_ADDR-log_dir >&2 || RC=$? if [ $RC -ne 0 ]; then @@ -350,8 +414,7 @@ EOF fi # then, we parallelize the transfer of database directories, use . so that pathconcatenation works - OLD_PWD="$(pwd)" - cd $WSREP_SST_OPT_DATA + cd "$WSREP_SST_OPT_DATA" count=1 [ "$OS" = "Linux" ] && count=$(grep -c processor /proc/cpuinfo) @@ -362,7 +425,7 @@ EOF rsync ${STUNNEL:+--rsh="$STUNNEL"} \ --owner --group --perms --links --specials \ --ignore-times --inplace --recursive --delete --quiet \ - $WHOLE_FILE_OPT --exclude '*/ib_logfile*' "$WSREP_SST_OPT_DATA"/{}/ \ + $WHOLE_FILE_OPT --exclude '*/ib_logfile*' --exclude "*/aria_log.*" --exclude "*/aria_log_control" "$WSREP_SST_OPT_DATA"/{}/ \ rsync://$WSREP_SST_OPT_ADDR/{} >&2 || RC=$? cd "$OLD_PWD" @@ -385,50 +448,46 @@ EOF echo "continue" # now server can resume updating data echo "$STATE" > "$MAGIC_FILE" + + if [ -n "$WSREP_SST_OPT_REMOTE_PSWD" ]; then + # Let joiner know that we know its secret + echo "$SECRET_TAG $WSREP_SST_OPT_REMOTE_PSWD" >> "$MAGIC_FILE" + fi + rsync ${STUNNEL:+--rsh="$STUNNEL"} \ --archive --quiet --checksum "$MAGIC_FILE" rsync://$WSREP_SST_OPT_ADDR echo "done $STATE" -elif [ "$WSREP_SST_OPT_ROLE" = "joiner" ] +elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ] then wsrep_check_programs lsof - touch $SST_PROGRESS_FILE - MYSQLD_PID=$WSREP_SST_OPT_PARENT + touch "$SST_PROGRESS_FILE" + MYSQLD_PID="$WSREP_SST_OPT_PARENT" MODULE="rsync_sst" RSYNC_PID="$WSREP_SST_OPT_DATA/$MODULE.pid" # give some time for lingering rsync from previous SST to complete check_round=0 - while check_pid $RSYNC_PID && [ $check_round -lt 10 ] + while check_pid "$RSYNC_PID" && [ $check_round -lt 10 ] do wsrep_log_info "lingering rsync daemon found at startup, waiting for it to exit" check_round=$(( check_round + 1 )) sleep 1 done - if check_pid $RSYNC_PID + if check_pid "$RSYNC_PID" then wsrep_log_error "rsync daemon already running." exit 114 # EALREADY fi rm -rf "$RSYNC_PID" - ADDR=$WSREP_SST_OPT_ADDR - if [ "${ADDR#\[}" != "$ADDR" ]; then - RSYNC_PORT=$(echo $ADDR | awk -F '\\]:' '{ print $2 }') - RSYNC_ADDR=$(echo $ADDR | awk -F '\\]:' '{ print $1 }')"]" - else - RSYNC_PORT=$(echo $ADDR | awk -F ':' '{ print $2 }') - RSYNC_ADDR=$(echo $ADDR | awk -F ':' '{ print $1 }') - fi - if [ -z "$RSYNC_PORT" ] - then - RSYNC_PORT=4444 - ADDR="$RSYNC_ADDR:$RSYNC_PORT" - fi + ADDR="$WSREP_SST_OPT_ADDR" + RSYNC_PORT="$WSREP_SST_OPT_PORT" + RSYNC_ADDR="$WSREP_SST_OPT_HOST" trap "exit 32" HUP PIPE trap "exit 3" INT TERM ABRT @@ -436,7 +495,7 @@ then RSYNC_CONF="$WSREP_SST_OPT_DATA/$MODULE.conf" - if [ -n "${MYSQL_TMP_DIR:-}" ] ; then + if [ -n "${MYSQL_TMP_DIR:-}" ]; then SILENT="log file = $MYSQL_TMP_DIR/rsyncd.log" else SILENT="" @@ -459,7 +518,6 @@ EOF # rm -rf "$DATA"/ib_logfile* # we don't want old logs around - readonly RSYNC_PORT=${WSREP_SST_OPT_PORT:-4444} # If the IP is local listen only in it if is_local_ip "$RSYNC_ADDR" then @@ -481,18 +539,19 @@ EOF cat << EOF > "$STUNNEL_CONF" key = $SSTKEY cert = $SSTCERT +${CAFILE_OPT} foreground = yes pid = $STUNNEL_PID debug = warning client = no [rsync] accept = $STUNNEL_ACCEPT -exec = $(which rsync) -execargs = rsync --server --daemon --config=$RSYNC_CONF . +exec = $(command -v rsync) +execargs = rsync --server --daemon --config='$RSYNC_CONF' . EOF stunnel "$STUNNEL_CONF" & RSYNC_REAL_PID=$! - RSYNC_PID=$STUNNEL_PID + RSYNC_PID="$STUNNEL_PID" fi until check_pid_and_port "$RSYNC_PID" "$RSYNC_REAL_PID" "$RSYNC_ADDR" "$RSYNC_PORT" @@ -500,7 +559,30 @@ EOF sleep 0.2 done - echo "ready $WSREP_SST_OPT_HOST:$RSYNC_PORT/$MODULE" + if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ] + then # backward-incompatible behavior + CN="" + if [ -n "$SSTCERT" ] + then + # find out my Common Name + get_openssl + if [ -z "$OPENSSL_BINARY" ]; then + wsrep_log_error 'openssl not found but it is required for authentication' + exit 42 + fi + CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$SSTCERT" | \ + tr "," "\n" | grep "CN =" | cut -d= -f2 | sed s/^\ // | \ + sed s/\ %//) + fi + MY_SECRET=$(wsrep_gen_secret) + # Add authentication data to address + ADDR="$CN:$MY_SECRET@$WSREP_SST_OPT_HOST" + else + MY_SECRET="" # for check down in recv_joiner() + ADDR=$WSREP_SST_OPT_HOST + fi + + echo "ready $ADDR:$RSYNC_PORT/$MODULE" # wait for SST to complete by monitoring magic file while [ ! -r "$MAGIC_FILE" ] && check_pid "$RSYNC_PID" && \ @@ -513,37 +595,46 @@ EOF then wsrep_log_error \ "Parent mysqld process (PID:$MYSQLD_PID) terminated unexpectedly." - kill -- -"${MYSQLD_PID}" + kill -- -$MYSQLD_PID sleep 1 exit 32 fi - if ! [ -z $WSREP_SST_OPT_BINLOG ] - then - OLD_PWD="$(pwd)" - cd $BINLOG_DIRNAME + if [ -n "$WSREP_SST_OPT_BINLOG" ]; then + if [ -f "$BINLOG_TAR_FILE" ]; then + cd "$BINLOG_DIRNAME" + + binlog_index="${WSREP_SST_OPT_BINLOG_INDEX%.index}.index" - if [ -f $BINLOG_TAR_FILE ] - then # Clean up old binlog files first - rm -f ${BINLOG_FILENAME}.* + rm -f "$BINLOG_FILENAME".[0-9]* + [ -f "$binlog_index" ] && rm "$binlog_index" + wsrep_log_info "Extracting binlog files:" - tar -xvf $BINLOG_TAR_FILE >&2 - for ii in $(ls -1 ${BINLOG_FILENAME}.*) - do - if ! [ -z $WSREP_SST_OPT_BINLOG_INDEX ] - echo ${BINLOG_DIRNAME}/${ii} >> ${BINLOG_FILENAME}.index - then - echo ${BINLOG_DIRNAME}/${ii} >> ${BINLOG_INDEX_DIRNAME}/${BINLOG_INDEX_FILENAME}.index - fi - done - fi + tar -xvf "$BINLOG_TAR_FILE" >> _binlog_tmp_files_$! + while read bin_file; do + echo "$BINLOG_DIRNAME/$bin_file" >> "$binlog_index" + done < _binlog_tmp_files_$! + rm -f _binlog_tmp_files_$! - cd "$OLD_PWD" + cd "$OLD_PWD" + fi fi if [ -r "$MAGIC_FILE" ] then + # check donor supplied secret + SECRET=$(grep "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2) + if [ "$SECRET" != "$MY_SECRET" ]; then + wsrep_log_error "Donor does not know my secret!" + wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'" + exit 32 + fi + + # remove secret from magic file + grep -v "$SECRET_TAG " "$MAGIC_FILE" > "$MAGIC_FILE.new" + + mv "$MAGIC_FILE.new" "$MAGIC_FILE" # UUID:seqno & wsrep_gtid_domain_id is received here. cat "$MAGIC_FILE" # Output : UUID:seqno wsrep_gtid_domain_id else @@ -558,6 +649,6 @@ else exit 22 # EINVAL fi -rm -f $BINLOG_TAR_FILE || : +rm -f "$BINLOG_TAR_FILE" || : exit 0 diff --git a/scripts/wsrep_sst_xtrabackup-v2.sh b/scripts/wsrep_sst_xtrabackup-v2.sh index 7c3859237e0..c1c9a41bdf2 100644 --- a/scripts/wsrep_sst_xtrabackup-v2.sh +++ b/scripts/wsrep_sst_xtrabackup-v2.sh @@ -1,5 +1,6 @@ #!/bin/bash -ue # Copyright (C) 2013 Percona Inc +# Copyright (C) 2017-2021 MariaDB # # 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 @@ -19,6 +20,7 @@ # Make sure to read that before proceeding! . $(dirname $0)/wsrep_sst_common +wsrep_check_datadir ealgo="" ekey="" @@ -93,7 +95,7 @@ if ! which lsof > /dev/null; then fi timeit(){ - local stage=$1 + local stage="$1" shift local cmd="$@" local x1 x2 took extcode @@ -137,17 +139,17 @@ get_keys() wsrep_log_info "Xtrabackup based encryption enabled in my.cnf - Supported only from Xtrabackup 2.1.4" - if [[ -z $ealgo ]];then + 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 + if [[ -z "$ekey" && ! -r "$ekeyfile" ]];then wsrep_log_error "FATAL: Either key or keyfile must be readable" exit 3 fi - if [[ -z $ekey ]];then + if [[ -z "$ekey" ]];then ecmd="xbcrypt --encrypt-algo=$ealgo --encrypt-key-file=$ekeyfile" else wsrep_log_warning "Using the 'encrypt-key' option causes the encryption key" @@ -199,8 +201,8 @@ check_for_dhparams() # verify_cert_matches_key() { - local cert_path=$1 - local key_path=$2 + local cert_path="$1" + local key_path="$2" wsrep_check_programs openssl diff @@ -226,9 +228,9 @@ verify_cert_matches_key() # verify_file_exists() { - local file_path=$1 - local error_message1=$2 - local error_message2=$3 + local file_path="$1" + local error_message1="$2" + local error_message2="$3" if ! [[ -r "$file_path" ]]; then wsrep_log_error "******** FATAL ERROR ************************* " @@ -246,7 +248,7 @@ verify_file_exists() get_transfer() { - TSST_PORT=${WSREP_SST_OPT_PORT:-4444} + TSST_PORT="$WSREP_SST_OPT_PORT" if [[ $tfmt == 'nc' ]];then if [[ ! -x `which nc` ]];then @@ -264,26 +266,46 @@ get_transfer() wsrep_log_info "Using netcat as streamer" if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then - if nc -h 2>&1 | grep -q ncat; then + if nc -h 2>&1 | grep -q ncat;then # Ncat - tcmd="nc $sockopt -l ${TSST_PORT}" - elif nc -h 2>&1 | grep -q -- '-d\>';then + tcmd="nc -l ${TSST_PORT}" + elif nc -h 2>&1 | grep -qw -- '-d\>';then # Debian netcat - tcmd="nc $sockopt -dl ${TSST_PORT}" + if [ $WSREP_SST_OPT_HOST_IPv6 -eq 1 ];then + # When host is not explicitly specified (when only the port + # is specified) netcat can only bind to an IPv4 address if + # the "-6" option is not explicitly specified: + tcmd="nc -dl -6 ${TSST_PORT}" + else + tcmd="nc -dl ${TSST_PORT}" + fi else # traditional netcat - tcmd="nc $sockopt -l -p ${TSST_PORT}" + tcmd="nc -l -p ${TSST_PORT}" fi else + # Check to see if netcat supports the '-N' flag. + # -N Shutdown the network socket after EOF on stdin + # If it supports the '-N' flag, then we need to use the '-N' + # flag, otherwise the transfer will stay open after the file + # transfer and cause the command to timeout. + # Older versions of netcat did not need this flag and will + # return an error if the flag is used. + # + tcmd_extra="" + if nc -h 2>&1 | grep -qw -- -N;then + tcmd_extra+="-N" + fi + # netcat doesn't understand [] around IPv6 address if nc -h 2>&1 | grep -q ncat;then # Ncat - tcmd="nc ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}" - elif nc -h 2>&1 | grep -q -- '-d\>';then + tcmd="nc ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}" + elif nc -h 2>&1 | grep -qw -- '-d\>';then # Debian netcat - tcmd="nc ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}" + tcmd="nc ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}" else # traditional netcat - tcmd="nc -q0 ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}" + tcmd="nc -q0 ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}" fi fi else @@ -323,7 +345,7 @@ get_transfer() if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]]; then # dhparams check (will create ssl_dhparams if needed) check_for_dhparams - joiner_extra=",dhparam=$ssl_dhparams" + joiner_extra=",dhparam='$ssl_dhparams'" fi fi if check_for_version "$SOCAT_VERSION" "1.7.3"; then @@ -343,10 +365,10 @@ get_transfer() stagemsg+="-OpenSSL-Encrypted-2" if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then wsrep_log_info "Decrypting with CERT: $tcert, CA: $tca" - tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tcert},cafile=${tca}${joiner_extra}${sockopt} stdio" + tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert='${tcert}',cafile='${tca}'${joiner_extra}${sockopt} stdio" else wsrep_log_info "Encrypting with CERT: $tcert, CA: $tca" - tcmd="socat -u stdio openssl-connect:${WSREP_SST_OPT_HOST}:${TSST_PORT},cert=${tcert},cafile=${tca}${donor_extra}${sockopt}" + tcmd="socat -u stdio openssl-connect:${WSREP_SST_OPT_HOST}:${TSST_PORT},cert='${tcert}',cafile='${tca}'${donor_extra}${sockopt}" fi elif [[ $encrypt -eq 3 ]];then wsrep_log_warning "**** WARNING **** encrypt=3 is deprecated and will be removed in a future release" @@ -360,10 +382,10 @@ get_transfer() stagemsg+="-OpenSSL-Encrypted-3" if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then wsrep_log_info "Decrypting with CERT: $tcert, KEY: $tkey" - tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tcert},key=${tkey},verify=0${joiner_extra}${sockopt} stdio" + tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert='${tcert}',key='${tkey}',verify=0${joiner_extra}${sockopt} stdio" else wsrep_log_info "Encrypting with CERT: $tcert, KEY: $tkey" - tcmd="socat -u stdio openssl-connect:${WSREP_SST_OPT_HOST}:${TSST_PORT},cert=${tcert},key=${tkey},verify=0${sockopt}" + tcmd="socat -u stdio openssl-connect:${WSREP_SST_OPT_HOST}:${TSST_PORT},cert='${tcert}',key='${tkey}',verify=0${sockopt}" fi elif [[ $encrypt -eq 4 ]]; then wsrep_log_info "Using openssl based encryption with socat: with key, crt, and ca" @@ -381,10 +403,10 @@ get_transfer() stagemsg+="-OpenSSL-Encrypted-4" if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]]; then wsrep_log_info "Decrypting with CERT: $ssl_cert, KEY: $ssl_key, CA: $ssl_ca" - tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${ssl_cert},key=${ssl_key},cafile=${ssl_ca},verify=1${joiner_extra}${sockopt} stdio" + tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert='${ssl_cert}',key='${ssl_key}',cafile='${ssl_ca}',verify=1${joiner_extra}${sockopt} stdio" else wsrep_log_info "Encrypting with CERT: $ssl_cert, KEY: $ssl_key, CA: $ssl_ca" - tcmd="socat -u stdio openssl-connect:${WSREP_SST_OPT_HOST}:${TSST_PORT},cert=${ssl_cert},key=${ssl_key},cafile=${ssl_ca},verify=1${donor_extra}${sockopt}" + tcmd="socat -u stdio openssl-connect:${WSREP_SST_OPT_HOST}:${TSST_PORT},cert='${ssl_cert}',key='${ssl_key}',cafile='${ssl_ca}',verify=1${donor_extra}${sockopt}" fi else if [[ $encrypt -eq 1 ]]; then @@ -402,7 +424,7 @@ get_transfer() get_footprint() { - pushd $WSREP_SST_OPT_DATA 1>/dev/null + pushd "$WSREP_SST_OPT_DATA" 1>/dev/null payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c -s | awk 'END { print $1 }') if $MY_PRINT_DEFAULTS xtrabackup | grep -q -- "--compress";then # QuickLZ has around 50% compression ratio @@ -425,18 +447,18 @@ adjust_progress() return fi - if [[ -n $progress && $progress != '1' ]];then - if [[ -e $progress ]];then + if [[ -n "$progress" && "$progress" != '1' ]];then + if [[ -e "$progress" ]];then pcmd+=" 2>>$progress" else pcmd+=" 2>$progress" fi - elif [[ -z $progress && -n $rlimit ]];then + elif [[ -z "$progress" && -n "$rlimit" ]];then # When rlimit is non-zero pcmd="pv -q" fi - if [[ -n $rlimit && "$WSREP_SST_OPT_ROLE" == "donor" ]];then + if [[ -n "$rlimit" && "$WSREP_SST_OPT_ROLE" == "donor" ]];then wsrep_log_info "Rate-limiting SST to $rlimit" pcmd+=" -L \$rlimit" fi @@ -466,7 +488,7 @@ read_cnf() sdecomp=$(parse_cnf sst decompressor "") # Refer to http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html - if [[ -z $ealgo ]];then + if [[ -z "$ealgo" ]];then ealgo=$(parse_cnf sst encrypt-algo "") ekey=$(parse_cnf sst encrypt-key "") ekeyfile=$(parse_cnf sst encrypt-key-file "") @@ -510,15 +532,15 @@ get_stream() if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then strmcmd="xbstream -x" else - strmcmd="xbstream -c \${INFO_FILE}" + 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 - " + strmcmd="tar xfi -" else - strmcmd="tar cf - \${INFO_FILE} " + strmcmd="tar cf - '${INFO_FILE}'" fi fi } @@ -547,13 +569,12 @@ cleanup_joiner() wsrep_log_info "Removing the sst_in_progress file" wsrep_cleanup_progress_file fi - if [[ -n $progress && -p $progress ]];then + 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 + if [[ -n "${STATDIR:-}" ]];then + [[ -d "$STATDIR" ]] && rm -rf "$STATDIR" fi # Final cleanup @@ -586,8 +607,8 @@ cleanup_donor() wsrep_log_error "Cleanup after exit with status:$estatus" fi - if [[ -n ${XTRABACKUP_PID:-} ]];then - if check_pid $XTRABACKUP_PID + if [[ -n "${XTRABACKUP_PID:-}" ]];then + if check_pid "$XTRABACKUP_PID" then wsrep_log_error "xtrabackup process is still running. Killing... " kill_xtrabackup @@ -595,21 +616,21 @@ cleanup_donor() fi - rm -f ${DATA}/${IST_FILE} || true + rm -f "${DATA}/${IST_FILE}" || true - if [[ -n $progress && -p $progress ]];then + if [[ -n "$progress" && -p "$progress" ]];then wsrep_log_info "Cleaning up fifo file $progress" - rm -f $progress || true + rm -f "$progress" || true fi wsrep_log_info "Cleaning up temporary directories" - if [[ -n $xtmpdir ]];then - [[ -d $xtmpdir ]] && rm -rf $xtmpdir || true + if [[ -n "$xtmpdir" ]];then + [[ -d "$xtmpdir" ]] && rm -rf "$xtmpdir" || true fi - if [[ -n $itmpdir ]];then - [[ -d $itmpdir ]] && rm -rf $itmpdir || true + if [[ -n "$itmpdir" ]];then + [[ -d "$itmpdir" ]] && rm -rf "$itmpdir" || true fi # Final cleanup @@ -632,7 +653,7 @@ cleanup_donor() kill_xtrabackup() { - local PID=$(cat $XTRABACKUP_PID) + local PID=$(cat "$XTRABACKUP_PID") [ -n "$PID" -a "0" != "$PID" ] && kill $PID && (kill $PID && kill -9 $PID) || : wsrep_log_info "Removing xtrabackup pid file $XTRABACKUP_PID" rm -f "$XTRABACKUP_PID" || true @@ -642,9 +663,9 @@ kill_xtrabackup() # (regardless of timeout) wait_for_listen() { - local HOST=$1 - local PORT=$2 - local MODULE=$3 + local HOST="$1" + local PORT="$2" + local MODULE="$3" local LSOF_OUT for i in {1..300} @@ -660,10 +681,11 @@ wait_for_listen() check_extra() { local use_socket=1 - if [[ $uextra -eq 1 ]];then - if [ $(parse_cnf --mysqld thread-handling) = 'pool-of-threads'];then - local eport=$(parse_cnf --mysqld extra-port) - if [[ -n $eport ]];then + if [ $uextra -eq 1 ]; then + local thread_handling=$(parse_cnf '--mysqld' 'thread-handling') + if [ "$thread_handling" = 'pool-of-threads' ]; then + local eport=$(parse_cnf '--mysqld' 'extra-port') + 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" @@ -677,25 +699,25 @@ check_extra() 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" + if [ $use_socket -eq 1 -a -n "$WSREP_SST_OPT_SOCKET" ]; then + INNOEXTRA+=" --socket='$WSREP_SST_OPT_SOCKET'" fi } recv_joiner() { - local dir=$1 - local msg=$2 + local dir="$1" + local msg="$2" local tmt=$3 local checkf=$4 local ltcmd - if [[ ! -d ${dir} ]];then + if [[ ! -d "${dir}" ]];then # This indicates that IST is in progress return fi - pushd ${dir} 1>/dev/null + pushd "${dir}" 1>/dev/null set +e if [[ $tmt -gt 0 && -x `which timeout` ]];then @@ -736,10 +758,10 @@ recv_joiner() send_donor() { - local dir=$1 - local msg=$2 + local dir="$1" + local msg="$2" - pushd ${dir} 1>/dev/null + pushd "${dir}" 1>/dev/null set +e timeit "$msg" "$strmcmd | $tcmd; RC=( "\${PIPESTATUS[@]}" )" set -e @@ -747,7 +769,7 @@ send_donor() for ecode in "${RC[@]}";do if [[ $ecode -ne 0 ]];then - wsrep_log_error "Error while getting data from donor node: " \ + wsrep_log_error "Error while sending data to joiner node: " \ "exit codes: ${RC[@]}" exit 32 fi @@ -821,7 +843,7 @@ fi XB_REQUIRED_VERSION="2.3.5" XB_VERSION=`$INNOBACKUPEX_BIN --version 2>&1 | grep -oe '[0-9]\.[0-9][\.0-9]*' | head -n1` -if [[ -z $XB_VERSION ]]; then +if [[ -z "$XB_VERSION" ]]; then wsrep_log_error "FATAL: Cannot determine the $INNOBACKUPEX_BIN version. Needs xtrabackup-$XB_REQUIRED_VERSION or higher to perform SST" exit 2 fi @@ -841,18 +863,17 @@ fi read_cnf if ${INNOBACKUPEX_BIN} /tmp --help 2>/dev/null | grep -q -- '--version-check'; then - disver="--no-version-check" + disver='--no-version-check' fi -if [[ ${FORCE_FTWRL:-0} -eq 1 ]];then +iopts+=" --databases-exclude='lost+found'" + +if [ ${FORCE_FTWRL:-0} -eq 1 ]; then wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL" - iopts+=" --no-backup-locks " + iopts+=' --no-backup-locks' fi -INNOEXTRA="" - if [[ $ssyslog -eq 1 ]];then - if [[ ! -x `which logger` ]];then wsrep_log_error "logger not in path: $PATH. Ignoring" else @@ -874,44 +895,38 @@ if [[ $ssyslog -eq 1 ]];then INNOMOVE="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move " INNOBACKUP="2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)" fi - else - INNOAPPLY="&>\${DATA}/innobackup.prepare.log" - INNOMOVE="&>\${DATA}/innobackup.move.log" - INNOBACKUP="2>\${DATA}/innobackup.backup.log" + INNOAPPLY="&>'$DATA/innobackup.prepare.log'" + INNOMOVE="&>'$DATA/innobackup.move.log'" + INNOBACKUP="2>'$DATA/innobackup.backup.log'" fi get_stream get_transfer -INNODB_DATA_HOME_DIR=${INNODB_DATA_HOME_DIR:-""} -# Try to set INNODB_DATA_HOME_DIR from the command line: -if [ ! -z "$INNODB_DATA_HOME_DIR_ARG" ]; then - INNODB_DATA_HOME_DIR=$INNODB_DATA_HOME_DIR_ARG -fi -# if no command line arg and INNODB_DATA_HOME_DIR environment variable +# if no command line argument and INNODB_DATA_HOME_DIR environment variable # is not set, try to get it from my.cnf: if [ -z "$INNODB_DATA_HOME_DIR" ]; then - INNODB_DATA_HOME_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-data-home-dir '') -fi -if [ -z "$INNODB_DATA_HOME_DIR" ]; then - INNODB_DATA_HOME_DIR=$(parse_cnf --mysqld innodb-data-home-dir '') -fi -if [ ! -z "$INNODB_DATA_HOME_DIR" ]; then - INNOEXTRA+=" --innodb-data-home-dir=$INNODB_DATA_HOME_DIR" + INNODB_DATA_HOME_DIR=$(parse_cnf '--mysqld' 'innodb-data-home-dir') fi +OLD_PWD="$(pwd)" + if [ -n "$INNODB_DATA_HOME_DIR" ]; then # handle both relative and absolute paths - INNODB_DATA_HOME_DIR=$(cd $DATA; mkdir -p "$INNODB_DATA_HOME_DIR"; cd $INNODB_DATA_HOME_DIR; pwd -P) + INNODB_DATA_HOME_DIR=$(cd "$DATA"; mkdir -p "$INNODB_DATA_HOME_DIR"; cd "$INNODB_DATA_HOME_DIR"; pwd -P) else # default to datadir - INNODB_DATA_HOME_DIR=$(cd $DATA; pwd -P) + INNODB_DATA_HOME_DIR=$(cd "$DATA"; pwd -P) fi -INNOAPPLY="${INNOBACKUPEX_BIN} $disver $iapts \$INNOEXTRA --apply-log \$rebuildcmd \${DATA} ${INNOAPPLY}" -INNOMOVE="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} $disver $impts --move-back --force-non-empty-directories \${DATA} ${INNOMOVE}" -INNOBACKUP="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt \$itmpdir ${INNOBACKUP}" +cd "$OLD_PWD" + +setup_commands () { + INNOAPPLY="$INNOBACKUPEX_BIN $disver $iapts $INNOEXTRA --apply-log $rebuildcmd '$DATA' $INNOAPPLY" + INNOMOVE="$INNOBACKUPEX_BIN $WSREP_SST_OPT_CONF $disver $impts --move-back --force-non-empty-directories '$DATA' $INNOMOVE" + INNOBACKUP="$INNOBACKUPEX_BIN $WSREP_SST_OPT_CONF $disver $iopts $tmpopts $INNOEXTRA --galera-info --stream='$sfmt' '$itmpdir' $INNOBACKUP" +} if [ "$WSREP_SST_OPT_ROLE" = "donor" ] then @@ -920,31 +935,30 @@ then if [ $WSREP_SST_OPT_BYPASS -eq 0 ] then usrst=0 - if [[ -z $WSREP_SST_OPT_SST_VER ]];then + if [ -z "$WSREP_SST_OPT_SST_VER" ]; then wsrep_log_error "Upgrade joiner to 5.6.21 or higher for backup locks support" wsrep_log_error "The joiner is not supported for this version of donor" exit 93 fi - if [[ -z $(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE tmpdir "") && \ - -z $(parse_cnf --mysqld tmpdir "") && \ - -z $(parse_cnf xtrabackup tmpdir "") ]]; then + if [ -z "$(parse_cnf --mysqld tmpdir)" -a \ + -z "$(parse_cnf xtrabackup tmpdir)" ]; then xtmpdir=$(mktemp -d) - tmpopts=" --tmpdir=$xtmpdir" + tmpopts=" --tmpdir='$xtmpdir'" wsrep_log_info "Using $xtmpdir as xtrabackup temporary directory" fi itmpdir=$(mktemp -d) wsrep_log_info "Using $itmpdir as innobackupex temporary directory" - if [[ -n "${WSREP_SST_OPT_USER:-}" && "$WSREP_SST_OPT_USER" != "(null)" ]]; then - INNOEXTRA+=" --user=$WSREP_SST_OPT_USER" + if [ -n "$WSREP_SST_OPT_USER" ]; then + INNOEXTRA+=" --user='$WSREP_SST_OPT_USER'" usrst=1 fi - if [ -n "${WSREP_SST_OPT_PSWD:-}" ]; then - export MYSQL_PWD=$WSREP_SST_OPT_PSWD - elif [[ $usrst -eq 1 ]];then + if [ -n "$WSREP_SST_OPT_PSWD" ]; then + export MYSQL_PWD="$WSREP_SST_OPT_PSWD" + elif [ $usrst -eq 1 ]; then # Empty password, used for testing, debugging etc. unset MYSQL_PWD fi @@ -960,24 +974,24 @@ then ttcmd="$tcmd" - if [[ $encrypt -eq 1 ]];then - if [[ -n $scomp ]];then - tcmd=" \$ecmd | $scomp | $tcmd " + if [ $encrypt -eq 1 ]; then + if [ -n "$scomp" ]; then + tcmd="\$ecmd | $scomp | $tcmd" else - tcmd=" \$ecmd | $tcmd " + tcmd="\$ecmd | $tcmd" fi - elif [[ -n $scomp ]];then - tcmd=" $scomp | $tcmd " + elif [ -n "$scomp" ]; then + tcmd="$scomp | $tcmd" fi send_donor $DATA "${stagemsg}-gtid" # Restore the transport commmand to its original state tcmd="$ttcmd" - if [[ -n $progress ]];then + if [ -n "$progress" ]; then get_footprint tcmd="$pcmd | $tcmd" - elif [[ -n $rlimit ]];then + elif [ -n "$rlimit" ]; then adjust_progress tcmd="$pcmd | $tcmd" fi @@ -985,10 +999,10 @@ then wsrep_log_info "Sleeping before data transfer for SST" sleep 10 - wsrep_log_info "Streaming the backup to joiner at ${WSREP_SST_OPT_HOST} ${WSREP_SST_OPT_PORT:-4444}" + wsrep_log_info "Streaming the backup to joiner at ${WSREP_SST_OPT_HOST}:${WSREP_SST_OPT_PORT}" # Add compression to the head of the stream (if specified) - if [[ -n $scomp ]]; then + if [[ -n "$scomp" ]]; then tcmd="$scomp | $tcmd" fi @@ -997,6 +1011,7 @@ then tcmd=" \$ecmd | $tcmd " fi + setup_commands set +e timeit "${stagemsg}-SST" "$INNOBACKUP | $tcmd; RC=( "\${PIPESTATUS[@]}" )" set -e @@ -1023,18 +1038,18 @@ then echo "${WSREP_SST_OPT_GTID} ${WSREP_SST_OPT_GTID_DOMAIN_ID}" > "${MAGIC_FILE}" echo "1" > "${DATA}/${IST_FILE}" get_keys - if [[ $encrypt -eq 1 ]];then - if [[ -n $scomp ]];then - tcmd=" \$ecmd | $scomp | $tcmd " + if [ $encrypt -eq 1 ]; then + if [ -n "$scomp" ]; then + tcmd="\$ecmd | $scomp | $tcmd" else - tcmd=" \$ecmd | $tcmd " + tcmd="\$ecmd | $tcmd" fi - elif [[ -n $scomp ]];then - tcmd=" $scomp | $tcmd " + elif [ -n "$scomp" ]; then + tcmd="$scomp | $tcmd" fi strmcmd+=" \${IST_FILE}" - send_donor $DATA "${stagemsg}-IST" + send_donor "$DATA" "${stagemsg}-IST" fi @@ -1043,29 +1058,26 @@ then 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 + [[ -e "$SST_PROGRESS_FILE" ]] && wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE" + [[ -n "$SST_PROGRESS_FILE" ]] && touch "$SST_PROGRESS_FILE" - ib_home_dir=$INNODB_DATA_HOME_DIR + ib_home_dir="$INNODB_DATA_HOME_DIR" - # Try to set ib_log_dir from the command line: - ib_log_dir=$INNODB_LOG_GROUP_HOME_ARG - if [ -z "$ib_log_dir" ]; then - ib_log_dir=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-log-group-home-dir "") - fi - if [ -z "$ib_log_dir" ]; then - ib_log_dir=$(parse_cnf --mysqld innodb-log-group-home-dir "") + # if no command line argument and INNODB_LOG_GROUP_HOME is not set, + # try to get it from my.cnf: + if [ -z "$INNODB_LOG_GROUP_HOME" ]; then + INNODB_LOG_GROUP_HOME=$(parse_cnf '--mysqld' 'innodb-log-group-home-dir') fi - # Try to set ib_undo_dir from the command line: - ib_undo_dir=$INNODB_UNDO_DIR_ARG - if [ -z "$ib_undo_dir" ]; then - ib_undo_dir=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-undo-directory "") - fi - if [ -z "$ib_undo_dir" ]; then - ib_undo_dir=$(parse_cnf --mysqld innodb-undo-directory "") + ib_log_dir="$INNODB_LOG_GROUP_HOME" + + # if no command line argument then try to get it from my.cnf: + if [ -z "$INNODB_UNDO_DIR" ]; then + INNODB_UNDO_DIR=$(parse_cnf '--mysqld' 'innodb-undo-directory') fi + ib_undo_dir="$INNODB_UNDO_DIR" + stagemsg="Joiner-Recv" sencrypted=1 @@ -1076,32 +1088,32 @@ then rm -f "${DATA}/${IST_FILE}" # May need xtrabackup_checkpoints later on - rm -f ${DATA}/xtrabackup_binary ${DATA}/xtrabackup_galera_info ${DATA}/xtrabackup_logfile + rm -f "${DATA}/xtrabackup_binary" "${DATA}/xtrabackup_galera_info" "${DATA}/xtrabackup_logfile" - wait_for_listen ${WSREP_SST_OPT_HOST} ${WSREP_SST_OPT_PORT:-4444} ${MODULE} & + wait_for_listen ${WSREP_SST_OPT_HOST} ${WSREP_SST_OPT_PORT} ${MODULE} & trap sig_joiner_cleanup HUP PIPE INT TERM trap cleanup_joiner EXIT - if [[ -n $progress ]];then + if [[ -n "$progress" ]];then adjust_progress tcmd+=" | $pcmd" fi get_keys - if [[ $encrypt -eq 1 && $sencrypted -eq 1 ]];then - if [[ -n $sdecomp ]];then - strmcmd=" $sdecomp | \$ecmd | $strmcmd" + if [ $encrypt -eq 1 -a $sencrypted -eq 1 ]; then + if [ -n "$sdecomp" ]; then + strmcmd="$sdecomp | \$ecmd | $strmcmd" else - strmcmd=" \$ecmd | $strmcmd" + strmcmd="\$ecmd | $strmcmd" fi - elif [[ -n $sdecomp ]];then - strmcmd=" $sdecomp | $strmcmd" + elif [ -n "$sdecomp" ]; then + strmcmd="$sdecomp | $strmcmd" fi STATDIR=$(mktemp -d) MAGIC_FILE="${STATDIR}/${INFO_FILE}" - recv_joiner $STATDIR "${stagemsg}-gtid" $stimeout 1 + recv_joiner "$STATDIR" "${stagemsg}-gtid" $stimeout 1 if ! ps -p ${WSREP_SST_OPT_PARENT} &>/dev/null then @@ -1112,12 +1124,12 @@ then if [ ! -r "${STATDIR}/${IST_FILE}" ] then - if [[ -d ${DATA}/.sst ]];then + if [[ -d "${DATA}/.sst" ]];then wsrep_log_info "WARNING: Stale temporary SST directory: ${DATA}/.sst from previous state transfer. Removing" - rm -rf ${DATA}/.sst + rm -rf "${DATA}/.sst" fi - mkdir -p ${DATA}/.sst - (recv_joiner $DATA/.sst "${stagemsg}-SST" 0 0) & + mkdir -p "${DATA}/.sst" + (recv_joiner "$DATA/.sst" "${stagemsg}-SST" 0 0) & jpid=$! wsrep_log_info "Proceeding with SST" @@ -1128,25 +1140,19 @@ then find $ib_home_dir $ib_log_dir $ib_undo_dir $DATA -mindepth 1 -prune -regex $cpat -o -exec rm -rfv {} 1>&2 \+ fi - tempdir=$LOG_BIN_ARG - if [ -z "$tempdir" ]; then - tempdir=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE log-bin "") - fi - if [ -z "$tempdir" ]; then - tempdir=$(parse_cnf --mysqld log-bin "") - fi - 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 \+ || true - rm $binlog_dir/*.index || true - fi + get_binlog + + if [ -n "$WSREP_SST_OPT_BINLOG" ]; then + binlog_dir=$(dirname "$WSREP_SST_OPT_BINLOG") + cd "$binlog_dir" + wsrep_log_info "Cleaning the binlog directory $binlog_dir as well" + rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || true + binlog_index="${WSREP_SST_OPT_BINLOG_INDEX%.index}.index" + [ -f "$binlog_index" ] && rm -fv "$binlog_index" 1>&2 \+ || true + cd "$OLD_PWD" fi - TDATA=${DATA} + TDATA="${DATA}" DATA="${DATA}/.sst" MAGIC_FILE="${DATA}/${INFO_FILE}" @@ -1155,13 +1161,13 @@ then get_proc - if [[ ! -s ${DATA}/xtrabackup_checkpoints ]];then + if [[ ! -s "${DATA}/xtrabackup_checkpoints" ]];then wsrep_log_error "xtrabackup_checkpoints missing, failed innobackupex/SST on donor" exit 2 fi # Rebuild indexes for compact backups - if grep -q 'compact = 1' ${DATA}/xtrabackup_checkpoints;then + if grep -q 'compact = 1' "${DATA}/xtrabackup_checkpoints";then wsrep_log_info "Index compaction detected" rebuild=1 fi @@ -1169,11 +1175,11 @@ 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" + rebuildcmd="--rebuild-indexes --rebuild-threads='$nthreads'" fi - if test -n "$(find ${DATA} -maxdepth 1 -type f -name '*.qp' -print -quit)";then - + qpfiles=$(find "${DATA}" -maxdepth 1 -type f -name '*.qp' -print -quit) + if [ -n "$qpfiles" ]; then wsrep_log_info "Compressed qpress files found" if [[ ! -x `which qpress` ]];then @@ -1181,8 +1187,8 @@ then exit 22 fi - if [[ -n $progress ]] && pv --help | grep -q 'line-mode';then - count=$(find ${DATA} -type f -name '*.qp' | wc -l) + 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]'" @@ -1203,7 +1209,7 @@ then if [[ $extcode -eq 0 ]];then wsrep_log_info "Removing qpress files after decompression" - find ${DATA} -type f -name '*.qp' -delete + find "$DATA" -type f -name '*.qp' -delete if [[ $? -ne 0 ]];then wsrep_log_error "Something went wrong with deletion of qpress files. Investigate" fi @@ -1213,23 +1219,24 @@ then fi fi - if [[ ! -z $WSREP_SST_OPT_BINLOG ]];then + if [ -n "$WSREP_SST_OPT_BINLOG" ]; then - BINLOG_DIRNAME=$(dirname $WSREP_SST_OPT_BINLOG) - BINLOG_FILENAME=$(basename $WSREP_SST_OPT_BINLOG) + BINLOG_DIRNAME=$(dirname "$WSREP_SST_OPT_BINLOG") + BINLOG_FILENAME=$(basename "$WSREP_SST_OPT_BINLOG") # To avoid comparing data directory and BINLOG_DIRNAME - mv $DATA/${BINLOG_FILENAME}.* $BINLOG_DIRNAME/ 2>/dev/null || true + mv "$DATA/$BINLOG_FILENAME".* "$BINLOG_DIRNAME/" 2>/dev/null || true - pushd $BINLOG_DIRNAME &>/dev/null - for bfiles in $(ls -1 ${BINLOG_FILENAME}.[0-9]*);do - echo ${BINLOG_DIRNAME}/${bfiles} >> ${BINLOG_FILENAME}.index + cd "$BINLOG_DIRNAME" + for bfile in $(ls -1 "$BINLOG_FILENAME".[0-9]*); do + echo "$BINLOG_DIRNAME/$bfile" >> "${WSREP_SST_OPT_BINLOG_INDEX%.index}.index" done - popd &> /dev/null + cd "$OLD_PWD" fi wsrep_log_info "Preparing the backup at ${DATA}" + setup_commands timeit "Xtrabackup prepare stage" "$INNOAPPLY" if [ $? -ne 0 ]; @@ -1240,14 +1247,14 @@ then MAGIC_FILE="${TDATA}/${INFO_FILE}" set +e - rm $TDATA/innobackup.prepare.log $TDATA/innobackup.move.log + 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} + 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" @@ -1258,7 +1265,7 @@ then wsrep_log_info "${IST_FILE} received from donor: Running IST" fi - if [[ ! -r ${MAGIC_FILE} ]];then + if [[ ! -r "${MAGIC_FILE}" ]];then wsrep_log_error "SST magic file ${MAGIC_FILE} not found/readable" exit 2 fi diff --git a/scripts/wsrep_sst_xtrabackup.sh b/scripts/wsrep_sst_xtrabackup.sh index d0083a8eea0..b8ca7f43ed6 100644 --- a/scripts/wsrep_sst_xtrabackup.sh +++ b/scripts/wsrep_sst_xtrabackup.sh @@ -1,5 +1,6 @@ #!/bin/bash -ue # Copyright (C) 2013 Percona Inc +# Copyright (C) 2017-2021 MariaDB # # 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 @@ -19,6 +20,7 @@ # Make sure to read that before proceeding! . $(dirname $0)/wsrep_sst_common +wsrep_check_datadir ealgo="" ekey="" @@ -131,7 +133,7 @@ get_keys() get_transfer() { - TSST_PORT=${WSREP_SST_OPT_PORT:-4444} + TSST_PORT=$WSREP_SST_OPT_PORT if [[ $tfmt == 'nc' ]];then if [[ ! -x `which nc` ]];then @@ -406,7 +408,6 @@ read_cnf get_stream get_transfer -INNOEXTRA="" INNOAPPLY="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} --apply-log \$rebuildcmd \${DATA} &>\${DATA}/innobackup.prepare.log" INNOBACKUP="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} \$INNOEXTRA --galera-info --stream=\$sfmt \${TMPDIR} 2>\${DATA}/innobackup.backup.log" @@ -419,14 +420,14 @@ then usrst=0 TMPDIR="${TMPDIR:-/tmp}" - if [[ -n "${WSREP_SST_OPT_USER:-}" && "$WSREP_SST_OPT_USER" != "(null)" ]]; then + if [ -n "$WSREP_SST_OPT_USER" ]; then INNOEXTRA+=" --user=$WSREP_SST_OPT_USER" usrst=1 fi - if [ -n "${WSREP_SST_OPT_PSWD:-}" ]; then + if [ -n "$WSREP_SST_OPT_PSWD" ]; then INNOEXTRA+=" --password=$WSREP_SST_OPT_PSWD" - elif [[ $usrst -eq 1 ]];then + elif [ $usrst -eq 1 ]; then # Empty password, used for testing, debugging etc. INNOEXTRA+=" --password=" fi @@ -528,9 +529,9 @@ then # May need xtrabackup_checkpoints later on rm -f ${DATA}/xtrabackup_binary ${DATA}/xtrabackup_galera_info ${DATA}/xtrabackup_logfile - ADDR="${WSREP_SST_OPT_HOST}:${WSREP_SST_OPT_PORT:-4444}" + ADDR="${WSREP_SST_OPT_HOST}:${WSREP_SST_OPT_PORT}" - wait_for_listen ${WSREP_SST_OPT_PORT:-4444} ${ADDR} ${MODULE} & + wait_for_listen ${WSREP_SST_OPT_PORT} ${ADDR} ${MODULE} & trap sig_joiner_cleanup HUP PIPE INT TERM trap cleanup_joiner EXIT -- cgit v1.2.1 From 5ad7f52558cb283c685322df1fcdbd10daf3c3ae Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 3 May 2021 23:26:30 +0200 Subject: MDEV-21603 Crashing SHOW TABLES with derived table in WHERE condition When you only need view structure, don't call handle_derived with DT_CREATE and rely on its internal hackish check to skip DT_CREATE. Because handle_derived is called from many different places, and this internal hackish check is indiscriminative. Instead, just don't ask handle_derived to do DT_CREATE if you don't want it to do DT_CREATE. --- mysql-test/r/show.result | 32 ++++++++++++++++++++++++++++++++ mysql-test/t/show.test | 34 +++++++++++++++++++++++++++++----- sql/sql_base.cc | 1 - sql/sql_class.h | 4 ---- sql/sql_derived.cc | 7 ------- sql/sql_prepare.cc | 8 ++++---- sql/sql_show.cc | 4 ++-- 7 files changed, 67 insertions(+), 23 deletions(-) diff --git a/mysql-test/r/show.result b/mysql-test/r/show.result index 3dd7af5de05..d1b373d8969 100644 --- a/mysql-test/r/show.result +++ b/mysql-test/r/show.result @@ -1,3 +1,8 @@ +# +# MDEV-9538 Server crashes in check_show_access on SHOW STATISTICS +# MDEV-9539 Server crashes in make_columns_old_format on SHOW GEOMETRY_COLUMNS +# MDEV-9540 SHOW SPATIAL_REF_SYS and SHOW SYSTEM_VARIABLES return empty results with numerous warnings +# show statistics; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'statistics' at line 1 show spatial_ref_sys @@ -10,3 +15,30 @@ show geometry_columns; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'geometry_columns' at line 1 show nonexistent; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'nonexistent' at line 1 +# +# MDEV-21603 Crashing SHOW TABLES with derived table in WHERE condition +# +create table t1 (nm varchar(32), a int); +insert t1 values ('1',1),('2',2),('3',3); +show tables +where tables_in_test in (select * +from (select nm from test.t1 group by nm) dt); +Tables_in_test +show fields from test.t1 +where field in (select * from (select nm from test.t1 group by nm) dt); +Field Type Null Key Default Extra +insert t1 values ('nm',0); +show fields from test.t1 +where field in (select * from (select nm from test.t1 group by nm) dt); +Field Type Null Key Default Extra +nm varchar(32) YES NULL +show fields from test.t1 where field in +(select * from (select column_name from information_schema.columns +where table_name='t1' group by column_name) dt); +Field Type Null Key Default Extra +nm varchar(32) YES NULL +a int(11) YES NULL +drop table t1; +# +# End of 10.2 tests +# diff --git a/mysql-test/t/show.test b/mysql-test/t/show.test index 3101f443264..f2f6efc4e45 100644 --- a/mysql-test/t/show.test +++ b/mysql-test/t/show.test @@ -1,8 +1,8 @@ -# -# MDEV-9538 Server crashes in check_show_access on SHOW STATISTICS -# MDEV-9539 Server crashes in make_columns_old_format on SHOW GEOMETRY_COLUMNS -# MDEV-9540 SHOW SPATIAL_REF_SYS and SHOW SYSTEM_VARIABLES return empty results with numerous warnings -# +--echo # +--echo # MDEV-9538 Server crashes in check_show_access on SHOW STATISTICS +--echo # MDEV-9539 Server crashes in make_columns_old_format on SHOW GEOMETRY_COLUMNS +--echo # MDEV-9540 SHOW SPATIAL_REF_SYS and SHOW SYSTEM_VARIABLES return empty results with numerous warnings +--echo # --error ER_PARSE_ERROR show statistics; --error ER_PARSE_ERROR @@ -13,3 +13,27 @@ show system_variables; show geometry_columns; --error ER_PARSE_ERROR show nonexistent; + +--echo # +--echo # MDEV-21603 Crashing SHOW TABLES with derived table in WHERE condition +--echo # +create table t1 (nm varchar(32), a int); +insert t1 values ('1',1),('2',2),('3',3); + +show tables + where tables_in_test in (select * + from (select nm from test.t1 group by nm) dt); +show fields from test.t1 + where field in (select * from (select nm from test.t1 group by nm) dt); +insert t1 values ('nm',0); +show fields from test.t1 + where field in (select * from (select nm from test.t1 group by nm) dt); + +show fields from test.t1 where field in + (select * from (select column_name from information_schema.columns + where table_name='t1' group by column_name) dt); +drop table t1; + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 3403f9e03ff..16689f86c4e 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4939,7 +4939,6 @@ bool open_normal_and_derived_tables(THD *thd, TABLE_LIST *tables, uint flags, uint counter; MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint(); DBUG_ENTER("open_normal_and_derived_tables"); - DBUG_ASSERT(!thd->fill_derived_tables()); if (open_tables(thd, &tables, &counter, flags, &prelocking_strategy) || mysql_handle_derived(thd->lex, dt_phases)) goto end; diff --git a/sql/sql_class.h b/sql/sql_class.h index ce4bf67e745..e08bb3e6358 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3469,10 +3469,6 @@ public: { return server_status & SERVER_STATUS_IN_TRANS; } - inline bool fill_derived_tables() - { - return !stmt_arena->is_stmt_prepare() && !lex->only_view_structure(); - } inline bool fill_information_schema_tables() { return !stmt_arena->is_stmt_prepare(); diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 5f90f2f9ab0..3ab93840d80 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -70,7 +70,6 @@ bool mysql_handle_derived(LEX *lex, uint phases) { bool res= FALSE; - THD *thd= lex->thd; DBUG_ENTER("mysql_handle_derived"); DBUG_PRINT("enter", ("phases: 0x%x", phases)); if (!lex->derived_tables) @@ -85,8 +84,6 @@ mysql_handle_derived(LEX *lex, uint phases) break; if (!(phases & phase_flag)) continue; - if (phase_flag >= DT_CREATE && !thd->fill_derived_tables()) - break; for (SELECT_LEX *sl= lex->all_selects_list; sl && !res; @@ -169,7 +166,6 @@ bool mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases) { bool res= FALSE; - THD *thd= lex->thd; uint8 allowed_phases= (derived->is_merged_derived() ? DT_PHASES_MERGE : DT_PHASES_MATERIALIZE); DBUG_ENTER("mysql_handle_single_derived"); @@ -192,8 +188,6 @@ mysql_handle_single_derived(LEX *lex, TABLE_LIST *derived, uint phases) if (phase_flag != DT_PREPARE && !(allowed_phases & phase_flag)) continue; - if (phase_flag >= DT_CREATE && !thd->fill_derived_tables()) - break; if ((res= (*processors[phase])(lex->thd, lex, derived))) break; @@ -1376,4 +1370,3 @@ bool pushdown_cond_for_derived(THD *thd, Item *cond, TABLE_LIST *derived) thd->lex->current_select= save_curr_select; DBUG_RETURN(false); } - diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 56a38757f28..a8a671075f9 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1659,7 +1659,7 @@ static int mysql_test_select(Prepared_statement *stmt, } if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL, - DT_INIT | DT_PREPARE | DT_CREATE)) + DT_INIT | DT_PREPARE)) goto error; thd->lex->used_tables= 0; // Updated by setup_fields @@ -1721,7 +1721,7 @@ static bool mysql_test_do_fields(Prepared_statement *stmt, DBUG_RETURN(TRUE); if (open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL, - DT_INIT | DT_PREPARE | DT_CREATE)) + DT_INIT | DT_PREPARE)) DBUG_RETURN(TRUE); DBUG_RETURN(setup_fields(thd, Ref_ptr_array(), *values, MARK_COLUMNS_NONE, 0, NULL, 0)); @@ -1753,7 +1753,7 @@ static bool mysql_test_set_fields(Prepared_statement *stmt, if ((tables && check_table_access(thd, SELECT_ACL, tables, FALSE, UINT_MAX, FALSE)) || open_normal_and_derived_tables(thd, tables, MYSQL_OPEN_FORCE_SHARED_MDL, - DT_INIT | DT_PREPARE | DT_CREATE)) + DT_INIT | DT_PREPARE)) goto error; while ((var= it++)) @@ -1918,7 +1918,7 @@ static bool mysql_test_create_table(Prepared_statement *stmt) if (open_normal_and_derived_tables(stmt->thd, lex->query_tables, MYSQL_OPEN_FORCE_SHARED_MDL, - DT_INIT | DT_PREPARE | DT_CREATE)) + DT_INIT | DT_PREPARE)) DBUG_RETURN(TRUE); select_lex->context.resolve_in_select_list= TRUE; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 7023e5fe9ea..b5622497a06 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1528,7 +1528,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild) if (open_normal_and_derived_tables(thd, table_list, MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL, - DT_INIT | DT_PREPARE | DT_CREATE)) + DT_INIT | DT_PREPARE)) DBUG_VOID_RETURN; table= table_list->table; @@ -4414,7 +4414,7 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL | (can_deadlock ? MYSQL_OPEN_FAIL_ON_MDL_CONFLICT : 0)), - DT_INIT | DT_PREPARE | DT_CREATE)); + DT_INIT | DT_PREPARE)); /* Restore old value of sql_command back as it is being looked at in -- cgit v1.2.1 From 625e44a80d3ca40d4164c2092acdcaeb788d3482 Mon Sep 17 00:00:00 2001 From: Sujatha Date: Wed, 5 May 2021 15:46:22 +0530 Subject: MDEV-25597: Disable rpl_semi_sync_slave_compressed_protocol.test --- mysql-test/suite/rpl/disabled.def | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/suite/rpl/disabled.def b/mysql-test/suite/rpl/disabled.def index f446aa6a2aa..94073575606 100644 --- a/mysql-test/suite/rpl/disabled.def +++ b/mysql-test/suite/rpl/disabled.def @@ -15,3 +15,4 @@ rpl_partition_archive : MDEV-5077 2013-09-27 svoj Cannot exchange partition rpl_row_binlog_max_cache_size : MDEV-11092 rpl_row_index_choice : MDEV-11666 rpl_semi_sync_after_sync : fails after MDEV-16172 +rpl_semi_sync_slave_compressed_protocol : MDEV-25580 2021-05-05 Sujatha -- cgit v1.2.1 From 6895c9eaa0145f1cce43dc63f4ca7a6dfc913127 Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Wed, 5 May 2021 03:17:51 +0200 Subject: MDEV-24962 addendum: mariabackup does not understand --log-bin-index and --log-basename options --- scripts/wsrep_sst_common.sh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index 9e6807e20a3..3c0fbfff058 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -349,7 +349,7 @@ case "$1" in fi shift done - readonly WSREP_SST_OPT_MYSQLD="$original_cmd" + WSREP_SST_OPT_MYSQLD="$original_cmd" break ;; *) # must be command @@ -410,7 +410,11 @@ fi # Reconstructing the command line arguments that control the innodb # and binlog options: if [ -n "$WSREP_SST_OPT_LOG_BASENAME" ]; then - INNOEXTRA="$INNOEXTRA --log-basename='$WSREP_SST_OPT_LOG_BASENAME'" + if [ -n "$WSREP_SST_OPT_MYSQLD" ]; then + WSREP_SST_OPT_MYSQLD="--log-basename='$WSREP_SST_OPT_LOG_BASENAME' $WSREP_SST_OPT_MYSQLD" + else + WSREP_SST_OPT_MYSQLD="--log-basename='$WSREP_SST_OPT_LOG_BASENAME'" + fi fi if [ -n "$INNODB_DATA_HOME_DIR" ]; then INNOEXTRA="$INNOEXTRA --innodb-data-home-dir='$INNODB_DATA_HOME_DIR'" @@ -424,10 +428,16 @@ fi if [ -n "$WSREP_SST_OPT_BINLOG" ]; then INNOEXTRA="$INNOEXTRA --log-bin='$WSREP_SST_OPT_BINLOG'" if [ -n "$WSREP_SST_OPT_BINLOG_INDEX" ]; then - INNOEXTRA="$INNOEXTRA --log-bin-index='$WSREP_SST_OPT_BINLOG_INDEX'" + if [ -n "$WSREP_SST_OPT_MYSQLD" ]; then + WSREP_SST_OPT_MYSQLD="--log-bin-index='$WSREP_SST_OPT_BINLOG_INDEX' $WSREP_SST_OPT_MYSQLD" + else + WSREP_SST_OPT_MYSQLD="--log-bin-index='$WSREP_SST_OPT_BINLOG_INDEX'" + fi fi fi +readonly WSREP_SST_OPT_MYSQLD + get_binlog() { # if no command line argument and WSREP_SST_OPT_BINLOG is not set, -- cgit v1.2.1 From ee1e877470715f0626529e0499c6ddfd4187e941 Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Thu, 6 May 2021 01:16:52 +0200 Subject: MDEV-24962 addendum: improved handling of paths with spaces --- scripts/wsrep_sst_common.sh | 2 +- scripts/wsrep_sst_rsync.sh | 28 +++++++++++++++------------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index 3c0fbfff058..082873dff3c 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -747,7 +747,7 @@ wsrep_check_programs() while [ $# -gt 0 ] do - wsrep_check_program $1 || ret=$? + wsrep_check_program "$1" || ret=$? shift done diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index 92fdc28f643..8db5dbb5e40 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -225,11 +225,11 @@ check_server_ssl_config() SSLMODE=$(parse_cnf 'sst' 'ssl-mode' | tr [:lower:] [:upper:]) -if [ -z "$SSTKEY" -a -z "$SSTCERT" ] +if [ -z "$SSTKEY" -a -z "$SSTCERT" -a -z "$SSTCA" ] then # no old-style SSL config in [sst], check for new one check_server_ssl_config 'sst' - if [ -z "$SSTKEY" -a -z "$SSTCERT" ]; then + if [ -z "$SSTKEY" -a -z "$SSTCERT" -a -z "$SSTCA" ]; then check_server_ssl_config '--mysqld' fi fi @@ -279,7 +279,7 @@ fi STUNNEL="" if [ -n "$SSLMODE" -a "$SSLMODE" != 'DISABLED' ] && wsrep_check_programs stunnel then - wsrep_log_info "Using stunnel for SSL encryption: CAfile: $SSTCA, SSLMODE: $SSLMODE" + wsrep_log_info "Using stunnel for SSL encryption: CAfile: '$SSTCA', SSLMODE: '$SSLMODE'" STUNNEL="stunnel $STUNNEL_CONF" fi @@ -365,11 +365,11 @@ EOF # first, the normal directories, so that we can detect incompatible protocol RC=0 - eval rsync ${STUNNEL:+--rsh=\"$STUNNEL\"} \ + eval rsync "'${STUNNEL:+--rsh=$STUNNEL}'" \ --owner --group --perms --links --specials \ --ignore-times --inplace --dirs --delete --quiet \ - $WHOLE_FILE_OPT ${FILTER} "$WSREP_SST_OPT_DATA/" \ - rsync://$WSREP_SST_OPT_ADDR >&2 || RC=$? + $WHOLE_FILE_OPT ${FILTER} "'$WSREP_SST_OPT_DATA/'" \ + "'rsync://$WSREP_SST_OPT_ADDR'" >&2 || RC=$? if [ $RC -ne 0 ]; then wsrep_log_error "rsync returned code $RC:" @@ -394,7 +394,7 @@ EOF --ignore-times --inplace --dirs --delete --quiet \ $WHOLE_FILE_OPT -f '+ /ibdata*' -f '+ /ib_lru_dump' \ -f '- **' "$INNODB_DATA_HOME_DIR/" \ - rsync://$WSREP_SST_OPT_ADDR-data_dir >&2 || RC=$? + "rsync://$WSREP_SST_OPT_ADDR-data_dir" >&2 || RC=$? if [ $RC -ne 0 ]; then wsrep_log_error "rsync innodb_data_home_dir returned code $RC:" @@ -405,8 +405,9 @@ EOF rsync ${STUNNEL:+--rsh="$STUNNEL"} \ --owner --group --perms --links --specials \ --ignore-times --inplace --dirs --delete --quiet \ - $WHOLE_FILE_OPT -f '+ /ib_logfile[0-9]*' -f '+ /aria_log.*' -f '+ /aria_log_control' -f '- **' "$WSREP_LOG_DIR/" \ - rsync://$WSREP_SST_OPT_ADDR-log_dir >&2 || RC=$? + $WHOLE_FILE_OPT -f '+ /ib_logfile[0-9]*' -f '+ /aria_log.*' \ + -f '+ /aria_log_control' -f '- **' "$WSREP_LOG_DIR/" \ + "rsync://$WSREP_SST_OPT_ADDR-log_dir" >&2 || RC=$? if [ $RC -ne 0 ]; then wsrep_log_error "rsync innodb_log_group_home_dir returned code $RC:" @@ -425,8 +426,9 @@ EOF rsync ${STUNNEL:+--rsh="$STUNNEL"} \ --owner --group --perms --links --specials \ --ignore-times --inplace --recursive --delete --quiet \ - $WHOLE_FILE_OPT --exclude '*/ib_logfile*' --exclude "*/aria_log.*" --exclude "*/aria_log_control" "$WSREP_SST_OPT_DATA"/{}/ \ - rsync://$WSREP_SST_OPT_ADDR/{} >&2 || RC=$? + $WHOLE_FILE_OPT --exclude '*/ib_logfile*' --exclude '*/aria_log.*' \ + --exclude '*/aria_log_control' "$WSREP_SST_OPT_DATA/"{}"/" \ + "rsync://$WSREP_SST_OPT_ADDR/"{} >&2 || RC=$? cd "$OLD_PWD" @@ -455,7 +457,7 @@ EOF fi rsync ${STUNNEL:+--rsh="$STUNNEL"} \ - --archive --quiet --checksum "$MAGIC_FILE" rsync://$WSREP_SST_OPT_ADDR + --archive --quiet --checksum "$MAGIC_FILE" "rsync://$WSREP_SST_OPT_ADDR" echo "done $STATE" @@ -547,7 +549,7 @@ client = no [rsync] accept = $STUNNEL_ACCEPT exec = $(command -v rsync) -execargs = rsync --server --daemon --config='$RSYNC_CONF' . +execargs = rsync --server --daemon --config=$RSYNC_CONF . EOF stunnel "$STUNNEL_CONF" & RSYNC_REAL_PID=$! -- cgit v1.2.1 From cf67ca48d6731ba43dcde385991ae1efaff40675 Mon Sep 17 00:00:00 2001 From: Alexey Yurchenko Date: Sun, 25 Apr 2021 18:06:53 +0300 Subject: MDEV-25418 rsync SST does not work with stunnel encryption 1. Fix eval command line to correctly pass stunnel option to rsync on donor. 2. Deprecate `tkey`, `tcert` and `tca` options in [sst] section in favor of conventional `ssl-key`, `ssl-cert` and `ssl-ca`, but keep their precedence for backward compatibility. 3. Default to require SSL encryption if at least SSL key and cert files are specified in configuration, either in [sst] or [mysqld] sections. 4. Enable `verify*` option for stunnel on donor only if a. CA file is specified somewhere in the configuration b. it is explicitly requested in [sst] section by either specifying ssl-mode or CA file there. In this case if ssl-mode is not explicitly given, it defaults to VERIFY_CA. ssl-mode maps to stunnel options as follows: VERIFY_CA -> verifyChain = yes VERIFY_IDENTITY -> verifyPeer = yes Example to require donor to verify joiner identity: ``` [mysqld] ssl-cert=/path/to/cert ssl-key=/path/to/key ssl-ca=/path/to/ca [sst] ssl-mode=VERIFY_IDENTITY ``` 5. If SSL verification is requested, joiner verifies donor by checking the secret passed to donor via SST request. Signed-off-by: Julius Goryavsky --- .../r/galera_sst_rsync_encrypt_with_key.result | 400 +++++++++++++++++++++ .../r/galera_sst_rsync_encrypt_with_server.result | 400 +++++++++++++++++++++ .../galera/t/galera_sst_rsync_encrypt_with_key.cnf | 15 + .../t/galera_sst_rsync_encrypt_with_key.test | 28 ++ .../t/galera_sst_rsync_encrypt_with_server.cnf | 17 + .../t/galera_sst_rsync_encrypt_with_server.test | 28 ++ 6 files changed, 888 insertions(+) create mode 100644 mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result create mode 100644 mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result create mode 100644 mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.cnf create mode 100644 mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test create mode 100644 mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.cnf create mode 100644 mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result new file mode 100644 index 00000000000..251c087412b --- /dev/null +++ b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_key.result @@ -0,0 +1,400 @@ +connection node_1; +connection node_2; +connection node_2; +CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); +connection node_1; +Performing State Transfer on a server that has been shut down cleanly and restarted +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +Shutting down server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_shutdown_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Starting server ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_shutdown_slave; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +Performing State Transfer on a server that starts from a clean var directory +This is accomplished by shutting down node #2 and removing its var directory before restarting it +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +Shutting down server ... +connection node_1; +Cleaning var directory ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_clean_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Starting server ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_clean_slave; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +Performing State Transfer on a server that has been killed and restarted +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +Killing server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_kill_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Performing --wsrep-recover ... +Starting server ... +Using --wsrep-start-position when starting mysqld ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_kill_slave; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +Performing State Transfer on a server that has been killed and restarted +while a DDL was in progress on it +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +connection node_2; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +SET GLOBAL debug_dbug = 'd,sync.alter_opened_table'; +connection node_1; +ALTER TABLE t1 ADD COLUMN f2 INTEGER; +connection node_2; +SET wsrep_sync_wait = 0; +Killing server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_kill_slave_ddl, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Performing --wsrep-recover ... +connection node_2; +Starting server ... +Using --wsrep-start-position when starting mysqld ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_kill_slave_ddl; +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +COUNT(*) = 2 +1 +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +COUNT(*) = 2 +1 +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +SET GLOBAL debug_dbug = $debug_orig; +include/assert_grep.inc [Using stunnel for SSL encryption] diff --git a/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result new file mode 100644 index 00000000000..251c087412b --- /dev/null +++ b/mysql-test/suite/galera/r/galera_sst_rsync_encrypt_with_server.result @@ -0,0 +1,400 @@ +connection node_1; +connection node_2; +connection node_2; +CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); +connection node_1; +Performing State Transfer on a server that has been shut down cleanly and restarted +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +Shutting down server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_shutdown_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Starting server ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_shutdown_slave; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +Performing State Transfer on a server that starts from a clean var directory +This is accomplished by shutting down node #2 and removing its var directory before restarting it +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +Shutting down server ... +connection node_1; +Cleaning var directory ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_clean_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Starting server ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_clean_slave; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +Performing State Transfer on a server that has been killed and restarted +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +COMMIT; +connection node_2; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +Killing server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +INSERT INTO t1 VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_kill_slave, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Performing --wsrep-recover ... +Starting server ... +Using --wsrep-start-position when starting mysqld ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +INSERT INTO t1 VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +INSERT INTO t1 VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_kill_slave; +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +Performing State Transfer on a server that has been killed and restarted +while a DDL was in progress on it +connection node_1; +CREATE TABLE t1 (f1 CHAR(255)) ENGINE=InnoDB; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +INSERT INTO t1 VALUES ('node1_committed_before'); +connection node_2; +START TRANSACTION; +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +INSERT INTO t1 VALUES ('node2_committed_before'); +COMMIT; +SET GLOBAL debug_dbug = 'd,sync.alter_opened_table'; +connection node_1; +ALTER TABLE t1 ADD COLUMN f2 INTEGER; +connection node_2; +SET wsrep_sync_wait = 0; +Killing server ... +connection node_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +INSERT INTO t1 (f1) VALUES ('node1_committed_during'); +COMMIT; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +connect node_1a_galera_st_kill_slave_ddl, 127.0.0.1, root, , test, $NODE_MYPORT_1; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +connection node_2; +Performing --wsrep-recover ... +connection node_2; +Starting server ... +Using --wsrep-start-position when starting mysqld ... +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +INSERT INTO t1 (f1) VALUES ('node2_committed_after'); +COMMIT; +connection node_1; +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_committed_after'); +COMMIT; +SET AUTOCOMMIT=OFF; +START TRANSACTION; +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +INSERT INTO t1 (f1) VALUES ('node1_committed_after'); +COMMIT; +connection node_1a_galera_st_kill_slave_ddl; +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +INSERT INTO t1 (f1) VALUES ('node1_to_be_rollbacked_after'); +ROLLBACK; +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +COUNT(*) = 2 +1 +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +COMMIT; +SET AUTOCOMMIT=ON; +connection node_1; +SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 't1'; +COUNT(*) = 2 +1 +SELECT COUNT(*) = 35 FROM t1; +COUNT(*) = 35 +1 +SELECT COUNT(*) = 0 FROM (SELECT COUNT(*) AS c, f1 FROM t1 GROUP BY f1 HAVING c NOT IN (5, 10)) AS a1; +COUNT(*) = 0 +1 +DROP TABLE t1; +COMMIT; +SET AUTOCOMMIT=ON; +SET GLOBAL debug_dbug = $debug_orig; +include/assert_grep.inc [Using stunnel for SSL encryption] diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.cnf b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.cnf new file mode 100644 index 00000000000..f131088f582 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.cnf @@ -0,0 +1,15 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep_sst_method=rsync + +[sst] +tkey=@ENV.MYSQL_TEST_DIR/std_data/server-key.pem +tcert=@ENV.MYSQL_TEST_DIR/std_data/server-cert.pem + +[mysqld.1] +wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true' + +[mysqld.2] +wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true' + diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test new file mode 100644 index 00000000000..505f7e7626d --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_key.test @@ -0,0 +1,28 @@ +--source include/big_test.inc +--source include/galera_cluster.inc +--source include/have_debug.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--source include/auto_increment_offset_save.inc + +--connection node_2 +CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); + +--connection node_1 +--source suite/galera/include/galera_st_shutdown_slave.inc +--source suite/galera/include/galera_st_clean_slave.inc + +--source suite/galera/include/galera_st_kill_slave.inc +--source suite/galera/include/galera_st_kill_slave_ddl.inc + +# Confirm that transfer was SSL-encrypted +--let $assert_text = Using stunnel for SSL encryption +--let $assert_select = Using stunnel for SSL encryption +--let $assert_count = 5 +--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err +--let $assert_only_after = CURRENT_TEST +--source include/assert_grep.inc + +--source include/auto_increment_offset_restore.inc diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.cnf b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.cnf new file mode 100644 index 00000000000..8e31e69a590 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.cnf @@ -0,0 +1,17 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep_sst_method=rsync +ssl-cert=@ENV.MYSQL_TEST_DIR/std_data/client-cert.pem +ssl-key=@ENV.MYSQL_TEST_DIR/std_data/client-key.pem +ssl-ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem + +[sst] +ssl-mode=VERIFY_CA + +[mysqld.1] +wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore_sb=true' + +[mysqld.2] +wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true' + diff --git a/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test new file mode 100644 index 00000000000..505f7e7626d --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sst_rsync_encrypt_with_server.test @@ -0,0 +1,28 @@ +--source include/big_test.inc +--source include/galera_cluster.inc +--source include/have_debug.inc + +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--source include/auto_increment_offset_save.inc + +--connection node_2 +CALL mtr.add_suppression("\\[ERROR\\] .*ib_buffer_pool' for reading: No such file or directory"); + +--connection node_1 +--source suite/galera/include/galera_st_shutdown_slave.inc +--source suite/galera/include/galera_st_clean_slave.inc + +--source suite/galera/include/galera_st_kill_slave.inc +--source suite/galera/include/galera_st_kill_slave_ddl.inc + +# Confirm that transfer was SSL-encrypted +--let $assert_text = Using stunnel for SSL encryption +--let $assert_select = Using stunnel for SSL encryption +--let $assert_count = 5 +--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err +--let $assert_only_after = CURRENT_TEST +--source include/assert_grep.inc + +--source include/auto_increment_offset_restore.inc -- cgit v1.2.1 From 54d7ba96093475240c666d2964384d358d9f9b54 Mon Sep 17 00:00:00 2001 From: Alexey Yurchenko Date: Thu, 6 May 2021 04:03:07 +0200 Subject: MDEV-25418: Improve mariabackup SST script compliance with native MariaDB SSL practices and configuration. 1. Pass joiner's authentication information to donor together with address in State Transfer Request. This allows joiner to authenticate donor on connection. Previously joiner would accept data from anywhere. 2. Deprecate custom SSL configuration variables tca, tcert and tkey in favor of more familiar ssl-ca, ssl-cert and ssl-key. For backward compatibility tca, tcert and tkey are still supported. 3. Allow falling back to server-wide SSL configuration in [mysqld] if no SSL configuration is found in [sst] section of the config file. 4. Introduce ssl-mode variable in [sst] section that takes standard values and has following effects: - old-style SSL configuration present in [sst]: no effect otherwise: - ssl-mode=DISABLED or absent: retains old, backward compatible behavior and ignores any other SSL configuration - ssl-mode=VERIFY*: verify joiner's certificate and CN on donor, verify donor's secret on joiner (passed to donor via State Transfer Request) BACKWARD INCOMPATIBLE BEHAVIOR - anything else enables new SSL configuration convetions but does not require verification ssl-mode should be set to VERIFY only in a fully upgraded cluster. Examples: [mysqld] ssl-cert=/path/to/cert ssl-key=/path/to/key ssl-ca=/path/to/ca [sst] -- server-wide SSL configuration is ignored, SST does not use SSL [mysqld] ssl-cert=/path/to/cert ssl-key=/path/to/key ssl-ca=/path/to/ca [sst] ssl-mode=REQUIRED -- use server-wide SSL configuration for SST but don't attempt to verify the peer identity [sst] ssl-cert=/path/to/cert ssl-key=/path/to/key ssl-ca=/path/to/ca ssl-mode=VERIFY_CA -- use SST-specific SSL configuration for SST and require verification on both sides Signed-off-by: Julius Goryavsky --- .../galera_sst_mariabackup_encrypt_with_key.result | 1 + ..._sst_mariabackup_encrypt_with_key_server.result | 4 + .../t/galera_sst_mariabackup_encrypt_with_key.test | 14 +++- ...era_sst_mariabackup_encrypt_with_key_server.cnf | 13 +++ ...ra_sst_mariabackup_encrypt_with_key_server.test | 25 ++++++ sql/wsrep_sst.cc | 95 ++++++++++++---------- 6 files changed, 106 insertions(+), 46 deletions(-) create mode 100644 mysql-test/suite/galera/r/galera_sst_mariabackup_encrypt_with_key_server.result create mode 100644 mysql-test/suite/galera/t/galera_sst_mariabackup_encrypt_with_key_server.cnf create mode 100644 mysql-test/suite/galera/t/galera_sst_mariabackup_encrypt_with_key_server.test diff --git a/mysql-test/suite/galera/r/galera_sst_mariabackup_encrypt_with_key.result b/mysql-test/suite/galera/r/galera_sst_mariabackup_encrypt_with_key.result index 990e0a29506..8048cafecd8 100644 --- a/mysql-test/suite/galera/r/galera_sst_mariabackup_encrypt_with_key.result +++ b/mysql-test/suite/galera/r/galera_sst_mariabackup_encrypt_with_key.result @@ -1,3 +1,4 @@ SELECT 1; 1 1 +include/assert_grep.inc [Using openssl based encryption with socat] diff --git a/mysql-test/suite/galera/r/galera_sst_mariabackup_encrypt_with_key_server.result b/mysql-test/suite/galera/r/galera_sst_mariabackup_encrypt_with_key_server.result new file mode 100644 index 00000000000..8048cafecd8 --- /dev/null +++ b/mysql-test/suite/galera/r/galera_sst_mariabackup_encrypt_with_key_server.result @@ -0,0 +1,4 @@ +SELECT 1; +1 +1 +include/assert_grep.inc [Using openssl based encryption with socat] diff --git a/mysql-test/suite/galera/t/galera_sst_mariabackup_encrypt_with_key.test b/mysql-test/suite/galera/t/galera_sst_mariabackup_encrypt_with_key.test index 4449ea43c43..523d44102dd 100644 --- a/mysql-test/suite/galera/t/galera_sst_mariabackup_encrypt_with_key.test +++ b/mysql-test/suite/galera/t/galera_sst_mariabackup_encrypt_with_key.test @@ -1,6 +1,8 @@ # -# This test checks that key and cert encryption options can be passed to mariabackup via the my.cnf file -# Initial SST happens via mariabackup, so there is not much to do in the body of the test +# This test checks that key and cert encryption options can be passed to +# mariabackup via the my.cnf file +# Initial SST happens via mariabackup, so there is not much to do in the body +# of the test # --source include/big_test.inc @@ -12,3 +14,11 @@ SELECT 1; --let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; --source include/wait_condition.inc + +# Confirm that transfer was SSL-encrypted +--let $assert_text = Using openssl based encryption with socat +--let $assert_select = Using openssl based encryption with socat: with key and crt +--let $assert_count = 1 +--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err +--let $assert_only_after = CURRENT_TEST +--source include/assert_grep.inc diff --git a/mysql-test/suite/galera/t/galera_sst_mariabackup_encrypt_with_key_server.cnf b/mysql-test/suite/galera/t/galera_sst_mariabackup_encrypt_with_key_server.cnf new file mode 100644 index 00000000000..12fca48e065 --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sst_mariabackup_encrypt_with_key_server.cnf @@ -0,0 +1,13 @@ +!include ../galera_2nodes.cnf + +[mysqld] +wsrep_sst_method=mariabackup +wsrep_sst_auth="root:" +wsrep_debug=ON + +ssl-cert=@ENV.MYSQL_TEST_DIR/std_data/client-cert.pem +ssl-key=@ENV.MYSQL_TEST_DIR/std_data/client-key.pem +ssl-ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem + +[sst] +ssl-mode=VERIFY_CA \ No newline at end of file diff --git a/mysql-test/suite/galera/t/galera_sst_mariabackup_encrypt_with_key_server.test b/mysql-test/suite/galera/t/galera_sst_mariabackup_encrypt_with_key_server.test new file mode 100644 index 00000000000..19ebd0cf51e --- /dev/null +++ b/mysql-test/suite/galera/t/galera_sst_mariabackup_encrypt_with_key_server.test @@ -0,0 +1,25 @@ +# +# This test checks that if SST SSL is not explicitly donfigured mariabackup SST +# uses server SSL configuration if present. +# Initial SST happens via mariabackup, so there is not much to do in the body +# of the test +# + +--source include/big_test.inc +--source include/galera_cluster.inc +--source include/have_innodb.inc +--source include/have_mariabackup.inc +--source include/have_ssl_communication.inc + +SELECT 1; + +--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; +--source include/wait_condition.inc + +# Confirm that transfer was SSL-encrypted +--let $assert_text = Using openssl based encryption with socat +--let $assert_select = Using openssl based encryption with socat: with key and c +--let $assert_count = 1 +--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err +--let $assert_only_after = CURRENT_TEST +--source include/assert_grep.inc diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index f4092b9b8a7..38560c7c663 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -637,49 +637,30 @@ err: return NULL; } -#define WSREP_SST_AUTH_ENV "WSREP_SST_OPT_AUTH" +#define WSREP_SST_AUTH_ENV "WSREP_SST_OPT_AUTH" +#define WSREP_SST_REMOTE_AUTH_ENV "WSREP_SST_OPT_REMOTE_AUTH" +#define DATA_HOME_DIR_ENV "INNODB_DATA_HOME_DIR" -static int sst_append_auth_env(wsp::env& env, const char* sst_auth) +static int sst_append_env_var(wsp::env& env, + const char* const var, + const char* const val) { - int const sst_auth_size= strlen(WSREP_SST_AUTH_ENV) + 1 /* = */ - + (sst_auth ? strlen(sst_auth) : 0) + 1 /* \0 */; + int const env_str_size= strlen(var) + 1 /* = */ + + (val ? strlen(val) : 0) + 1 /* \0 */; - wsp::string sst_auth_str(sst_auth_size); // for automatic cleanup on return - if (!sst_auth_str()) return -ENOMEM; + wsp::string env_str(env_str_size); // for automatic cleanup on return + if (!env_str()) return -ENOMEM; - int ret= snprintf(sst_auth_str(), sst_auth_size, "%s=%s", - WSREP_SST_AUTH_ENV, sst_auth ? sst_auth : ""); + int ret= snprintf(env_str(), env_str_size, "%s=%s", var, val ? val : ""); - if (ret < 0 || ret >= sst_auth_size) + if (ret < 0 || ret >= env_str_size) { - WSREP_ERROR("sst_append_auth_env(): snprintf() failed: %d", ret); + WSREP_ERROR("sst_append_env_var(): snprintf(%s=%s) failed: %d", + var, val, ret); return (ret < 0 ? ret : -EMSGSIZE); } - env.append(sst_auth_str()); - return -env.error(); -} - -#define DATA_HOME_DIR_ENV "INNODB_DATA_HOME_DIR" - -static int sst_append_data_dir(wsp::env& env, const char* data_dir) -{ - int const data_dir_size= strlen(DATA_HOME_DIR_ENV) + 1 /* = */ - + (data_dir ? strlen(data_dir) : 0) + 1 /* \0 */; - - wsp::string data_dir_str(data_dir_size); // for automatic cleanup on return - if (!data_dir_str()) return -ENOMEM; - - int ret= snprintf(data_dir_str(), data_dir_size, "%s=%s", - DATA_HOME_DIR_ENV, data_dir ? data_dir : ""); - - if (ret < 0 || ret >= data_dir_size) - { - WSREP_ERROR("sst_append_data_dir(): snprintf() failed: %d", ret); - return (ret < 0 ? ret : -EMSGSIZE); - } - - env.append(data_dir_str()); + env.append(env_str()); return -env.error(); } @@ -1090,7 +1071,7 @@ static ssize_t sst_prepare_other (const char* method, return -env.error(); } - if ((ret= sst_append_auth_env(env, sst_auth))) + if ((ret= sst_append_env_var(env, WSREP_SST_AUTH_ENV, sst_auth))) { WSREP_ERROR("sst_prepare_other(): appending auth failed: %d", ret); return ret; @@ -1098,7 +1079,7 @@ static ssize_t sst_prepare_other (const char* method, if (data_home_dir) { - if ((ret= sst_append_data_dir(env, data_home_dir))) + if ((ret= sst_append_env_var(env, DATA_HOME_DIR_ENV, data_home_dir))) { WSREP_ERROR("sst_prepare_other(): appending data " "directory failed: %d", ret); @@ -1275,12 +1256,12 @@ ssize_t wsrep_sst_prepare (void** msg) *msg = malloc (msg_len); if (NULL != *msg) { - char* const method_ptr(reinterpret_cast(*msg)); + char* const method_ptr(static_cast(*msg)); strcpy (method_ptr, wsrep_sst_method); char* const addr_ptr(method_ptr + method_len + 1); strcpy (addr_ptr, addr_out); - WSREP_INFO ("Prepared SST request: %s|%s", method_ptr, addr_ptr); + WSREP_DEBUG("Prepared SST request: %s|%s", method_ptr, addr_ptr); } else { WSREP_ERROR("Failed to allocate SST request of size %zu. Can't continue.", @@ -1733,6 +1714,7 @@ static int sst_donate_other (const char* method, "wsrep_sst_%s " WSREP_SST_OPT_ROLE " 'donor' " WSREP_SST_OPT_ADDR " '%s' " + WSREP_SST_OPT_LPORT " '%u' " WSREP_SST_OPT_SOCKET " '%s' " WSREP_SST_OPT_DATA " '%s' " "%s" @@ -1740,7 +1722,8 @@ static int sst_donate_other (const char* method, WSREP_SST_OPT_GTID_DOMAIN_ID " '%d'" "%s" "%s", - method, addr, mysqld_unix_port, mysql_real_data_home, + method, addr, mysqld_port, mysqld_unix_port, + mysql_real_data_home, wsrep_defaults_file, uuid, (long long) seqno, wsrep_gtid_domain_id, binlog_opt_val, @@ -1820,7 +1803,21 @@ wsrep_cb_status_t wsrep_sst_donate_cb (void* app_ctx, void* recv_ctx, const char* data = method + method_len + 1; - if (check_request_str(data, address_char)) + /* check for auth@addr separator */ + const char* addr= strrchr(data, '@'); + wsp::string remote_auth; + if (addr) + { + remote_auth.set(strndup(data, addr - data)); + addr++; + } + else + { + // no auth part + addr= data; + } + + if (check_request_str(addr, address_char)) { WSREP_ERROR("Bad SST address string. SST canceled."); return WSREP_CB_FAILURE; @@ -1841,15 +1838,25 @@ wsrep_cb_status_t wsrep_sst_donate_cb (void* app_ctx, void* recv_ctx, } int ret; - if ((ret= sst_append_auth_env(env, sst_auth_real))) + if ((ret= sst_append_env_var(env, WSREP_SST_AUTH_ENV, sst_auth_real))) { WSREP_ERROR("wsrep_sst_donate_cb(): appending auth env failed: %d", ret); return WSREP_CB_FAILURE; } + if (remote_auth()) + { + if ((ret= sst_append_env_var(env, WSREP_SST_REMOTE_AUTH_ENV,remote_auth()))) + { + WSREP_ERROR("wsrep_sst_donate_cb(): appending remote auth env failed: " + "%d", ret); + return WSREP_CB_FAILURE; + } + } + if (data_home_dir) { - if ((ret= sst_append_data_dir(env, data_home_dir))) + if ((ret= sst_append_env_var(env, DATA_HOME_DIR_ENV, data_home_dir))) { WSREP_ERROR("wsrep_sst_donate_cb(): appending data " "directory failed: %d", ret); @@ -1859,12 +1866,12 @@ wsrep_cb_status_t wsrep_sst_donate_cb (void* app_ctx, void* recv_ctx, if (!strcmp (WSREP_SST_MYSQLDUMP, method)) { - ret = sst_donate_mysqldump(data, ¤t_gtid->uuid, uuid_str, + ret = sst_donate_mysqldump(addr, ¤t_gtid->uuid, uuid_str, current_gtid->seqno, bypass, env()); } else { - ret = sst_donate_other(method, data, uuid_str, + ret = sst_donate_other(method, addr, uuid_str, current_gtid->seqno, bypass, env()); } -- cgit v1.2.1 From 76c2b5106e56d60a1007337f42ab22995b9bb672 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 7 May 2021 14:52:46 +0300 Subject: Fix clang++-11 -Wsometimes-uninitialized --- storage/connect/jsonudf.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp index 7db01af2f2b..c3cb9a8fb63 100644 --- a/storage/connect/jsonudf.cpp +++ b/storage/connect/jsonudf.cpp @@ -508,7 +508,7 @@ PVAL JSNX::GetCalcValue(PGLOBAL g, PJAR jap, int n) { // For calculated arrays, a local Value must be used int lng = 0; - short type, prec = 0; + short type= 0, prec= 0; bool b = n < Nod - 1; PVAL valp; PJVAL vlp, vp; -- cgit v1.2.1 From afb8e873911141a2c2e4989c9281d3fb0093ecc4 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 7 May 2021 21:42:42 +0200 Subject: Skip auth_named_pipe test, if plugin was not built --- mysql-test/t/auth_named_pipe.test | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mysql-test/t/auth_named_pipe.test b/mysql-test/t/auth_named_pipe.test index 00577fbef05..4685b13143c 100644 --- a/mysql-test/t/auth_named_pipe.test +++ b/mysql-test/t/auth_named_pipe.test @@ -1,5 +1,10 @@ --source include/windows.inc +if (!$AUTH_NAMED_PIPE_SO) +{ + skip No auth_named_pipe plugin; +} + INSTALL SONAME 'auth_named_pipe'; --replace_result $USERNAME USERNAME -- cgit v1.2.1 From ad4b51948f2c0e1276e62902a2be463576224eec Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 3 May 2021 17:53:17 +0200 Subject: Revert "Connect: remove Mongo dependencies" This reverts commit 72fa9dabadb4b0011f483ccbf1ef59e62d0ef1e0 but doesn't recover deleted jars - they still exist in mysql-test/connect/std_data, no need to have them twice. Also it removes a redundant copy on JavaWrappers.jar --- storage/connect/CMakeLists.txt | 17 ++++++++++++++--- storage/connect/JavaWrappers.jar | Bin 19192 -> 0 bytes 2 files changed, 14 insertions(+), 3 deletions(-) delete mode 100644 storage/connect/JavaWrappers.jar diff --git a/storage/connect/CMakeLists.txt b/storage/connect/CMakeLists.txt index 43902613ce8..e06b59804fb 100644 --- a/storage/connect/CMakeLists.txt +++ b/storage/connect/CMakeLists.txt @@ -272,8 +272,14 @@ IF(CONNECT_WITH_JDBC) JdbcInterface.java ApacheInterface.java MariadbInterface.java MysqlInterface.java OracleInterface.java PostgresqlInterface.java Mongo2Interface.java Mongo3Interface.java - JavaWrappers.jar) + mysql-test/connect/std_data/JavaWrappers.jar) add_definitions(-DJAVA_SUPPORT) + IF(CONNECT_WITH_MONGO) + SET(CONNECT_SOURCES ${CONNECT_SOURCES} + mysql-test/connect/std_data/Mongo2.jar + mysql-test/connect/std_data/Mongo3.jar) + add_definitions(-DMONGO_SUPPORT) + ENDIF() ELSE() SET(JDBC_LIBRARY "") ENDIF() @@ -404,8 +410,13 @@ IF(CONNECT_WITH_JDBC AND JAVA_FOUND AND JNI_FOUND) SET (JAVA_SOURCES JdbcInterface.java) add_jar(JdbcInterface ${JAVA_SOURCES}) INSTALL(FILES - ${CMAKE_CURRENT_SOURCE_DIR}/JavaWrappers.jar + ${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/connect/std_data/JavaWrappers.jar ${CMAKE_CURRENT_BINARY_DIR}/JdbcInterface.jar DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine) + IF(CONNECT_WITH_MONGO) + INSTALL(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/connect/std_data/Mongo2.jar + ${CMAKE_CURRENT_SOURCE_DIR}/mysql-test/connect/std_data/Mongo3.jar + DESTINATION ${INSTALL_PLUGINDIR} COMPONENT connect-engine) + ENDIF() ENDIF() - diff --git a/storage/connect/JavaWrappers.jar b/storage/connect/JavaWrappers.jar deleted file mode 100644 index 33b29e7685b..00000000000 Binary files a/storage/connect/JavaWrappers.jar and /dev/null differ -- cgit v1.2.1 From af781f1ac435f4fc9e395417af2ad15ea524a502 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 3 May 2021 18:00:09 +0200 Subject: fix mtr --client-gdb to work mysqltest has no --gdb option --- mysql-test/lib/My/Debugger.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/lib/My/Debugger.pm b/mysql-test/lib/My/Debugger.pm index 7331238e1c8..b769f41dace 100644 --- a/mysql-test/lib/My/Debugger.pm +++ b/mysql-test/lib/My/Debugger.pm @@ -147,7 +147,7 @@ sub do_args($$$$$) { my %vars = ( vardir => $::opt_vardir, exe => $$exe, - args => join(' ', map { quote_from_mtr $_ } @$$args, '--gdb'), + args => join(' ', map { quote_from_mtr $_ } @$$args, '--loose-gdb'), input => $input, script => "$::opt_vardir/tmp/${k}init.$type", log => "$::opt_vardir/log/$type.$k", -- cgit v1.2.1 From 18fbe566bdf7420fbd9b4a1a8bede76e351d3b95 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 3 May 2021 18:01:30 +0200 Subject: mtr --gdb='commands' and restarts if mysqld is restarted during a test, the debugger script should be reused or overwritten, but not appended to the existing file --- mysql-test/lib/My/Debugger.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/lib/My/Debugger.pm b/mysql-test/lib/My/Debugger.pm index b769f41dace..5e04c070e7f 100644 --- a/mysql-test/lib/My/Debugger.pm +++ b/mysql-test/lib/My/Debugger.pm @@ -158,7 +158,7 @@ sub do_args($$$$$) { my $script = join "\n", @params; if ($v->{script}) { - ::mtr_tofile($vars{script}, subst($v->{script}, %vars)."\n".$script); + ::mtr_tonewfile($vars{script}, subst($v->{script}, %vars)."\n".$script); } elsif ($script) { die "$k is not using a script file, nowhere to write the script \n---\n$script\n---\n"; } -- cgit v1.2.1 From 66acec99d5877241b694493e96a0265be9260c69 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 3 May 2021 18:10:13 +0200 Subject: XA PREPARE and SHOW STATUS XA transaction only allows to access data in specific states, in ACTIVE, but not in IDLE or PREPARE. But even then one should be able to run SHOW STATUS. --- mysql-test/r/xa.result | 26 ++++++++++++++++++++++++++ mysql-test/t/xa.test | 18 ++++++++++++++++++ sql/sql_base.cc | 20 +++++++++++++------- 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/xa.result b/mysql-test/r/xa.result index 8ff84862270..4e4d7bc6048 100644 --- a/mysql-test/r/xa.result +++ b/mysql-test/r/xa.result @@ -317,3 +317,29 @@ XA ROLLBACK 'xid'; DROP TABLE t1; disconnect con1; connection default; +# +# XA states and SHOW commands +# +create table t1 (pk int primary key) engine=innodb; +xa start 'foo'; +insert t1 set pk=1; +xa end 'foo'; +xa prepare 'foo'; +show status like 'foo'; +Variable_name Value +select table_name,table_comment from information_schema.tables where table_schema='test'; +table_name t1 +table_comment +select table_name,table_rows,table_comment from information_schema.tables where table_schema='test'; +table_name t1 +table_rows NULL +table_comment XAER_RMFAIL: The command cannot be executed when global transaction is in the PREPARED state +Warnings: +Level Warning +Code 1399 +Message XAER_RMFAIL: The command cannot be executed when global transaction is in the PREPARED state +xa commit 'foo'; +drop table t1; +# +# End of 10.2 tests +# diff --git a/mysql-test/t/xa.test b/mysql-test/t/xa.test index ecce563b8c8..b13d12d2019 100644 --- a/mysql-test/t/xa.test +++ b/mysql-test/t/xa.test @@ -470,3 +470,21 @@ DROP TABLE t1; connection default; --source include/wait_until_count_sessions.inc + +--echo # +--echo # XA states and SHOW commands +--echo # +create table t1 (pk int primary key) engine=innodb; +xa start 'foo'; +insert t1 set pk=1; +xa end 'foo'; +xa prepare 'foo'; +show status like 'foo'; +--query_vertical select table_name,table_comment from information_schema.tables where table_schema='test' +--query_vertical select table_name,table_rows,table_comment from information_schema.tables where table_schema='test' +xa commit 'foo'; +drop table t1; + +--echo # +--echo # End of 10.2 tests +--echo # diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 16689f86c4e..e3c30c7433b 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -3985,13 +3985,19 @@ bool open_tables(THD *thd, const DDL_options_st &options, bool has_prelocking_list; DBUG_ENTER("open_tables"); - /* Accessing data in XA_IDLE or XA_PREPARED is not allowed. */ - enum xa_states xa_state= thd->transaction.xid_state.xa_state; - if (*start && (xa_state == XA_IDLE || xa_state == XA_PREPARED)) - { - my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[xa_state]); - DBUG_RETURN(true); - } + /* Data access in XA transaction is only allowed when it is active. */ + for (TABLE_LIST *table= *start; table; table= table->next_global) + if (!table->schema_table) + { + enum xa_states xa_state= thd->transaction.xid_state.xa_state; + if (xa_state == XA_IDLE || xa_state == XA_PREPARED) + { + my_error(ER_XAER_RMFAIL, MYF(0), xa_state_names[xa_state]); + DBUG_RETURN(true); + } + else + break; + } thd->current_tablenr= 0; restart: -- cgit v1.2.1 From e1bf1aea5cd8f8b5a1b15fd2a8ca0b8205654431 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 6 May 2021 22:58:28 +0200 Subject: force jemalloc to be used in release rpm/deb builds unless explicitly overruled with -DWITH_JEMALLOC=no --- cmake/build_configurations/mysql_release.cmake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake index efd736809e0..dadfc78e18b 100644 --- a/cmake/build_configurations/mysql_release.cmake +++ b/cmake/build_configurations/mysql_release.cmake @@ -97,11 +97,13 @@ ELSEIF(RPM) SET(WITH_ZLIB system CACHE STRING "") SET(CHECKMODULE /usr/bin/checkmodule CACHE FILEPATH "") SET(SEMODULE_PACKAGE /usr/bin/semodule_package CACHE FILEPATH "") + SET(WITH_JEMALLOC "yes" CACHE STRING "") ELSEIF(DEB) SET(WITH_SSL system CACHE STRING "") SET(WITH_ZLIB system CACHE STRING "") SET(WITH_LIBWRAP ON) SET(HAVE_EMBEDDED_PRIVILEGE_CONTROL ON) + SET(WITH_JEMALLOC "yes" CACHE STRING "") ELSE() SET(WITH_SSL bundled CACHE STRING "") SET(WITH_PCRE bundled CACHE STRING "") -- cgit v1.2.1 From d0785f773188b5f0eebb3135b320b2bac628f2f2 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sun, 9 May 2021 10:32:49 +0200 Subject: MDEV-25232 Ninja MSVC build sets default CMAKE_BUILD_TYPE to Debug This is incosistent with other single config generators, where the default type has always been RelWithDebInfo. Fixed by moving setting of CMAKE_BUILD_TYPE right before PROJECT. --- CMakeLists.txt | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 866792967d3..1ce95c44d92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,18 @@ # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA CMAKE_MINIMUM_REQUIRED(VERSION 2.8.12) + +IF(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) + # Setting build type to RelWithDebInfo as none was specified. + # Must occur before PROJECT + SET(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING + "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel" + FORCE) + # Set the possible values of build type for cmake-gui + SET_PROPERTY(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS + "None" "Debug" "Release" "MinSizeRel" "RelWithDebInfo") +ENDIF() + PROJECT(MySQL) # explicitly set the policy to OLD @@ -54,17 +66,6 @@ IF(NOT DEFINED MANUFACTURER) MARK_AS_ADVANCED(MANUFACTURER) ENDIF() -IF(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - # Setting build type to RelWithDebInfo as none was specified.") - SET(CMAKE_BUILD_TYPE "RelWithDebInfo" CACHE STRING - "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel" - FORCE) - # Set the possible values of build type for cmake-gui - SET_PROPERTY(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS - "None" "Debug" "Release" "MinSizeRel" "RelWithDebInfo") -ENDIF() - - # MAX_INDEXES - Set the maximum number of indexes per table, default 64 IF (NOT MAX_INDEXES) SET(MAX_INDEXES 64) -- cgit v1.2.1