diff options
author | Julius Goryavsky <julius.goryavsky@mariadb.com> | 2021-05-10 04:27:16 +0200 |
---|---|---|
committer | Julius Goryavsky <julius.goryavsky@mariadb.com> | 2021-05-10 12:09:29 +0200 |
commit | 8fef2b8667f30e4562ac006f992f859d1defdc0e (patch) | |
tree | fe640faf8ef39d833019593e91cb418e693a87fd /scripts | |
parent | d0785f773188b5f0eebb3135b320b2bac628f2f2 (diff) | |
download | mariadb-git-8fef2b8667f30e4562ac006f992f859d1defdc0e.tar.gz |
MDEV-23580: WSREP_SST: [ERROR] rsync daemon port has been taken
This commit contains a large set of further bug fixes and
improvements to SST scripts for Galera, continuing the work
that was started in MDEV-24962 to make SST scripts work smoothly
in different network configurations (especially using ipv6) and
with different environment settings:
1) The ipv6 addresses were incorrectly handled in the SST script
for rsync (incorrect address substitution for establishing a
connection, incorrect address substitution for bind, and so on);
2) Checking the locality of the ip-address in SST scripts did not
support ipv6 addresses (such as "[::1]"), which were falsely
identified as non-local ip, which further did not allow running
two SSTs on different local addresses on the same machine.
On the other hand, this bug masked some other errors (related
to handling ipv6 addresses);
3) The code for checking the locality of the ip address was different
in the SST scripts for rsync and for mysqldump, with individual
flaws. This code is now made common and moved to wsrep_sst_common;
4) Waiting for the start of the transport channel (socat, nc, rsync,
stunnel) in the wait_for_listen() and check_pid_and_port() functions
did not process ipv6 addresses correctly in all cases (not for all
branches);
5) Waiting for the start of the transport channel (socat, nc, rsync,
stunnel) in the wait_for_listen() and check_pid_and_port() functions
for some code branches could give a false positive result due to
the textual match of prefixes in the port number and/or PID of
the process;
6) Waiting for the start of the transport channel (socat, nc, rsync,
stunnel) was supported through different utilities in SST scripts
for mariabackup and for rsync, and with various minor flaws in
the code. Now the code is still different in these scripts, but
it supports a common set of utilities (lsof, ss, sockstat) and
is synchronized across patterns that used to check the output
of these utilities;
7) In SST via mariabackup, the signal about readiness to receive data
is sometimes sent too early - immediately after listen(), and not
after accept() (which are called by socat or netcat utility).
8) Checking availability of the some options of some utilities was
done using the grep pattern, which easily gives false positives;
9) Common name (CN) for local addresses, if not explicitly specified,
is now always replaced to "localhost" to avoid the need to generate
many separate certificates for local addresses of one machine and
not to depend on which the local address is currently used in test
(ipv4 or ipv6, etc.);
10) In tests galera_sst_mariabackup_encrypt_with_key_server and
galera_sst_rsync_encrypt_with_key_server the correct certificate
is selected to avoid commonname (CN) mismatch problems;
11) Further refactoring to protect against spaces in file names.
12) Further general refactoring to eliminate bash-specific constructs
or to improve code readability;
13) The code for setting options for the nc (netcat) utility was
different in different scripts for SST - now it is made identical.
14) Fixed long-time broken encryption via xbcrypt in combination with
mariabackup and added support for key-based encryption via openssl
utility, which is now enabled by default for encrypt=1 mode (this
default mode can be changed using a new configuration file option
"encypt-format=openssl|xbcrypt", which can be placed in the [mysqld],
[sst] or in the [xtrabackup] section) - this change will allow us
to use and to test the encypt=1 encryption without installing
non-standard third-party utilities.
Diffstat (limited to 'scripts')
-rwxr-xr-x[-rw-r--r--] | scripts/wsrep_sst_common.sh | 152 | ||||
-rw-r--r-- | scripts/wsrep_sst_mariabackup.sh | 474 | ||||
-rw-r--r-- | scripts/wsrep_sst_mysqldump.sh | 26 | ||||
-rw-r--r-- | scripts/wsrep_sst_rsync.sh | 156 | ||||
-rw-r--r-- | scripts/wsrep_sst_xtrabackup-v2.sh | 120 | ||||
-rw-r--r-- | scripts/wsrep_sst_xtrabackup.sh | 146 |
6 files changed, 610 insertions, 464 deletions
diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index 082873dff3c..d19a0dbfdd5 100644..100755 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -51,7 +51,7 @@ case "$1" in # # Break address string into host:port/path parts # - case "${WSREP_SST_OPT_ADDR}" in + case "$WSREP_SST_OPT_ADDR" in \[*) # IPv6 # Remove the starting and ending square brackets, if present: @@ -81,7 +81,7 @@ case "$1" in # up to "/" (if present): WSREP_SST_OPT_ADDR_PORT="${remain%%/*}" # If the "/" character is present, then the path is not empty: - if [ "${remain#*/}" != "${remain}" ]; then + 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#*/}" @@ -89,10 +89,10 @@ case "$1" in 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 + if [ "${remain%%/*}" != "$remain" ]; then # This operation removes the tail after the very first # occurrence of the "/" character (inclusively): readonly WSREP_SST_OPT_MODULE="${remain%%/*}" @@ -103,7 +103,7 @@ case "$1" in 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 + 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%%/*}" @@ -113,7 +113,7 @@ case "$1" in # If the remainder does not match the original string, # then there is something else (the version number in # our case): - if [ "$remain" != "${WSREP_SST_OPT_LSN}" ]; then + if [ "$remain" != "$WSREP_SST_OPT_LSN" ]; then # Let's extract the version number by removing the tail # after the very first occurence of the "/" character # (inclusively): @@ -535,7 +535,8 @@ 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)" +script_binary=$(dirname "$0") +SCRIPTS_DIR=$(cd "$script_binary"; pwd -P) EXTRA_DIR="$SCRIPTS_DIR/../extra" CLIENT_DIR="$SCRIPTS_DIR/../client" @@ -581,30 +582,45 @@ readonly MY_PRINT_DEFAULTS="$MY_PRINT_DEFAULTS $WSREP_SST_OPT_CONF" # parse_cnf() { - local group="$1" + local groups="$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 + # normalize the variable names specified in the .cnf file + # (user can use '_' or '-', for example, log-bin or log_bin), + # then search for the last instance of the desired variable + # and finally get the value of that variable (if the variable + # was specified several times - we use only its last instance): + + local pattern='BEGIN {OFS=FS="="} {sub(/^--loose/,"-",$0); gsub(/_/,"-",$1); if ($1=="--'"$var"'") lastval=substr($0,length($1)+2)} END {print lastval}' + + while [ -n "$groups" ]; do + # Remove the largest suffix starting with the '|' character: + local group="${groups%%\|*}" + # Remove the remainder (the group name) from the rest + # of the groups list (as if it were a prefix): + groups="${groups#$group}" + groups="${groups#\|}" + # if the group name is the same as the "[--]mysqld", then + # try to use it together with the group suffix: + if [ "${group#--}" = 'mysqld' -a -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then + reval=$($MY_PRINT_DEFAULTS "mysqld$WSREP_SST_OPT_SUFFIX_VALUE" | awk "$pattern") + if [ -n "$reval" ]; then + break + fi + fi + # Let's try to use the group name as it is: + reval=$($MY_PRINT_DEFAULTS "$group" | awk "$pattern") + if [ -n "$reval" ]; then + break + fi + done - # use default if we haven't found a value + # use default if we haven't found a value: if [ -z "$reval" ]; then [ -n "${3:-}" ] && reval="$3" fi - echo $reval + echo "$reval" } # @@ -615,18 +631,37 @@ parse_cnf() # in_config() { - local group="$1" + local groups="$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 + + # normalize the variable names specified in the .cnf file + # (user can use '_' or '-', for example, log-bin or log_bin), + # then search for the last instance(s) of the desired variable: + + local pattern='BEGIN {OFS=FS="="; found=0} {sub(/^--loose/,"-",$0); gsub(/_/,"-",$1); if ($1=="--'"$var"'") found=1} END {print found}' + + while [ -n "$groups" ]; do + # Remove the largest suffix starting with the '|' character: + local group="${groups%%\|*}" + # Remove the remainder (the group name) from the rest + # of the groups list (as if it were a prefix): + groups="${groups#$group}" + groups="${groups#\|}" + # if the group name is the same as the "[--]mysqld", then + # try to use it together with the group suffix: + if [ "${group#--}" = 'mysqld' -a -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then + found=$($MY_PRINT_DEFAULTS "mysqld$WSREP_SST_OPT_SUFFIX_VALUE" | awk "$pattern") + if [ $found -ne 0 ]; then + break + fi + fi + # Let's try to use the group name as it is: + found=$($MY_PRINT_DEFAULTS "$group" | awk "$pattern") + if [ $found -ne 0 ]; then + break + fi + done echo $found } @@ -793,3 +828,52 @@ wsrep_gen_secret() $RANDOM $RANDOM $RANDOM $RANDOM fi } + +is_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 + [ "$1" = "$(hostname -f)" ] && return 0 + [ "$1" = "$(hostname -d)" ] && return 0 + + local ip_util="$(command -v ip)" + if [ -x "$ip_util" ]; then + # ip address show ouput format is " inet[6] <address>/<mask>": + "$ip_util" address show \ + | grep -E "^[[:space:]]*inet.? [^[:space:]]+/" -o \ + | grep -F " $1/" >/dev/null && return 0 + else + local ifconfig_util="$(command -v ifconfig)" + if [ -x "$ifconfig_util" ]; then + # ifconfig output format is " inet[6] <address> ...": + "$ifconfig_util" \ + | grep -E "^[[:space:]]*inet.? [^[:space:]]+ " -o \ + | grep -F " $1 " >/dev/null && return 0 + fi + fi + + return 1 +} + +check_sockets_utils() +{ + lsof_available=0 + sockstat_available=0 + ss_available=0 + + [ -x "$(command -v lsof)" ] && lsof_available=1 + [ -x "$(command -v sockstat)" ] && sockstat_available=1 + [ -x "$(command -v ss)" ] && ss_available=1 + + if [ $lsof_available -eq 0 -a \ + $sockstat_available -eq 0 -a \ + $ss_available -eq 0 ] + then + wsrep_log_error "Neither lsof tool, nor ss or sockstat was found in " \ + "the PATH! Make sure you have it installed." + exit 2 # ENOENT + fi +} diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index 8b05217b2fa..de789dc1728 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-2021 MariaDB +# Copyright (C) 2013 Percona Inc # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -17,14 +17,15 @@ # MA 02110-1335 USA. # Documentation: -# http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html +# https://mariadb.com/kb/en/mariabackup-overview/ # Make sure to read that before proceeding! -. $(dirname $0)/wsrep_sst_common +. $(dirname "$0")/wsrep_sst_common wsrep_check_datadir -OS=$(uname) +OS="$(uname)" ealgo="" +eformat="" ekey="" ekeyfile="" encrypt=0 @@ -32,7 +33,7 @@ nproc=1 ecode=0 ssyslog="" ssystag="" -XTRABACKUP_PID="" +MARIABACKUP_PID="" SST_PORT="" REMOTEIP="" tcert="" @@ -47,7 +48,7 @@ lsn="" ecmd="" rlimit="" # Initially -stagemsg="${WSREP_SST_OPT_ROLE}" +stagemsg="$WSREP_SST_OPT_ROLE" cpat="" speciald=1 ib_home_dir="" @@ -59,8 +60,8 @@ strmcmd="" tfmt="" tcmd="" payload=0 -pvformat="-F '%N => Rate:%r Avg:%a Elapsed:%t %e Bytes: %b %p' " -pvopts="-f -i 10 -N $WSREP_SST_OPT_ROLE " +pvformat="-F '%N => Rate:%r Avg:%a Elapsed:%t %e Bytes: %b %p'" +pvopts="-f -i 10 -N $WSREP_SST_OPT_ROLE" STATDIR="" uextra=0 disver="" @@ -79,23 +80,22 @@ readonly SECRET_TAG="secret" # 5.6.21 PXC and later can't donate to an older joiner sst_ver=1 -if pv --help 2>/dev/null | grep -q FORMAT;then - pvopts+=$pvformat +if [ -x "$(command -v pv)" ] && pv --help | grep -qw -- '-F'; then + pvopts="$pvopts $pvformat" fi pcmd="pv $pvopts" declare -a RC set +e MARIABACKUP_BIN="$(command -v mariabackup)" -if [ -z "$MARIABACKUP_BIN" ]; then +if [ ! -x "$MARIABACKUP_BIN" ]; then wsrep_log_error 'mariabackup binary not found in $PATH' exit 42 fi set -e MBSTREAM_BIN=mbstream -XBCRYPT_BIN=xbcrypt # Not available in MariaBackup -DATA="${WSREP_SST_OPT_DATA}" +DATA="$WSREP_SST_OPT_DATA" INFO_FILE="xtrabackup_galera_info" IST_FILE="xtrabackup_ist" MAGIC_FILE="$DATA/$INFO_FILE" @@ -112,7 +112,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" @@ -137,19 +137,21 @@ get_keys() fi 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" + if [ -n "$ealgo" -o -n "$ekey" -o -n "$ekeyfile" ]; then + wsrep_log_error "Options for encryption are specified, " \ + "but encryption itself is disabled. SST may fail." fi return fi if [ $sfmt = 'tar' ]; then - wsrep_log_info "NOTE: Xtrabackup-based encryption - encrypt=1 - cannot be enabled with tar format" + wsrep_log_info "NOTE: key-based encryption (encrypt=1) " \ + "cannot be enabled with tar format" encrypt=-1 return fi - wsrep_log_info "Xtrabackup based encryption enabled in my.cnf - Supported only from Xtrabackup 2.1.4" + wsrep_log_info "Key based encryption enabled in my.cnf" if [ -z "$ealgo" ]; then wsrep_log_error "FATAL: Encryption algorithm empty from my.cnf, bailing out" @@ -161,17 +163,49 @@ get_keys() exit 3 fi - if [ -z "$ekey" ]; then - ecmd="$XBCRYPT_BIN --encrypt-algo='$ealgo' --encrypt-key-file='$ekeyfile'" + if [ "$eformat" = 'openssl' ]; then + get_openssl + if [ -z "$OPENSSL_BINARY" ]; then + wsrep_log_error "If encryption using the openssl is enabled, " \ + "then you need to install openssl" + exit 2 + fi + ecmd="'$OPENSSL_BINARY' enc -$ealgo" + if "$OPENSSL_BINARY" enc -help 2>&1 | grep -qw -- '-pbkdf2'; then + ecmd="$ecmd -pbkdf2" + elif "$OPENSSL_BINARY" enc -help 2>&1 | grep -qw -- '-iter'; then + ecmd="$ecmd -iter 1" + elif "$OPENSSL_BINARY" enc -help 2>&1 | grep -qw -- '-md'; then + ecmd="$ecmd -md sha256" + fi + if [ -z "$ekey" ]; then + ecmd="$ecmd -kfile '$ekeyfile'" + else + ecmd="$ecmd -k '$ekey'" + fi + elif [ "$eformat" = 'xbcrypt' ]; then + if [ ! -x "$(command -v xbcrypt)" ]; then + wsrep_log_error "If encryption using the xbcrypt is enabled, " \ + "then you need to install xbcrypt" + exit 2 + fi + wsrep_log_info "NOTE: xbcrypt-based encryption, " \ + "supported only from Xtrabackup 2.1.4" + if [ -z "$ekey" ]; then + ecmd="xbcrypt --encrypt-algo='$ealgo' --encrypt-key-file='$ekeyfile'" + else + ecmd="xbcrypt --encrypt-algo='$ealgo' --encrypt-key='$ekey'" + fi else - ecmd="$XBCRYPT_BIN --encrypt-algo='$ealgo' --encrypt-key='$ekey'" + wsrep_log_error "Unknown encryption format='$eformat'" + exit 2 fi if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then ecmd="$ecmd -d" fi - stagemsg+="-XB-Encrypted" + stagemsg="$stagemsg-XB-Encrypted" } get_transfer() @@ -179,27 +213,27 @@ get_transfer() TSST_PORT="$SST_PORT" if [ $tfmt = 'nc' ]; then - wsrep_check_programs nc wsrep_log_info "Using netcat as streamer" - + wsrep_check_programs nc + tcmd="nc" 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 - # Debian netcat + if nc -h 2>&1 | grep -q 'ncat'; then + wsrep_log_info "Using Ncat as streamer" + tcmd="$tcmd -l" + elif nc -h 2>&1 | grep -qw -- '-d'; then + wsrep_log_info "Using Debian netcat as streamer" + tcmd="$tcmd -dl" 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" + tcmd="$tcmd -6" fi else - # traditional netcat - tcmd="nc -l -p $TSST_PORT" + wsrep_log_info "Using traditional netcat as streamer" + tcmd="$tcmd -l -p" fi + tcmd="$tcmd $TSST_PORT" else # Check to see if netcat supports the '-N' flag. # -N Shutdown the network socket after EOF on stdin @@ -208,33 +242,28 @@ get_transfer() # 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" + if nc -h 2>&1 | grep -qw -- '-N'; then + tcmd="$tcmd -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 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 - # Debian netcat + elif nc -h 2>&1 | grep -qw -- '-d'; then wsrep_log_info "Using Debian netcat as streamer" - 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="$tcmd -q0" fi + tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT" fi else tfmt='socat' - wsrep_check_programs socat + wsrep_log_info "Using socat as streamer" + wsrep_check_programs socat - if [[ $encrypt -eq 2 || $encrypt -eq 3 ]] && ! socat -V | grep -q "WITH_OPENSSL 1";then + if [ $encrypt -eq 2 -o $encrypt -eq 3 ] && ! socat -V | grep -q -F 'WITH_OPENSSL 1'; then wsrep_log_error "Encryption requested, but socat is not OpenSSL enabled (encrypt=$encrypt)" exit 2 fi @@ -245,7 +274,7 @@ get_transfer() wsrep_log_error "Both PEM and CRT files required" exit 22 fi - stagemsg+="-OpenSSL-Encrypted-2" + stagemsg="$stagemsg-OpenSSL-Encrypted-2" 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" @@ -259,7 +288,7 @@ get_transfer() wsrep_log_error "Both certificate and key files required" exit 22 fi - stagemsg+="-OpenSSL-Encrypted-3" + stagemsg="$stagemsg-OpenSSL-Encrypted-3" if [ -z "$tcert" ]; then # no verification if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then @@ -278,6 +307,8 @@ get_transfer() CN_option="" if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'" + elif is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then + CN_option=',commonname=localhost' 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'$CN_option$sockopt" @@ -297,13 +328,13 @@ 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 )) fi popd 1>/dev/null - pcmd+=" -s $payload" + pcmd="$pcmd -s $payload" adjust_progress } @@ -320,9 +351,9 @@ adjust_progress() if [ -n "$progress" -a "$progress" != '1' ]; then if [ -e "$progress" ]; then - pcmd+=" 2>>'$progress'" + pcmd="$pcmd 2>>'$progress'" else - pcmd+=" 2>'$progress'" + pcmd="$pcmd 2>'$progress'" fi elif [ -z "$progress" -a -n "$rlimit" ]; then # When rlimit is non-zero @@ -331,25 +362,26 @@ adjust_progress() if [ -n "$rlimit" -a "$WSREP_SST_OPT_ROLE" = 'donor' ]; then wsrep_log_info "Rate-limiting SST to $rlimit" - pcmd+=" -L \$rlimit" + pcmd="$pcmd -L \$rlimit" fi } +encgroups='--mysqld|sst|xtrabackup' + 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') + tcert=$(parse_cnf "$encgroups" 'ssl-ca') + tpem=$(parse_cnf "$encgroups" 'ssl-cert') + tkey=$(parse_cnf "$encgroups" 'ssl-key') } read_cnf() { - sfmt=$(parse_cnf sst streamfmt "mbstream") - tfmt=$(parse_cnf sst transferfmt "socat") + sfmt=$(parse_cnf sst streamfmt 'mbstream') + tfmt=$(parse_cnf sst transferfmt 'socat') - encrypt=$(parse_cnf 'sst' 'encrypt' 0) - tmode=$(parse_cnf 'sst' 'ssl-mode' 'DISABLED' | tr [:lower:] [:upper:]) + encrypt=$(parse_cnf "$encgroups" 'encrypt' 0) + tmode=$(parse_cnf "$encgroups" 'ssl-mode' 'DISABLED' | tr [:lower:] [:upper:]) if [ $encrypt -eq 0 -o $encrypt -ge 2 ] then @@ -363,11 +395,7 @@ read_cnf() 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 + check_server_ssl_config fi if [ 0 -eq $encrypt -a -n "$tpem" -a -n "$tkey" ] then @@ -380,29 +408,21 @@ read_cnf() [ "${tmode#VERIFY}" != "$tmode" ] || tcert="" fi fi + elif [ $encrypt -eq 1 ]; then + ealgo=$(parse_cnf "$encgroups" 'encrypt-algo') + eformat=$(parse_cnf "$encgroups" 'encrypt-format' 'openssl') + ekey=$(parse_cnf "$encgroups" 'encrypt-key') + ekeyfile=$(parse_cnf "$encgroups" 'encrypt-key-file') 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 + 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 "") 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$') + [ $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$') scomp=$(parse_cnf sst compressor "") sdecomp=$(parse_cnf sst decompressor "") @@ -415,26 +435,20 @@ read_cnf() stimeout=$(parse_cnf sst sst-initial-timeout 300) ssyslog=$(parse_cnf sst sst-syslog 0) ssystag=$(parse_cnf mysqld_safe syslog-tag "${SST_SYSLOG_TAG:-}") - ssystag+="-" + ssystag="$ssystag-" sstlogarchive=$(parse_cnf sst sst-log-archive 1) - sstlogarchivedir=$(parse_cnf sst sst-log-archive-dir "/tmp/sst_log_archive") + 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 - if [[ $ssyslog -ne -1 ]];then - if $MY_PRINT_DEFAULTS mysqld_safe | grep -q -- "--syslog";then + if [ $ssyslog -ne -1 ]; then + if $MY_PRINT_DEFAULTS mysqld_safe | grep -q -- "--syslog"; then ssyslog=1 fi fi - - if [[ $encrypt -eq 1 ]]; then - wsrep_log_error "Xtrabackup-based encryption is currently not" \ - "supported with MariaBackup" - exit 2 - fi } get_stream() @@ -461,7 +475,7 @@ get_proc() { set +e nproc=$(grep -c processor /proc/cpuinfo) - [[ -z $nproc || $nproc -eq 0 ]] && nproc=1 + [ -z $nproc -o $nproc -eq 0 ] && nproc=1 set -e } @@ -477,7 +491,7 @@ cleanup_joiner() local estatus=$? 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 @@ -495,10 +509,10 @@ cleanup_joiner() # This means no setsid done in mysqld. # We don't want to kill mysqld here otherwise. - if [[ $$ -eq $pgid ]];then + if [ $$ -eq $pgid ]; then # This means a signal was delivered to the process. # So, more cleanup. - if [[ $estatus -ge 128 ]];then + if [ $estatus -ge 128 ]; then kill -KILL -$$ || true fi fi @@ -509,7 +523,7 @@ cleanup_joiner() check_pid() { local pid_file="$1" - [ -r "$pid_file" ] && ps -p $(cat "$pid_file") >/dev/null 2>&1 + [ -r "$pid_file" ] && ps -p $(cat "$pid_file") 2>&1 >/dev/null } cleanup_donor() @@ -520,11 +534,11 @@ cleanup_donor() wsrep_log_error "Cleanup after exit with status:$estatus" fi - if [ -n "$XTRABACKUP_PID" ]; then - if check_pid $XTRABACKUP_PID + if [ -n "$MARIABACKUP_PID" ]; then + if check_pid $MARIABACKUP_PID then - wsrep_log_error "xtrabackup process is still running. Killing..." - kill_xtrabackup + wsrep_log_error "mariabackup process is still running. Killing..." + kill_mariabackup fi fi @@ -550,10 +564,10 @@ cleanup_donor() # This means no setsid done in mysqld. # We don't want to kill mysqld here otherwise. - if [[ $$ -eq $pgid ]];then + if [ $$ -eq $pgid ]; then # This means a signal was delivered to the process. # So, more cleanup. - if [[ $estatus -ge 128 ]];then + if [ $estatus -ge 128 ]; then kill -KILL -$$ || true fi fi @@ -561,24 +575,57 @@ cleanup_donor() exit $estatus } -kill_xtrabackup() +kill_mariabackup() { - local PID=$(cat "$XTRABACKUP_PID") + local PID=$(cat "$MARIABACKUP_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 + wsrep_log_info "Removing mariabackup pid file ($MARIABACKUP_PID)" + rm -f "$MARIABACKUP_PID" || true } setup_ports() { 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}" + 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 } +check_port() +{ + local PORT="$1" + local UTILS="$2" + + local port_info is_util + + if [ $lsof_available -ne 0 ]; then + port_info=$(lsof -i ":$PORT" -Pn 2>/dev/null | \ + grep -F '(LISTEN)') + is_util=$(echo "$port_info" | \ + grep -E "^($UTILS)[^[:space:]]*[[:space:]]+[0-9]+[[:space:]]+") + elif [ $sockstat_available -ne 0 ]; then + port_info=$(sockstat -p "$PORT" 2>/dev/null | \ + grep -F 'LISTEN') + is_util=$(echo "$port_info" | \ + grep -E "[[:space:]]+($UTILS)[^[:space:]]*[[:space:]]+[0-9]+[[:space:]]+") + elif [ $ss_available -ne 0 ]; then + port_info=$(ss -H -p -n -l "( sport = :$PORT )" 2>/dev/null) + is_util=$(echo "$port_info" | \ + grep -E "users:\\(.*\\(\"($UTILS)[^[:space:]]*\".*\<pid=[0-9]+\>.*\\)") + else + wsrep_log_error "unknown sockets utility" + exit 2 # ENOENT + fi + + if [ -z "$is_util" ]; then + return 1 + fi + + return 0 +} + # waits ~10 seconds for nc to open the port and then reports ready # (regardless of timeout) wait_for_listen() @@ -586,16 +633,16 @@ wait_for_listen() local PORT="$1" local ADDR="$2" local MODULE="$3" + for i in {1..50} do - 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 + if check_port "$PORT" 'socat|nc' + then + break fi sleep 0.2 done - echo "ready ${ADDR}/${MODULE}//$sst_ver" + echo "ready $ADDR/$MODULE//$sst_ver" } check_extra() @@ -606,10 +653,10 @@ check_extra() 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. + # mariabackup works only locally, hence, + # setting host to 127.0.0.1 unconditionally: wsrep_log_info "SST through extra_port $eport" - INNOEXTRA+=" --host=127.0.0.1 --port=$eport" + INNOEXTRA="$INNOEXTRA --host=127.0.0.1 --port=$eport" use_socket=0 else wsrep_log_error "Extra port $eport null, failing" @@ -620,7 +667,7 @@ check_extra() fi fi if [ $use_socket -eq 1 -a -n "$WSREP_SST_OPT_SOCKET" ]; then - INNOEXTRA+=" --socket='$WSREP_SST_OPT_SOCKET'" + INNOEXTRA="$INNOEXTRA --socket='$WSREP_SST_OPT_SOCKET'" fi } @@ -630,7 +677,7 @@ recv_joiner() local msg="$2" local tmt=$3 local checkf=$4 - local ltcmd + local wait=$5 if [ ! -d "$dir" ]; then # This indicates that IST is in progress @@ -640,28 +687,34 @@ recv_joiner() pushd "$dir" 1>/dev/null set +e - 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" + local ltcmd="$tcmd" + if [ $tmt -gt 0 ]; then + if [ -x "$(command -v timeout)" ]; then + if timeout --help | grep -qw -- '-k'; then + ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd" + else + ltcmd="timeout -s9 $tmt $tcmd" + fi fi - timeit "$msg" "$ltcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )" - else - timeit "$msg" "$tcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )" fi + if [ $wait -ne 0 ]; then + wait_for_listen "$SST_PORT" "$ADDR" "$MODULE" & + fi + + timeit "$msg" "$ltcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )" + set -e 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[@]}" 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 @@ -672,14 +725,14 @@ recv_joiner() if [ ! -r "$MAGIC_FILE" ]; then # this message should cause joiner to abort wsrep_log_error "receiving process ended without creating " \ - "'${MAGIC_FILE}'" + "'$MAGIC_FILE'" wsrep_log_info "Contents of datadir" - wsrep_log_info "$(ls -l ${dir}/*)" + 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) + 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'" @@ -687,7 +740,7 @@ recv_joiner() fi # remove secret from magic file - grep -v "$SECRET_TAG " "$MAGIC_FILE" > "$MAGIC_FILE.new" + grep -v -- "$SECRET_TAG " "$MAGIC_FILE" > "$MAGIC_FILE.new" mv "$MAGIC_FILE.new" "$MAGIC_FILE" fi } @@ -703,8 +756,8 @@ send_donor() 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 sending data to joiner node: " \ "exit codes: ${RC[@]}" exit 32 @@ -717,11 +770,11 @@ monitor_process() local sst_stream_pid=$1 while true ; do - if ! ps -p "${WSREP_SST_OPT_PARENT}" &>/dev/null; then + if ! ps -p "$WSREP_SST_OPT_PARENT" &>/dev/null; then wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly." exit 32 fi - if ! ps -p "${sst_stream_pid}" &>/dev/null; then + if ! ps -p "$sst_stream_pid" &>/dev/null; then break fi sleep 0.1 @@ -730,7 +783,7 @@ monitor_process() wsrep_check_programs "$MARIABACKUP_BIN" -rm -f "${MAGIC_FILE}" +rm -f "$MAGIC_FILE" if [ "$WSREP_SST_OPT_ROLE" != 'joiner' -a "$WSREP_SST_OPT_ROLE" != 'donor' ]; then wsrep_log_error "Invalid role ${WSREP_SST_OPT_ROLE}" @@ -740,15 +793,15 @@ fi read_cnf setup_ports -if "${MARIABACKUP_BIN}" --help 2>/dev/null | grep -q -- '--version-check'; then +if "$MARIABACKUP_BIN" --help 2>/dev/null | grep -qw -- '--version-check'; then disver='--no-version-check' fi -iopts+=" --databases-exclude='lost+found'" +iopts="$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="$iopts --no-backup-locks" fi # if no command line argument and INNODB_DATA_HOME_DIR environment variable @@ -769,11 +822,9 @@ fi cd "$OLD_PWD" -if [[ $ssyslog -eq 1 ]];then +if [ $ssyslog -eq 1 ]; then - if [ ! -x "$(command -v logger)" ]; then - wsrep_log_error "logger not in path: $PATH. Ignoring" - else + if [ -x "$(command -v logger)" ]; then 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) @@ -787,6 +838,8 @@ if [[ $ssyslog -eq 1 ]];then { logger -p daemon.info -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" } + else + wsrep_log_error "logger not in path: $PATH. Ignoring" fi INNOAPPLY="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply" @@ -795,10 +848,9 @@ if [[ $ssyslog -eq 1 ]];then else -if [[ "$sstlogarchive" -eq 1 ]] +if [ $sstlogarchive -eq 1 ] then ARCHIVETIMESTAMP=$(date "+%Y.%m.%d-%H.%M.%S.%N") - newfile="" if [ -n "$sstlogarchivedir" ] then @@ -812,11 +864,12 @@ then then if [ -n "$sstlogarchivedir" ] then - newfile="$sstlogarchivedir/$(basename '$INNOAPPLYLOG').$ARCHIVETIMESTAMP" + newfile=$(basename "$INNOAPPLYLOG") + newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else newfile="$INNOAPPLYLOG.$ARCHIVETIMESTAMP" fi - wsrep_log_info "Moving ${INNOAPPLYLOG} to ${newfile}" + wsrep_log_info "Moving '$INNOAPPLYLOG' to '$newfile'" mv "$INNOAPPLYLOG" "$newfile" gzip "$newfile" fi @@ -825,11 +878,12 @@ then then if [ -n "$sstlogarchivedir" ] then - newfile="$sstlogarchivedir/$(basename '$INNOMOVELOG').$ARCHIVETIMESTAMP" + newfile=$(basename "$INNOMOVELOG") + newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else newfile="$INNOMOVELOG.$ARCHIVETIMESTAMP" fi - wsrep_log_info "Moving ${INNOMOVELOG} to ${newfile}" + wsrep_log_info "Moving '$INNOMOVELOG' to '$newfile'" mv "$INNOMOVELOG" "$newfile" gzip "$newfile" fi @@ -838,11 +892,12 @@ then then if [ -n "$sstlogarchivedir" ] then - newfile="$sstlogarchivedir/$(basename '$INNOBACKUPLOG').$ARCHIVETIMESTAMP" + newfile=$(basename "$INNOBACKUPLOG") + newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP" else newfile="$INNOBACKUPLOG.$ARCHIVETIMESTAMP" fi - wsrep_log_info "Moving ${INNOBACKUPLOG} to ${newfile}" + wsrep_log_info "Moving '$INNOBACKUPLOG' to '$newfile'" mv "$INNOBACKUPLOG" "$newfile" gzip "$newfile" fi @@ -868,7 +923,7 @@ setup_commands() get_stream get_transfer -if [ "$WSREP_SST_OPT_ROLE" = "donor" ] +if [ "$WSREP_SST_OPT_ROLE" = 'donor' ] then trap cleanup_donor EXIT @@ -881,18 +936,18 @@ then exit 93 fi - if [ -z "$(parse_cnf --mysqld tmpdir)" -a \ - -z "$(parse_cnf xtrabackup tmpdir)" ]; then - xtmpdir=$(mktemp -d) + tmpdir=$(parse_cnf "$encgroups" 'tmpdir') + if [ -z "$tmpdir" ]; then + xtmpdir="$(mktemp -d)" tmpopts="--tmpdir='$xtmpdir'" - wsrep_log_info "Using $xtmpdir as xtrabackup temporary directory" + wsrep_log_info "Using $xtmpdir as mariabackup temporary directory" fi - itmpdir=$(mktemp -d) + itmpdir="$(mktemp -d)" wsrep_log_info "Using $itmpdir as mariabackup temporary directory" if [ -n "$WSREP_SST_OPT_USER" ]; then - INNOEXTRA+=" --user='$WSREP_SST_OPT_USER'" + INNOEXTRA="$INNOEXTRA --user='$WSREP_SST_OPT_USER'" usrst=1 fi @@ -927,10 +982,11 @@ then tcmd="$ecmd | $tcmd" fi - send_donor "$DATA" "${stagemsg}-gtid" + send_donor "$DATA" "$stagemsg-gtid" tcmd="$ttcmd" + # Restore the transport commmand to its original state if [ -n "$progress" ]; then get_footprint tcmd="$pcmd | $tcmd" @@ -944,26 +1000,32 @@ then wsrep_log_info "Streaming the backup to joiner at ${REMOTEIP}:${SST_PORT}" + # Add compression to the head of the stream (if specified) if [ -n "$scomp" ]; then tcmd="$scomp | $tcmd" fi + # Add encryption to the head of the stream (if specified) + if [ $encrypt -eq 1 ]; then + tcmd="$ecmd | $tcmd" + fi + setup_commands set +e - timeit "${stagemsg}-SST" "$INNOBACKUP | $tcmd; RC=( "\${PIPESTATUS[@]}" )" + timeit "$stagemsg-SST" "$INNOBACKUP | $tcmd; RC=( "\${PIPESTATUS[@]}" )" set -e if [ ${RC[0]} -ne 0 ]; then 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 + elif [ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]; then wsrep_log_error "$tcmd finished with error: ${RC[1]}" exit 22 fi # mariabackup implicitly writes PID to fixed location in $xtmpdir - XTRABACKUP_PID="$xtmpdir/xtrabackup_pid" + MARIABACKUP_PID="$xtmpdir/xtrabackup_pid" else # BYPASS FOR IST @@ -984,19 +1046,19 @@ then tcmd="$ecmd | $tcmd" fi - strmcmd+=" '$IST_FILE'" + strmcmd="$strmcmd '$IST_FILE'" - send_donor "$DATA" "${stagemsg}-IST" + send_donor "$DATA" "$stagemsg-IST" fi - echo "done ${WSREP_SST_OPT_GTID}" + echo "done $WSREP_SST_OPT_GTID" wsrep_log_info "Total time on donor: $totime seconds" -elif [ "${WSREP_SST_OPT_ROLE}" = "joiner" ] +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" @@ -1015,7 +1077,7 @@ then ib_undo_dir="$INNODB_UNDO_DIR" - stagemsg="Joiner-Recv" + stagemsg='Joiner-Recv' sencrypted=1 nthreads=1 @@ -1041,42 +1103,41 @@ then exit 42 fi CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$tpem" | \ - tr "," "\n" | grep "CN =" | cut -d= -f2 | sed s/^\ // | \ + tr "," "\n" | grep -F 'CN =' | cut -d= -f2 | sed s/^\ // | \ sed s/\ %//) fi - MY_SECRET=$(wsrep_gen_secret) + 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" & - trap sig_joiner_cleanup HUP PIPE INT TERM trap cleanup_joiner EXIT if [ -n "$progress" ]; then adjust_progress - tcmd+=" | $pcmd" + tcmd="$tcmd | $pcmd" fi get_keys if [ $encrypt -eq 1 -a $sencrypted -eq 1 ]; then - if [ -n "$sdecomp" ]; then - strmcmd="$sdecomp | $ecmd | $strmcmd" - else - strmcmd="$ecmd | $strmcmd" - fi - elif [ -n "$sdecomp" ]; then - strmcmd="$sdecomp | $strmcmd" + strmcmd="$ecmd | $strmcmd" + fi + + if [ -n "$sdecomp" ]; then + strmcmd="$sdecomp | $strmcmd" fi - STATDIR=$(mktemp -d) + check_sockets_utils + + STATDIR="$(mktemp -d)" MAGIC_FILE="$STATDIR/$INFO_FILE" - recv_joiner "$STATDIR" "${stagemsg}-gtid" $stimeout 1 - if ! ps -p ${WSREP_SST_OPT_PARENT} &>/dev/null + recv_joiner "$STATDIR" "$stagemsg-gtid" $stimeout 1 1 + + if ! ps -p "$WSREP_SST_OPT_PARENT" &>/dev/null then wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly." exit 32 @@ -1090,12 +1151,12 @@ then rm -rf "$DATA/.sst" fi mkdir -p "$DATA/.sst" - (recv_joiner "$DATA/.sst" "${stagemsg}-SST" 0 0) & + (recv_joiner "$DATA/.sst" "$stagemsg-SST" 0 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 + if [ "$OS" = 'FreeBSD' ]; then find -E ${ib_home_dir:+"$ib_home_dir"} \ ${ib_undo_dir:+"$ib_undo_dir"} \ ${ib_log_dir:+"$ib_log_dir"} \ @@ -1128,13 +1189,13 @@ then get_proc - if [[ ! -s "$DATA/xtrabackup_checkpoints" ]];then + if [ ! -s "$DATA/xtrabackup_checkpoints" ]; then wsrep_log_error "xtrabackup_checkpoints missing, failed mariabackup/SST on donor" exit 2 fi # Compact backups are not supported by mariabackup - if grep -q 'compact = 1' "$DATA/xtrabackup_checkpoints"; then + if grep -q -F 'compact = 1' "$DATA/xtrabackup_checkpoints"; then wsrep_log_info "Index compaction detected" wsrel_log_error "Compact backups are not supported by mariabackup" exit 2 @@ -1149,13 +1210,12 @@ then exit 22 fi - if [[ -n "$progress" ]] && pv --help | grep -q 'line-mode';then + if [ -n "$progress" ] && pv --help | grep -qw -- '--line-mode'; then count=$(find "$DATA" -type f -name '*.qp' | wc -l) count=$(( count*2 )) - if pv --help | grep -q FORMAT;then - pvopts="-f -s $count -l -N Decompression -F '%N => Rate:%r Elapsed:%t %e Progress: [%b/$count]'" - else - pvopts="-f -s $count -l -N Decompression" + pvopts="-f -s $count -l -N Decompression" + if pv --help | grep -qw -- '-F'; then + pvopts="$pvopts -F '%N => Rate:%r Elapsed:%t %e Progress: [%b/$count]'" fi pcmd="pv $pvopts" adjust_progress @@ -1169,10 +1229,10 @@ then timeit "Joiner-Decompression" "find '$DATA' -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd" extcode=$? - if [[ $extcode -eq 0 ]];then + if [ $extcode -eq 0 ]; then wsrep_log_info "Removing qpress files after decompression" find "$DATA" -type f -name '*.qp' -delete - if [[ $? -ne 0 ]];then + if [ $? -ne 0 ]; then wsrep_log_error "Something went wrong with deletion of qpress files. Investigate" fi else @@ -1199,7 +1259,7 @@ then wsrep_log_info "Preparing the backup at ${DATA}" setup_commands - timeit "Xtrabackup prepare stage" "$INNOAPPLY" + timeit "mariabackup prepare stage" "$INNOAPPLY" if [ $? -ne 0 ]; then wsrep_log_error "${MARIABACKUP_BIN} apply finished with errors. Check syslog or ${INNOAPPLYLOG} for details" @@ -1208,8 +1268,8 @@ then MAGIC_FILE="$TDATA/$INFO_FILE" wsrep_log_info "Moving the backup to ${TDATA}" - timeit "Xtrabackup move stage" "$INNOMOVE" - if [[ $? -eq 0 ]];then + timeit "mariabackup move stage" "$INNOMOVE" + if [ $? -eq 0 ]; then wsrep_log_info "Move successful, removing ${DATA}" rm -rf "$DATA" DATA="$TDATA" @@ -1229,7 +1289,9 @@ 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}')" + + coords=$(cat "$MAGIC_FILE") + wsrep_log_info "Galera co-ords from recovery: $coords" cat "$MAGIC_FILE" # Output : UUID:seqno wsrep_gtid_domain_id wsrep_log_info "Total time on joiner: $totime seconds" diff --git a/scripts/wsrep_sst_mysqldump.sh b/scripts/wsrep_sst_mysqldump.sh index 3cc52398caa..e227a888baf 100644 --- a/scripts/wsrep_sst_mysqldump.sh +++ b/scripts/wsrep_sst_mysqldump.sh @@ -18,35 +18,18 @@ # This is a reference script for mysqldump-based state snapshot tansfer -. $(dirname $0)/wsrep_sst_common +. $(dirname "$0")/wsrep_sst_common PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin 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 - [ "$1" = "$(hostname -f)" ] && return 0 - [ "$1" = "$(hostname -d)" ] && return 0 - - # Now if ip program is not found in the path, we can't return 0 since - # it would block any address. Thankfully grep should fail in this case - ip route get "$1" | grep local >/dev/null && return 0 - - return 1 -} - if test -z "$WSREP_SST_OPT_HOST"; then wsrep_log_error "HOST cannot be nil"; exit $EINVAL; fi if test -z "$WSREP_SST_OPT_PORT"; then wsrep_log_error "PORT cannot be nil"; exit $EINVAL; fi if test -z "$WSREP_SST_OPT_LPORT"; then wsrep_log_error "LPORT cannot be nil"; exit $EINVAL; fi if test -z "$WSREP_SST_OPT_SOCKET";then wsrep_log_error "SOCKET cannot be nil";exit $EINVAL; fi if test -z "$WSREP_SST_OPT_GTID"; then wsrep_log_error "GTID cannot be nil"; exit $EINVAL; fi -if local_ip $WSREP_SST_OPT_HOST && \ +if is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED" && \ [ "$WSREP_SST_OPT_PORT" = "$WSREP_SST_OPT_LPORT" ] then wsrep_log_error \ @@ -111,7 +94,7 @@ then fi MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF "\ -"$AUTH -h${WSREP_SST_OPT_HOST_UNESCAPED} "\ +"$AUTH -h$WSREP_SST_OPT_HOST_UNESCAPED "\ "-P$WSREP_SST_OPT_PORT --disable-reconnect --connect_timeout=10" # Check if binary logging is enabled on the joiner node. @@ -139,7 +122,7 @@ then # 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 + if [ "$LOG_BIN" = 'ON' ]; then 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;" @@ -164,7 +147,6 @@ $MYSQL -e "$STOP_WSREP SET GLOBAL SLOW_QUERY_LOG=OFF" RESTORE_GENERAL_LOG="SET GLOBAL GENERAL_LOG=$GENERAL_LOG_OPT;" RESTORE_SLOW_QUERY_LOG="SET GLOBAL SLOW_QUERY_LOG=$SLOW_LOG_OPT;" - if [ $WSREP_SST_OPT_BYPASS -eq 0 ] then (echo $STOP_WSREP && echo $RESET_MASTER && \ diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index 8db5dbb5e40..70e4a3326a1 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -23,13 +23,13 @@ RSYNC_PID= # rsync pid file RSYNC_CONF= # rsync configuration file RSYNC_REAL_PID= # rsync process id -OS=$(uname) +OS="$(uname)" [ "$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 +. $(dirname "$0")/wsrep_sst_common wsrep_check_datadir wsrep_check_programs rsync @@ -48,7 +48,7 @@ cleanup_joiner() rm -rf "$MAGIC_FILE" rm -rf "$RSYNC_PID" wsrep_log_info "Joiner cleanup done." - if [ "${WSREP_SST_OPT_ROLE}" = "joiner" ];then + if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then wsrep_cleanup_progress_file fi } @@ -57,68 +57,71 @@ cleanup_joiner() check_pid() { local pid_file="$1" - [ -r "$pid_file" ] && ps -p $(cat "$pid_file") >/dev/null 2>&1 + [ -r "$pid_file" ] && ps -p $(cat "$pid_file") 2>&1 >/dev/null } check_pid_and_port() { local pid_file="$1" local rsync_pid=$2 - local rsync_addr=$3 - local rsync_port=$4 - - case $OS in - FreeBSD) - local port_info="$(sockstat -46lp ${rsync_port} 2>/dev/null | \ - grep ":${rsync_port}")" - local is_rsync="$(echo $port_info | \ - grep -E '[[:space:]]+(rsync|stunnel)[[:space:]]+'"$rsync_pid" 2>/dev/null)" - ;; - *) - 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 | \ - grep -E '^(rsync|stunnel)[[:space:]]+'"$rsync_pid" 2>/dev/null)" - ;; - esac + local rsync_addr="$3" + local rsync_port="$4" + + if [ -z "$rsync_port" -o -z "$rsync_addr" -o -z "$rsync_pid" ]; then + wsrep_log_error "check_pid_and_port(): bad arguments" + exit 2 # ENOENT + fi - local is_listening_all="$(echo $port_info | \ - grep "*:$rsync_port" 2>/dev/null)" - local is_listening_addr="$(echo $port_info | \ - grep -F "$rsync_addr:$rsync_port" 2>/dev/null)" + local port_info is_rsync + + if [ $lsof_available -ne 0 ]; then + port_info=$(lsof -i ":$rsync_port" -Pn 2>/dev/null | \ + grep -F '(LISTEN)') + is_rsync=$(echo "$port_info" | \ + grep -E "^(rsync|stunnel)[^[:space:]]*[[:space:]]+$rsync_pid[[:space:]]+") + elif [ $sockstat_available -ne 0 ]; then + port_info=$(sockstat -p "$rsync_port" 2>/dev/null | \ + grep -F 'LISTEN') + is_rsync=$(echo "$port_info" | \ + grep -E "[[:space:]]+(rsync|stunnel)[^[:space:]]*[[:space:]]+$rsync_pid[[:space:]]+") + elif [ $ss_available -ne 0 ]; then + port_info=$(ss -H -p -n -l "( sport = :$rsync_port )" 2>/dev/null) + is_rsync=$(echo "$port_info" | \ + grep -E "users:\\(.*\\(\"(rsync|stunnel)[^[:space:]]*\".*\<pid=$rsync_pid\>.*\\)") + else + wsrep_log_error "unknown sockets utility" + exit 2 # ENOENT + fi - if [ ! -z "$is_listening_all" -o ! -z "$is_listening_addr" ]; then - if [ -z "$is_rsync" ]; then - wsrep_log_error "rsync daemon port '$rsync_port' has been taken" + if [ -z "$is_rsync" ]; then + local is_listening_all + if [ $lsof_available -ne 0 ]; then + is_listening_all=$(echo "$port_info" | \ + grep -E "[[:space:]](\\*|\\[?::\\]?):$rsync_port[[:space:]]") + else + if [ $sockstat_available -eq 0 ]; then + port_info=$(echo "$port_info" | grep -q -F 'users:(') + fi + port_info=$(echo "$port_info" | \ + grep -E "[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+" -o) + is_listening_all=$(echo "$port_info" | \ + grep -E "[[:space:]](\\*|\\[?::\\]?):$rsync_port\$") + fi + local is_listening_addr=$(echo "$port_info" | \ + grep -w -F -- "$rsync_addr:$rsync_port") + if [ -z "$is_listening_addr" ]; then + is_listening_addr=$(echo "$port_info" | \ + grep -w -F "[$rsync_addr]:$rsync_port") + fi + if [ -n "$is_listening_all" -o -n "$is_listening_addr" ]; then + wsrep_log_error "rsync or stunnel daemon port '$rsync_port' " \ + "has been taken by another program" exit 16 # EBUSY fi + return 1 fi - check_pid "$pid_file" && \ - [ -n "$port_info" ] && [ -n "$is_rsync" ] && \ - [ $(cat "$pid_file") -eq $rsync_pid ] -} -is_local_ip() -{ - local address="$1" - local get_addr_bin="$(command -v ifconfig)" - if [ -z "$get_addr_bin" ] - then - 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/" - 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 " - fi - - $get_addr_bin | grep -F "$address" > /dev/null + check_pid "$pid_file" && [ $(cat "$pid_file") -eq $rsync_pid ] } STUNNEL_CONF="$WSREP_SST_OPT_DATA/stunnel.conf" @@ -296,7 +299,7 @@ foreground = yes pid = $STUNNEL_PID debug = warning client = yes -connect = ${WSREP_SST_OPT_ADDR%/*} +connect = $WSREP_SST_OPT_HOST_UNESCAPED:$WSREP_SST_OPT_PORT TIMEOUTclose = 0 ${VERIFY_OPT} EOF @@ -322,7 +325,7 @@ EOF # (b) Cluster state ID & wsrep_gtid_domain_id to be written to the file, OR # (c) ERROR file, in case flush tables operation failed. - while [ ! -r "$FLUSHED" ] && ! grep -q ':' "$FLUSHED" >/dev/null 2>&1 + while [ ! -r "$FLUSHED" ] && ! grep -q -F ':' "$FLUSHED" >/dev/null 2>&1 do # Check whether ERROR file exists. if [ -f "$ERROR" ] @@ -368,12 +371,11 @@ EOF eval rsync "'${STUNNEL:+--rsh=$STUNNEL}'" \ --owner --group --perms --links --specials \ --ignore-times --inplace --dirs --delete --quiet \ - $WHOLE_FILE_OPT ${FILTER} "'$WSREP_SST_OPT_DATA/'" \ + $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:" - case $RC in 12) RC=71 # EPROTO wsrep_log_error \ @@ -414,21 +416,23 @@ EOF exit 255 # unknown error fi - # then, we parallelize the transfer of database directories, use . so that pathconcatenation works + # then, we parallelize the transfer of database directories, + # use . so that path concatenation works: + cd "$WSREP_SST_OPT_DATA" count=1 - [ "$OS" = "Linux" ] && count=$(grep -c processor /proc/cpuinfo) - [ "$OS" = "Darwin" -o "$OS" = "FreeBSD" ] && count=$(sysctl -n hw.ncpu) + [ "$OS" = 'Linux' ] && count=$(grep -c processor /proc/cpuinfo) + [ "$OS" = 'Darwin' -o "$OS" = 'FreeBSD' ] && count=$(sysctl -n hw.ncpu) - find . -maxdepth 1 -mindepth 1 -type d -not -name "lost+found" -not -name ".zfs" \ - -print0 | xargs -I{} -0 -P $count \ + find . -maxdepth 1 -mindepth 1 -type d -not -name 'lost+found' \ + -not -name '.zfs' -print0 | xargs -I{} -0 -P $count \ 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=$? + --exclude '*/aria_log_control' "$WSREP_SST_OPT_DATA/{}/" \ + "rsync://$WSREP_SST_OPT_ADDR/{}" >&2 || RC=$? cd "$OLD_PWD" @@ -463,7 +467,7 @@ EOF elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ] then - wsrep_check_programs lsof + check_sockets_utils touch "$SST_PROGRESS_FILE" MYSQLD_PID="$WSREP_SST_OPT_PARENT" @@ -490,6 +494,7 @@ then ADDR="$WSREP_SST_OPT_ADDR" RSYNC_PORT="$WSREP_SST_OPT_PORT" RSYNC_ADDR="$WSREP_SST_OPT_HOST" + RSYNC_ADDR_UNESCAPED="$WSREP_SST_OPT_HOST_UNESCAPED" trap "exit 32" HUP PIPE trap "exit 3" INT TERM ABRT @@ -521,10 +526,10 @@ EOF # rm -rf "$DATA"/ib_logfile* # we don't want old logs around # If the IP is local listen only in it - if is_local_ip "$RSYNC_ADDR" + if is_local_ip "$RSYNC_ADDR_UNESCAPED" then - RSYNC_EXTRA_ARGS="--address $RSYNC_ADDR" - STUNNEL_ACCEPT="$RSYNC_ADDR:$RSYNC_PORT" + RSYNC_EXTRA_ARGS="--address $RSYNC_ADDR_UNESCAPED" + STUNNEL_ACCEPT="$RSYNC_ADDR_UNESCAPED:$RSYNC_PORT" else # Not local, possibly a NAT, listen on all interfaces RSYNC_EXTRA_ARGS="" @@ -535,7 +540,7 @@ EOF if [ -z "$STUNNEL" ] then - rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" ${RSYNC_EXTRA_ARGS} & + rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS & RSYNC_REAL_PID=$! else cat << EOF > "$STUNNEL_CONF" @@ -545,6 +550,7 @@ ${CAFILE_OPT} foreground = yes pid = $STUNNEL_PID debug = warning +debug = 6 client = no [rsync] accept = $STUNNEL_ACCEPT @@ -556,7 +562,7 @@ EOF RSYNC_PID="$STUNNEL_PID" fi - until check_pid_and_port "$RSYNC_PID" "$RSYNC_REAL_PID" "$RSYNC_ADDR" "$RSYNC_PORT" + until check_pid_and_port "$RSYNC_PID" "$RSYNC_REAL_PID" "$RSYNC_ADDR_UNESCAPED" "$RSYNC_PORT" do sleep 0.2 done @@ -573,10 +579,10 @@ EOF exit 42 fi CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$SSTCERT" | \ - tr "," "\n" | grep "CN =" | cut -d= -f2 | sed s/^\ // | \ + tr "," "\n" | grep -F 'CN =' | cut -d= -f2 | sed s/^\ // | \ sed s/\ %//) fi - MY_SECRET=$(wsrep_gen_secret) + MY_SECRET="$(wsrep_gen_secret)" # Add authentication data to address ADDR="$CN:$MY_SECRET@$WSREP_SST_OPT_HOST" else @@ -626,7 +632,7 @@ EOF if [ -r "$MAGIC_FILE" ] then # check donor supplied secret - SECRET=$(grep "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2) + SECRET=$(grep -F -- "$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'" @@ -634,7 +640,7 @@ EOF fi # remove secret from magic file - grep -v "$SECRET_TAG " "$MAGIC_FILE" > "$MAGIC_FILE.new" + grep -v -F -- "$SECRET_TAG " "$MAGIC_FILE" > "$MAGIC_FILE.new" mv "$MAGIC_FILE.new" "$MAGIC_FILE" # UUID:seqno & wsrep_gtid_domain_id is received here. @@ -645,7 +651,7 @@ EOF fi wsrep_cleanup_progress_file -# cleanup_joiner +# cleanup_joiner else wsrep_log_error "Unrecognized role: '$WSREP_SST_OPT_ROLE'" exit 22 # EINVAL diff --git a/scripts/wsrep_sst_xtrabackup-v2.sh b/scripts/wsrep_sst_xtrabackup-v2.sh index c1c9a41bdf2..7718e52184a 100644 --- a/scripts/wsrep_sst_xtrabackup-v2.sh +++ b/scripts/wsrep_sst_xtrabackup-v2.sh @@ -16,10 +16,11 @@ # 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 +. $(dirname "$0")/wsrep_sst_common wsrep_check_datadir ealgo="" @@ -72,13 +73,13 @@ ssl_cert="" ssl_ca="" ssl_key="" -if which pv &>/dev/null && pv --help | grep -q FORMAT;then +if [ -x "$(command -v pv)" ] && pv --help | grep -qw -- '-F'; then pvopts+=$pvformat fi pcmd="pv $pvopts" declare -a RC -INNOBACKUPEX_BIN=innobackupex +INNOBACKUPEX_BIN='innobackupex' DATA="${WSREP_SST_OPT_DATA}" INFO_FILE="xtrabackup_galera_info" IST_FILE="xtrabackup_ist" @@ -87,9 +88,9 @@ MAGIC_FILE="${DATA}/${INFO_FILE}" # Setting the path for ss and ip export PATH="/usr/sbin:/sbin:$PATH" -OS=$(uname) +OS="$(uname)" -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 @@ -131,7 +132,7 @@ get_keys() 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 @@ -251,10 +252,8 @@ get_transfer() TSST_PORT="$WSREP_SST_OPT_PORT" if [[ $tfmt == 'nc' ]];then - if [[ ! -x `which nc` ]];then - wsrep_log_error "nc(netcat) not found in path: $PATH" - exit 2 - fi + wsrep_log_info "Using netcat as streamer" + wsrep_check_programs nc if [[ $encrypt -eq 2 || $encrypt -eq 3 || $encrypt -eq 4 ]]; then wsrep_log_error "******** FATAL ERROR *********************** " @@ -264,25 +263,25 @@ get_transfer() exit 22 fi - wsrep_log_info "Using netcat as streamer" - 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 - # Debian netcat - if [ $WSREP_SST_OPT_HOST_IPv6 -eq 1 ];then + tcmd="nc" + if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then + if nc -h 2>&1 | grep -q 'ncat'; then + wsrep_log_info "Using Ncat as streamer" + tcmd="$tcmd -l" + elif nc -h 2>&1 | grep -qw -- '-d'; then + wsrep_log_info "Using Debian netcat as streamer" + tcmd="$tcmd -dl" + 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}" + tcmd="$tcmd -6" fi else - # traditional netcat - tcmd="nc -l -p ${TSST_PORT}" + wsrep_log_info "Using traditional netcat as streamer" + tcmd="$tcmd -l -p" fi + tcmd="$tcmd $TSST_PORT" else # Check to see if netcat supports the '-N' flag. # -N Shutdown the network socket after EOF on stdin @@ -291,30 +290,25 @@ get_transfer() # 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" + if nc -h 2>&1 | grep -qw -- '-N'; then + tcmd="$tcmd -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 - tcmd="nc ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}" - elif nc -h 2>&1 | grep -qw -- '-d\>';then - # Debian netcat - tcmd="nc ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}" + if nc -h 2>&1 | grep -q ncat; then + wsrep_log_info "Using Ncat as streamer" + elif nc -h 2>&1 | grep -qw -- '-d'; then + wsrep_log_info "Using Debian netcat as streamer" else - # traditional netcat - tcmd="nc -q0 ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}" + wsrep_log_info "Using traditional netcat as streamer" + tcmd="$tcmd -q0" fi + tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT" fi else tfmt='socat' wsrep_log_info "Using socat as streamer" - if [[ ! -x `which socat` ]];then - wsrep_log_error "socat not found in path: $PATH" - exit 2 - fi + wsrep_check_programs socat donor_extra="" joiner_extra="" @@ -438,7 +432,7 @@ get_footprint() adjust_progress() { - if [[ ! -x `which pv` ]];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="" @@ -529,7 +523,7 @@ get_stream() { if [[ $sfmt == 'xbstream' ]];then wsrep_log_info "Streaming with xbstream" - if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then + if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then strmcmd="xbstream -x" else strmcmd="xbstream -c '${INFO_FILE}'" @@ -537,7 +531,7 @@ get_stream() else sfmt="tar" wsrep_log_info "Streaming with tar" - if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then + if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then strmcmd="tar xfi -" else strmcmd="tar cf - '${INFO_FILE}'" @@ -720,8 +714,8 @@ 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 -a -x "$(command -v timeout)" ]; then + if timeout --help | grep -qw -- '-k';then ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd" else ltcmd="timeout -s9 $tmt $tcmd" @@ -751,7 +745,7 @@ recv_joiner() # 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}/*)" + wsrep_log_info $(ls -l "$dir/"*) exit 32 fi } @@ -802,8 +796,8 @@ normalize_version() # Returns 1 (failure) if $1 >= $2, 0 (success) otherwise check_for_version() { - local local_version_str="$( normalize_version $1 )" - local required_version_str="$( normalize_version $2 )" + local local_version_str=$(normalize_version "$1") + local required_version_str=$(normalize_version "$2") if [[ "$local_version_str" < "$required_version_str" ]]; then return 1 @@ -833,7 +827,8 @@ monitor_process() done } -if [[ ! -x `which $INNOBACKUPEX_BIN` ]];then +innobackup=$(command -v "$INNOBACKUPEX_BIN") +if [ ! -x "$innobackup" ]; then wsrep_log_error "innobackupex not in path: $PATH" exit 2 fi @@ -848,21 +843,21 @@ if [[ -z "$XB_VERSION" ]]; then exit 2 fi -if ! check_for_version $XB_VERSION $XB_REQUIRED_VERSION; then +if ! check_for_version "$XB_VERSION" "$XB_REQUIRED_VERSION"; then wsrep_log_error "FATAL: The $INNOBACKUPEX_BIN version is $XB_VERSION. Needs xtrabackup-$XB_REQUIRED_VERSION or higher to perform SST" 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 -qw -- '--version-check'; then disver='--no-version-check' fi @@ -874,7 +869,7 @@ if [ ${FORCE_FTWRL:-0} -eq 1 ]; then fi if [[ $ssyslog -eq 1 ]];then - if [[ ! -x `which logger` ]];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" @@ -891,8 +886,8 @@ if [[ $ssyslog -eq 1 ]];then logger -p daemon.info -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" } - INNOAPPLY="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply " - INNOMOVE="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move " + 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)" fi else @@ -1008,7 +1003,7 @@ then # Add encryption to the head of the stream (if specified) if [[ $encrypt -eq 1 ]]; then - tcmd=" \$ecmd | $tcmd " + tcmd="\$ecmd | $tcmd" fi setup_commands @@ -1182,15 +1177,15 @@ then if [ -n "$qpfiles" ]; then wsrep_log_info "Compressed qpress files found" - if [[ ! -x `which qpress` ]];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 + if [[ -n "$progress" ]] && pv --help | grep -qw '--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 -qw -F '-F';then pvopts="-f -s $count -l -N Decompression -F '%N => Rate:%r Elapsed:%t %e Progress: [%b/$count]'" else pvopts="-f -s $count -l -N Decompression" @@ -1269,8 +1264,11 @@ 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 + + coords=$(cat "$MAGIC_FILE") + wsrep_log_info "Galera co-ords from recovery: $coords" + 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_xtrabackup.sh b/scripts/wsrep_sst_xtrabackup.sh index b8ca7f43ed6..b9fedaadd3a 100644 --- a/scripts/wsrep_sst_xtrabackup.sh +++ b/scripts/wsrep_sst_xtrabackup.sh @@ -16,10 +16,11 @@ # 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 +. $(dirname "$0")/wsrep_sst_common wsrep_check_datadir ealgo="" @@ -51,13 +52,13 @@ 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 [ -x "$(command -v pv)" ] && pv --help | grep -qw -- '-F'; then pvopts+=$pvformat fi pcmd="pv $pvopts" declare -a RC -INNOBACKUPEX_BIN=innobackupex +INNOBACKUPEX_BIN='innobackupex' DATA="${WSREP_SST_OPT_DATA}" INFO_FILE="xtrabackup_galera_info" IST_FILE="xtrabackup_ist" @@ -67,7 +68,7 @@ MAGIC_FILE="${DATA}/${INFO_FILE}" export PATH="/usr/sbin:/sbin:$PATH" timeit(){ - local stage=$1 + local stage="$1" shift local cmd="$@" local x1 x2 took extcode @@ -102,7 +103,7 @@ get_keys() 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=0 return @@ -110,17 +111,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 ecmd="xbcrypt --encrypt-algo=$ealgo --encrypt-key=$ekey" @@ -136,43 +137,56 @@ get_transfer() TSST_PORT=$WSREP_SST_OPT_PORT if [[ $tfmt == 'nc' ]];then - if [[ ! -x `which nc` ]];then - wsrep_log_error "nc(netcat) not found in path: $PATH" - exit 2 - fi wsrep_log_info "Using netcat as streamer" - if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then - if nc -h 2>&1 | grep -q ncat;then - # Ncat - tcmd="nc -l ${TSST_PORT}" - elif nc -h 2>&1 | grep -q -- '-d\>';then - # Debian netcat - tcmd="nc -dl ${TSST_PORT}" + wsrep_check_programs nc + tcmd="nc" + if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then + if nc -h 2>&1 | grep -q 'ncat'; then + wsrep_log_info "Using Ncat as streamer" + tcmd="$tcmd -l" + elif nc -h 2>&1 | grep -qw -- '-d'; then + wsrep_log_info "Using Debian netcat as streamer" + tcmd="$tcmd -dl" + 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="$tcmd -6" + fi else - # traditional netcat - tcmd="nc -l -p ${TSST_PORT}" + wsrep_log_info "Using traditional netcat as streamer" + tcmd="$tcmd -l -p" fi + tcmd="$tcmd $TSST_PORT" else - if nc -h 2>&1 | grep -q ncat;then - # Ncat - tcmd="nc ${REMOTEIP} ${TSST_PORT}" - elif nc -h 2>&1 | grep -q -- '-d\>';then - # Debian netcat - tcmd="nc ${REMOTEIP} ${TSST_PORT}" + # 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. + if nc -h 2>&1 | grep -qw -- '-N'; then + tcmd="$tcmd -N" + wsrep_log_info "Using nc -N" + fi + # netcat doesn't understand [] around IPv6 address + if nc -h 2>&1 | grep -q ncat; then + wsrep_log_info "Using Ncat as streamer" + elif nc -h 2>&1 | grep -qw -- '-d'; then + wsrep_log_info "Using Debian netcat as streamer" else - # traditional netcat - tcmd="nc -q0 ${REMOTEIP} ${TSST_PORT}" + wsrep_log_info "Using traditional netcat as streamer" + tcmd="$tcmd -q0" fi + tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT" fi else tfmt='socat' wsrep_log_info "Using socat as streamer" - if [[ ! -x `which socat` ]];then - wsrep_log_error "socat not found in path: $PATH" - exit 2 - fi + wsrep_check_programs socat - if [[ $encrypt -eq 2 ]] && ! socat -V | grep -q OPENSSL;then + if [ $encrypt -eq 2 ] && ! socat -V | grep -q -F 'OPENSSL';then wsrep_log_info "NOTE: socat is not openssl enabled, falling back to plain transfer" encrypt=0 fi @@ -202,7 +216,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 @@ -216,18 +230,18 @@ 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 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 @@ -304,7 +318,7 @@ 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 @@ -324,18 +338,18 @@ 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 fi - rm -f $XTRABACKUP_PID + rm -f "$XTRABACKUP_PID" fi - rm -f ${DATA}/${IST_FILE} + 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 @@ -343,8 +357,8 @@ cleanup_donor() kill_xtrabackup() { - local PID=$(cat $XTRABACKUP_PID) - [ -n "$PID" -a "0" != "$PID" ] && kill $PID && (kill $PID && kill -9 $PID) || : + local PID=$(cat "$XTRABACKUP_PID") + [ -n "$PID" -a $PID -ne 0 ] && kill $PID && (kill $PID && kill -9 $PID) || : rm -f "$XTRABACKUP_PID" } @@ -392,7 +406,7 @@ check_extra() fi } -if [[ ! -x `which innobackupex` ]];then +if [ ! -x "$(command -v innobackupex)" ]; then wsrep_log_error "innobackupex not in path: $PATH" exit 2 fi @@ -507,10 +521,10 @@ then elif [ "${WSREP_SST_OPT_ROLE}" = "joiner" ] then - [[ -e $SST_PROGRESS_FILE ]] && wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE" - touch $SST_PROGRESS_FILE + [[ -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 @@ -527,11 +541,11 @@ then MODULE="xtrabackup_sst" # 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" ADDR="${WSREP_SST_OPT_HOST}:${WSREP_SST_OPT_PORT}" - wait_for_listen ${WSREP_SST_OPT_PORT} ${ADDR} ${MODULE} & + wait_for_listen "${WSREP_SST_OPT_PORT}" "${ADDR}" "${MODULE}" & trap sig_joiner_cleanup HUP PIPE INT TERM trap cleanup_joiner EXIT @@ -543,14 +557,14 @@ then if [[ $incremental -eq 1 ]];then BDATA=$DATA - DATA=$(mktemp -d) + DATA="$(mktemp -d)" MAGIC_FILE="${DATA}/${INFO_FILE}" fi get_keys set +e if [[ $encrypt -eq 1 && $sencrypted -eq 1 ]];then - strmcmd=" $ecmd | $strmcmd" + strmcmd="$ecmd | $strmcmd" fi pushd ${DATA} 1>/dev/null @@ -584,7 +598,7 @@ then # this message should cause joiner to abort wsrep_log_error "xtrabackup process ended without creating '${MAGIC_FILE}'" wsrep_log_info "Contents of datadir" - wsrep_log_info "$(ls -l ${DATA}/**/*)" + wsrep_log_info $(ls -l "${DATA}"/**/*) exit 32 fi @@ -600,9 +614,9 @@ then wsrep_log_info "Removing existing ib_logfile files" if [[ $incremental -ne 1 ]];then - rm -f ${DATA}/ib_logfile* + rm -f "${DATA}/ib_logfile"* else - rm -f ${BDATA}/ib_logfile* + rm -f "${BDATA}/ib_logfile"* fi get_proc @@ -619,19 +633,19 @@ then rebuildcmd="--rebuild-indexes --rebuild-threads=$nthreads" fi - if test -n "$(find ${DATA} -maxdepth 1 -type f -name '*.qp' -print -quit)";then + if test -n $(find "${DATA}" -maxdepth 1 -type f -name '*.qp' -print -quit); then wsrep_log_info "Compressed qpress files found" - if [[ ! -x `which qpress` ]];then + 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 -qw -- '--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 -qw -F '-F';then pvopts="-f -s $count -l -N Decompression -F '%N => Rate:%r Elapsed:%t %e Progress: [%b/$count]'" else pvopts="-f -s $count -l -N Decompression" @@ -644,11 +658,11 @@ then fi wsrep_log_info "Removing existing ibdata1 file" - rm -f ${DATA}/ibdata1 + rm -f "${DATA}/ibdata1" # 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" + timeit "Decompression" "find '${DATA}' -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd" extcode=$? if [[ $extcode -eq 0 ]];then |