summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-06-01 11:39:38 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2021-06-01 11:39:38 +0300
commita722ee88f33296eee6a72855570677c48dce7ebf (patch)
tree128ce4696a80fd953836b4a9eed20ab8afc4e61c /scripts
parent5727d56260e66d9b9f2dee6783385c5928d4f3a3 (diff)
parent9c7a456a92262bdb44b85a05aa9f87369c5b063c (diff)
downloadmariadb-git-a722ee88f33296eee6a72855570677c48dce7ebf.tar.gz
Merge 10.5 into 10.6
Diffstat (limited to 'scripts')
-rw-r--r--scripts/wsrep_sst_common.sh381
-rw-r--r--scripts/wsrep_sst_mariabackup.sh523
-rw-r--r--scripts/wsrep_sst_mysqldump.sh4
-rw-r--r--scripts/wsrep_sst_rsync.sh283
4 files changed, 740 insertions, 451 deletions
diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
index 952a37f75d2..05944ef6035 100644
--- a/scripts/wsrep_sst_common.sh
+++ b/scripts/wsrep_sst_common.sh
@@ -29,7 +29,9 @@ 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_DEFAULTS=""
WSREP_SST_OPT_EXTRA_DEFAULT=""
+WSREP_SST_OPT_EXTRA_DEFAULTS=""
WSREP_SST_OPT_SUFFIX_DEFAULT=""
WSREP_SST_OPT_SUFFIX_VALUE=""
WSREP_SST_OPT_MYSQLD=""
@@ -152,10 +154,12 @@ case "$1" in
;;
'--defaults-file')
readonly WSREP_SST_OPT_DEFAULT="$1=$2"
+ readonly WSREP_SST_OPT_DEFAULTS="$1='$2'"
shift
;;
'--defaults-extra-file')
readonly WSREP_SST_OPT_EXTRA_DEFAULT="$1=$2"
+ readonly WSREP_SST_OPT_EXTRA_DEFAULTS="$1='$2'"
shift
;;
'--defaults-group-suffix')
@@ -295,7 +299,7 @@ case "$1" in
value="$1"
fi
fi
- if [ $option == 'h' ]; then
+ if [ $option = 'h' ]; then
if [ -z "$WSREP_SST_OPT_DATA" ]; then
MYSQLD_OPT_DATADIR="${value%/}"
fi
@@ -611,24 +615,54 @@ else
MYSQLDUMP="$(command -v mysqldump)"
fi
+wsrep_log()
+{
+ # echo everything to stderr so that it gets into common error log
+ # deliberately made to look different from the rest of the log
+ local readonly tst="$(date +%Y%m%d\ %H:%M:%S.%N | cut -b -21)"
+ echo "WSREP_SST: $* ($tst)" >&2
+}
+
+wsrep_log_error()
+{
+ wsrep_log "[ERROR] $*"
+}
+
+wsrep_log_warning()
+{
+ wsrep_log "[WARNING] $*"
+}
+
+wsrep_log_info()
+{
+ wsrep_log "[INFO] $*"
+}
+
if [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then
MY_PRINT_DEFAULTS="$SCRIPTS_DIR/my_print_defaults"
elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then
MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults"
else
MY_PRINT_DEFAULTS="$(command -v my_print_defaults)"
+ if [ -z "$MY_PRINT_DEFAULTS" ]; then
+ wsrep_log_error "my_print_defaults not found in path"
+ exit 2
+ fi
fi
+readonly MY_PRINT_DEFAULTS
+
+wsrep_defaults="$WSREP_SST_OPT_DEFAULTS"
+wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_EXTRA_DEFAULTS"
+wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT"
+
+readonly WSREP_SST_OPT_CONF="$wsrep_defaults"
+
wsrep_defaults="$WSREP_SST_OPT_DEFAULT"
-if [ -n "$wsrep_defaults" ]; then
- wsrep_defaults="$wsrep_defaults "
-fi
-wsrep_defaults="$wsrep_defaults$WSREP_SST_OPT_EXTRA_DEFAULT"
-if [ -n "$wsrep_defaults" ]; then
- 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"
+wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_EXTRA_DEFAULT"
+wsrep_defaults="$wsrep_defaults${wsrep_defaults:+ }$WSREP_SST_OPT_SUFFIX_DEFAULT"
+
+readonly WSREP_SST_OPT_CONF_UNQUOTED="$wsrep_defaults"
#
# User can specify mariabackup specific settings that will be used during sst
@@ -663,13 +697,21 @@ parse_cnf()
# If the group name is the same as the "mysqld" without "--" prefix,
# 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")
+ reval=$("$MY_PRINT_DEFAULTS" \
+ ${WSREP_SST_OPT_DEFAULT:+"$WSREP_SST_OPT_DEFAULT"} \
+ ${WSREP_SST_OPT_EXTRA_DEFAULT:+"$WSREP_SST_OPT_EXTRA_DEFAULT"} \
+ ${WSREP_SST_OPT_SUFFIX_DEFAULT:+"$WSREP_SST_OPT_SUFFIX_DEFAULT"} \
+ "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")
+ reval=$("$MY_PRINT_DEFAULTS" \
+ ${WSREP_SST_OPT_DEFAULT:+"$WSREP_SST_OPT_DEFAULT"} \
+ ${WSREP_SST_OPT_EXTRA_DEFAULT:+"$WSREP_SST_OPT_EXTRA_DEFAULT"} \
+ ${WSREP_SST_OPT_SUFFIX_DEFAULT:+"$WSREP_SST_OPT_SUFFIX_DEFAULT"} \
+ "$group" | awk "$pattern")
if [ -n "$reval" ]; then
break
fi
@@ -710,13 +752,21 @@ in_config()
# If the group name is the same as the "mysqld" without "--" prefix,
# 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")
+ found=$("$MY_PRINT_DEFAULTS" \
+ ${WSREP_SST_OPT_DEFAULT:+"$WSREP_SST_OPT_DEFAULT"} \
+ ${WSREP_SST_OPT_EXTRA_DEFAULT:+"$WSREP_SST_OPT_EXTRA_DEFAULT"} \
+ ${WSREP_SST_OPT_SUFFIX_DEFAULT:+"$WSREP_SST_OPT_SUFFIX_DEFAULT"} \
+ "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")
+ found=$($MY_PRINT_DEFAULTS \
+ ${WSREP_SST_OPT_DEFAULT:+"$WSREP_SST_OPT_DEFAULT"} \
+ ${WSREP_SST_OPT_EXTRA_DEFAULT:+"$WSREP_SST_OPT_EXTRA_DEFAULT"} \
+ ${WSREP_SST_OPT_SUFFIX_DEFAULT:+"$WSREP_SST_OPT_SUFFIX_DEFAULT"} \
+ "$group" | awk "$pattern")
if [ $found -ne 0 ]; then
break
fi
@@ -797,29 +847,6 @@ else
SST_PROGRESS_FILE=""
fi
-wsrep_log()
-{
- # echo everything to stderr so that it gets into common error log
- # deliberately made to look different from the rest of the log
- local readonly tst="$(date +%Y%m%d\ %H:%M:%S.%N | cut -b -21)"
- echo "WSREP_SST: $* ($tst)" >&2
-}
-
-wsrep_log_error()
-{
- wsrep_log "[ERROR] $*"
-}
-
-wsrep_log_warning()
-{
- wsrep_log "[WARNING] $*"
-}
-
-wsrep_log_info()
-{
- wsrep_log "[INFO] $*"
-}
-
wsrep_cleanup_progress_file()
{
[ -n "$SST_PROGRESS_FILE" -a \
@@ -960,35 +987,139 @@ check_sockets_utils()
}
#
+# Check if the port is in the "listen" state.
+# The first parameter is the PID of the process that should
+# listen on the port - if it is not known, you can specify
+# an empty string or zero.
+# The second parameter is the port number.
+# The third parameter is a list of the names of utilities
+# (via "|") that can listen on this port during the state
+# transfer.
+#
+check_port()
+{
+ local pid="$1"
+ local port="$2"
+ local utils="$3"
+
+ [ -z "$pid" ] || [ $pid -eq 0 ] && pid='[0-9]+'
+
+ local rc=1
+
+ if [ $lsof_available -ne 0 ]; then
+ lsof -Pnl -i ":$port" 2>/dev/null | \
+ grep -q -E "^($utils)[^[:space:]]*[[:space:]]+$pid[[:space:]].*\\(LISTEN\\)" && rc=0
+ elif [ $sockstat_available -ne 0 ]; then
+ sockstat -p "$port" 2>/dev/null | \
+ grep -q -E "[[:space:]]+($utils)[^[:space:]]*[[:space:]]+$pid[[:space:]].*[[:space:]]LISTEN" && rc=0
+ elif [ $ss_available -ne 0 ]; then
+ ss -nlpH "( sport = :$port )" 2>/dev/null | \
+ grep -q -E "users:\\(.*\\(\"($utils)[^[:space:]]*\"[^)]*,pid=$pid(,[^)]*)?\\)" && rc=0
+ else
+ wsrep_log_error "unknown sockets utility"
+ exit 2 # ENOENT
+ fi
+
+ return $rc
+}
+
+#
# If the ssl_dhparams variable is already set, uses that as a source
# of dh parameters for OpenSSL. Otherwise, looks for dhparams.pem in
# the datadir, and creates it there if it can't find the file.
#
check_for_dhparams()
{
- if [ -z "$ssl_dhparams" ]; then
- ssl_dhparams="$DATA/dhparams.pem"
- if [ ! -r "$ssl_dhparams" ]; then
- get_openssl
- if [ -n "$OPENSSL_BINARY" ]; then
- wsrep_log_info "Could not find dhparams file, creating $ssl_dhparams"
- if ! "$OPENSSL_BINARY" dhparam -out "$ssl_dhparams" 2048 >/dev/null 2>&1
- then
- wsrep_log_error "******** ERROR *****************************************"
- wsrep_log_error "* Could not create the dhparams.pem file with OpenSSL. *"
- wsrep_log_error "********************************************************"
- ssl_dhparams=""
- fi
- else
- # Rollback: if openssl is not installed, then use
- # the default parameters:
+ ssl_dhparams="$DATA/dhparams.pem"
+ if [ ! -r "$ssl_dhparams" ]; then
+ get_openssl
+ if [ -n "$OPENSSL_BINARY" ]; then
+ wsrep_log_info "Could not find dhparams file, creating $ssl_dhparams"
+ if ! "$OPENSSL_BINARY" dhparam -out "$ssl_dhparams" 2048 >/dev/null 2>&1
+ then
+ wsrep_log_error "******** ERROR *****************************************"
+ wsrep_log_error "* Could not create the dhparams.pem file with OpenSSL. *"
+ wsrep_log_error "********************************************************"
ssl_dhparams=""
- fi
+ fi
+ else
+ # Rollback: if openssl is not installed, then use
+ # the default parameters:
+ ssl_dhparams=""
fi
fi
}
#
+# Verifies that the CA file verifies the certificate.
+# Doing this here lets us generate better error messages.
+#
+# 1st param: path to the CA file.
+# 2nd param: path to the certificate.
+#
+verify_ca_matches_cert()
+{
+ local ca_path="$1"
+ local cert_path="$2"
+
+ # If the openssl utility is not installed, then
+ # we will not do this certificate check:
+ get_openssl
+ if [ -z "$OPENSSL_BINARY" ]; then
+ return
+ fi
+
+ if ! "$OPENSSL_BINARY" verify -verbose -CAfile "$ca_path" "$cert_path" >/dev/null 2>&1
+ then
+ wsrep_log_error "******** FATAL ERROR ********************************************"
+ wsrep_log_error "* The certifcate and CA (certificate authority) do not match. *"
+ wsrep_log_error "* It does not appear that the certificate was issued by the CA. *"
+ wsrep_log_error "* Please check your certificate and CA files. *"
+ wsrep_log_error "*****************************************************************"
+ exit 22
+ fi
+}
+
+#
+# Verifies that the certificate matches the private key.
+# Doing this will save us having to wait for a timeout that would
+# otherwise occur.
+#
+# 1st param: path to the certificate.
+# 2nd param: path to the private key.
+#
+verify_cert_matches_key()
+{
+ local cert_path="$1"
+ local key_path="$2"
+
+ # If the diff utility is not installed, then
+ # we will not do this certificate check:
+ if [ -z "$(command -v diff)" ]; then
+ return
+ fi
+
+ # If the openssl utility is not installed, then
+ # we will not do this certificate check:
+ get_openssl
+ if [ -z "$OPENSSL_BINARY" ]; then
+ return
+ fi
+
+ # Generate the public key from the cert and the key.
+ # They should match (otherwise we can't create an SSL connection).
+ if ! diff <("$OPENSSL_BINARY" x509 -in "$cert_path" -pubkey -noout 2>/dev/null) \
+ <("$OPENSSL_BINARY" pkey -in "$key_path" -pubout 2>/dev/null) >/dev/null 2>&1
+ then
+ wsrep_log_error "******************* FATAL ERROR ****************"
+ wsrep_log_error "* The certifcate and private key do not match. *"
+ wsrep_log_error "* Please check your certificate and key files. *"
+ wsrep_log_error "************************************************"
+ exit 22
+ fi
+}
+
+#
# Compares two version strings.
# The first parameter is the version to be checked;
# The second parameter is the minimum version required;
@@ -996,22 +1127,22 @@ check_for_dhparams()
#
check_for_version()
{
- y1=${1#*.}
+ y1="${1#*.}"
[ "$y1" = "$1" ] && y1=""
z1=${y1#*.}
[ "$z1" = "$y1" ] && z1=""
- x1=${1%%.*}
- y1=${y1%%.*}
- z1=${z1%%.*}
+ x1="${1%%.*}"
+ y1="${y1%%.*}"
+ z1="${z1%%.*}"
[ -z "$y1" ] && y1=0
[ -z "$z1" ] && z1=0
- y2=${2#*.}
+ y2="${2#*.}"
[ "$y2" = "$2" ] && y2=""
- z2=${y2#*.}
+ z2="${y2#*.}"
[ "$z2" = "$y2" ] && z2=""
- x2=${2%%.*}
- y2=${y2%%.*}
- z2=${z2%%.*}
+ x2="${2%%.*}"
+ y2="${y2%%.*}"
+ z2="${z2%%.*}"
[ -z "$y2" ] && y2=0
[ -z "$z2" ] && z2=0
[ $x1 -lt $x2 ] && return 1
@@ -1021,3 +1152,127 @@ check_for_version()
[ $z1 -lt $z2 ] && return 1
return 0
}
+
+trim_string()
+{
+ if [ -n "$BASH_VERSION" ]; then
+ local pattern="[![:space:]${2:-}]"
+ local x="${1#*$pattern}"
+ local z=${#1}
+ x=${#x}
+ if [ $x -ne $z ]; then
+ local y="${1%$pattern*}"
+ y=${#y}
+ x=$(( z-x-1 ))
+ y=$(( y-x+1 ))
+ printf '%s' "${1:$x:$y}"
+ else
+ printf ''
+ fi
+ else
+ local pattern="[[:space:]${2:-}]"
+ echo "$1" | sed -E "s/^$pattern+|$pattern+\$//g"
+ fi
+}
+
+#
+# Check whether process is still running.
+# The first parameter contains the name of the PID file.
+# The second parameter is the flag of the need to delete
+# the PID file.
+# If the second parameter is not zero and not empty,
+# then if the process terminates, the corresponding
+# PID file will be deleted.
+# This function also sets the CHECK_PID variable to zero
+# if the process has already exited, or writes the PID
+# of the process there if it is still running.
+#
+check_pid()
+{
+ local pid_file="$1"
+ local remove=${2:-0}
+ if [ -r "$pid_file" ]; then
+ local pid=$(cat "$pid_file" 2>/dev/null)
+ if [ -n "$pid" ]; then
+ if [ $pid -ne 0 ]; then
+ if ps -p "$pid" >/dev/null 2>&1; then
+ CHECK_PID=$pid
+ return 0
+ fi
+ fi
+ fi
+ if [ $remove -eq 1 ]; then
+ rm -f "$pid_file"
+ fi
+ fi
+ CHECK_PID=0
+ return 1
+}
+
+#
+# Checking that the process with the specified PID is still
+# running and killing it in this case by sending SIGTERM
+# (using the "kill" operation).
+# The first parameter contains PID of the process.
+# The second and third parameters (both optional) are the names
+# of the PID and the configuration files, which should be removed
+# after the process ends.
+# If the first parameter (PID of the process) is zero, then
+# the function immediately deletes the PID and the configuration
+# files (if specified), without any additional checks.
+#
+cleanup_pid()
+{
+ local pid="$1"
+ local pid_file="${2:-}"
+ local config="${3:-}"
+
+ if [ $pid -ne 0 ]; then
+ if ps -p $pid >/dev/null 2>&1; then
+ if kill $pid >/dev/null 2>&1; then
+ sleep 0.5
+ local round=0
+ local force=0
+ while ps -p $pid >/dev/null 2>&1; do
+ sleep 1
+ round=$(( round+1 ))
+ if [ $round -eq 16 ]; then
+ if [ $force -eq 0 ]; then
+ round=8
+ force=1
+ kill -9 $pid >/dev/null 2>&1
+ else
+ return 1;
+ fi
+ fi
+ done
+ elif ps -p $pid >/dev/null 2>&1; then
+ wsrep_log_warning "Unable to kill PID=$pid ($pid_file)"
+ return 1
+ fi
+ fi
+ fi
+
+ [ -n "$pid_file" ] && [ -f "$pid_file" ] && rm -f "$pid_file"
+ [ -n "$config" ] && [ -f "$config" ] && rm -f "$config"
+
+ return 0
+}
+
+nproc=""
+
+get_proc()
+{
+ if [ -z "$nproc" ]; then
+ set +e
+ if [ "$OS" = 'Linux' ]; then
+ nproc=$(grep -c processor /proc/cpuinfo 2>/dev/null)
+ elif [ "$OS" = 'Darwin' -o "$OS" = 'FreeBSD' ]; then
+ nproc=$(sysctl -n hw.ncpu)
+ fi
+ if [ -z "$nproc" ] || [ $nproc -eq 0 ]; then
+ nproc=1
+ fi
+ set -e
+ fi
+}
diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh
index 5618c704dbc..7f97d9e8dea 100644
--- a/scripts/wsrep_sst_mariabackup.sh
+++ b/scripts/wsrep_sst_mariabackup.sh
@@ -29,13 +29,10 @@ eformat=""
ekey=""
ekeyfile=""
encrypt=0
-nproc=1
ecode=0
ssyslog=""
ssystag=""
-MARIABACKUP_PID=""
-SST_PORT=""
-REMOTEIP=""
+BACKUP_PID=""
tcert=""
tpem=""
tkey=""
@@ -55,7 +52,7 @@ ib_home_dir=""
ib_log_dir=""
ib_undo_dir=""
-sfmt="tar"
+sfmt=""
strmcmd=""
tfmt=""
tcmd=""
@@ -79,6 +76,11 @@ compress='none'
compress_chunk=""
compress_threads=""
+backup_threads=""
+
+encrypt_threads=""
+encrypt_chunk=""
+
readonly SECRET_TAG="secret"
# Required for backup locks
@@ -92,12 +94,11 @@ fi
pcmd="pv $pvopts"
declare -a RC
-MARIABACKUP_BIN="$(command -v mariabackup)"
-if [ ! -x "$MARIABACKUP_BIN" ]; then
- wsrep_log_error 'mariabackup binary not found in $PATH'
+BACKUP_BIN="$(command -v mariabackup)"
+if [ ! -x "$BACKUP_BIN" ]; then
+ wsrep_log_error 'mariabackup binary not found in path'
exit 42
fi
-MBSTREAM_BIN=mbstream
DATA="$WSREP_SST_OPT_DATA"
INFO_FILE="xtrabackup_galera_info"
@@ -111,7 +112,8 @@ INNOBACKUPLOG="$DATA/mariabackup.backup.log"
# Setting the path for ss and ip
export PATH="/usr/sbin:/sbin:$PATH"
-timeit(){
+timeit()
+{
local stage="$1"
shift
local cmd="$@"
@@ -201,6 +203,12 @@ get_keys()
else
ecmd="xbcrypt --encrypt-algo='$ealgo' --encrypt-key='$ekey'"
fi
+ if [ -n "$encrypt_threads" ]; then
+ ecmd="$ecmd --encrypt-threads=$encrypt_threads"
+ fi
+ if [ -n "$encrypt_chunk" ]; then
+ ecmd="$ecmd --encrypt-chunk-size=$encrypt_chunk"
+ fi
else
wsrep_log_error "Unknown encryption format='$eformat'"
exit 2
@@ -215,8 +223,6 @@ get_keys()
get_transfer()
{
- TSST_PORT="$SST_PORT"
-
if [ $tfmt = 'nc' ]; then
wsrep_log_info "Using netcat as streamer"
wsrep_check_programs nc
@@ -238,7 +244,7 @@ get_transfer()
wsrep_log_info "Using traditional netcat as streamer"
tcmd="$tcmd -l -p"
fi
- tcmd="$tcmd $TSST_PORT"
+ tcmd="$tcmd $SST_PORT"
else
# Check to see if netcat supports the '-N' flag.
# -N Shutdown the network socket after EOF on stdin
@@ -260,7 +266,7 @@ get_transfer()
wsrep_log_info "Using traditional netcat as streamer"
tcmd="$tcmd -q0"
fi
- tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT"
+ tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $SST_PORT"
fi
else
tfmt='socat'
@@ -268,25 +274,68 @@ get_transfer()
wsrep_log_info "Using socat as streamer"
wsrep_check_programs socat
- 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
+ if [ -n "$sockopt" ]; then
+ sockopt=$(trim_string "$sockopt" ',')
+ if [ -n "$sockopt" ]; then
+ sockopt=",$sockopt"
+ fi
fi
- # Determine the socat version
- SOCAT_VERSION=$(socat -V 2>&1 | grep -m1 -oe '[0-9]\.[0-9][\.0-9]*')
- if [ -z "$SOCAT_VERSION" ]; then
- wsrep_log_error "******** FATAL ERROR ******************"
- wsrep_log_error "* Cannot determine the socat version. *"
- wsrep_log_error "***************************************"
+ # Add an option for ipv6 if needed:
+ if [ $WSREP_SST_OPT_HOST_IPv6 -eq 1 ]; then
+ # If sockopt contains 'pf=ip6' somewhere in the middle,
+ # this will not interfere with socat, but exclude the trivial
+ # cases when sockopt contains 'pf=ip6' as prefix or suffix:
+ if [ "$sockopt" = "${sockopt#,pf=ip6}" -a \
+ "$sockopt" = "${sockopt%,pf=ip6}" ]
+ then
+ sockopt=",pf=ip6$sockopt"
+ fi
+ fi
+
+ if [ $encrypt -lt 2 ]; then
+ if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
+ tcmd="socat -u TCP-LISTEN:$SST_PORT,reuseaddr$sockopt stdio"
+ else
+ tcmd="socat -u stdio TCP:$REMOTEIP:$SST_PORT$sockopt"
+ fi
+ return
+ fi
+
+ if ! socat -V | grep -q -F 'WITH_OPENSSL 1'; then
+ wsrep_log_error "******** FATAL ERROR ************************************************ "
+ wsrep_log_error "* Encryption requested, but socat is not OpenSSL enabled (encrypt=$encrypt) *"
+ wsrep_log_error "********************************************************************* "
exit 2
fi
- if ! check_for_version "$SOCAT_VERSION" "1.7.3"; then
- # socat versions < 1.7.3 will have 512-bit dhparams (too small)
- # so create 2048-bit dhparams and send that as a parameter:
- check_for_dhparams
- sockopt=",dhparam='$ssl_dhparams'$sockopt"
+ local action='Decrypting'
+ if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
+ tcmd="socat -u openssl-listen:$SST_PORT,reuseaddr"
+ else
+ tcmd="socat -u stdio openssl-connect:$REMOTEIP:$SST_PORT"
+ action='Encrypting'
+ fi
+
+ if [ "${sockopt#*,dhparam=}" != "$sockopt" ]; then
+ if [ -z "$ssl_dhparams" ]; then
+ # Determine the socat version
+ SOCAT_VERSION=$(socat -V 2>&1 | grep -m1 -oe '[0-9]\.[0-9][\.0-9]*')
+ if [ -z "$SOCAT_VERSION" ]; then
+ wsrep_log_error "******** FATAL ERROR ******************"
+ wsrep_log_error "* Cannot determine the socat version. *"
+ wsrep_log_error "***************************************"
+ exit 2
+ fi
+ if ! check_for_version "$SOCAT_VERSION" '1.7.3'; then
+ # socat versions < 1.7.3 will have 512-bit dhparams (too small)
+ # so create 2048-bit dhparams and send that as a parameter:
+ check_for_dhparams
+ fi
+ fi
+ if [ -n "$ssl_dhparams" ]; then
+ tcmd="$tcmd,dhparam='$ssl_dhparams'"
+ fi
fi
if [ $encrypt -eq 2 ]; then
@@ -295,52 +344,60 @@ get_transfer()
wsrep_log_error "Both PEM and CRT files required"
exit 22
fi
- 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"
- else
- wsrep_log_info "Encrypting with cert=${tpem}, cafile=${tcert}"
- tcmd="socat -u stdio openssl-connect:$REMOTEIP:$TSST_PORT,cert='$tpem',cafile='$tcert'$sockopt"
+ if [ ! -r "$tpem" -o ! -r "$tcert" ]; then
+ wsrep_log_error "Both PEM and CRT files must be readable"
+ exit 22
fi
- elif [ $encrypt -eq 3 ]; then
+ verify_ca_matches_cert "$tcert" "$tpem"
+ tcmd="$tcmd,cert='$tpem',cafile='$tcert'$sockopt"
+ stagemsg="$stagemsg-OpenSSL-Encrypted-2"
+ wsrep_log_info "$action with cert=$tpem, cafile=$tcert"
+ elif [ $encrypt -eq 3 -o $encrypt -eq 4 ]; then
wsrep_log_info "Using openssl based encryption with socat: with key and crt"
if [ -z "$tpem" -o -z "$tkey" ]; then
wsrep_log_error "Both certificate and key files required"
exit 22
fi
+ if [ ! -r "$tpem" -o ! -r "$tkey" ]; then
+ wsrep_log_error "Both certificate and key files must be readable"
+ exit 22
+ fi
+ verify_cert_matches_key "$tpem" "$tkey"
stagemsg="$stagemsg-OpenSSL-Encrypted-3"
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"
- else
- 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"
+ if [ $encrypt -eq 4 ]; then
+ wsrep_log_error "Peer certificate required if encrypt=4"
+ exit 22
fi
+ # no verification
+ tcmd="$tcmd,cert='$tpem',key='$tkey',verify=0$sockopt"
+ wsrep_log_info "$action with cert=$tpem, key=$tkey, verify=0"
else
# 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"
+ if [ ! -r "$tcert" ]; then
+ wsrep_log_error "Certificate file must be readable"
+ exit 22
+ fi
+ verify_ca_matches_cert "$tcert" "$tpem"
+ if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then
+ CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'"
+ elif [ $encrypt -eq 4 ]; then
+ CN_option=",commonname=''"
+ elif is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then
+ CN_option=',commonname=localhost'
else
- 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"
+ CN_option=",commonname='$WSREP_SST_OPT_HOST_UNSECAPED'"
fi
+ tcmd="$tcmd,cert='$tpem',key='$tkey',cafile='$tcert'$CN_option$sockopt"
+ wsrep_log_info "$action with cert=$tpem, key=$tkey, cafile=$tcert"
fi
else
- if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
- tcmd="socat -u TCP-LISTEN:$TSST_PORT,reuseaddr$sockopt stdio"
- else
- tcmd="socat -u stdio TCP:$REMOTEIP:$TSST_PORT$sockopt"
- fi
+ wsrep_log_info "Unknown encryption mode: encrypt=$encrypt"
+ exit 22
+ fi
+
+ if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
+ tcmd="$tcmd stdio"
fi
fi
}
@@ -348,7 +405,7 @@ get_transfer()
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 }')
+ payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c -s | awk 'END { print $1 }')
if [ "$compress" != 'none' ]; then
# QuickLZ has around 50% compression ratio
# When compression/compaction used, the progress is only an approximate.
@@ -412,10 +469,10 @@ read_cnf()
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]
+ 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
fi
if [ 0 -eq $encrypt -a -n "$tpem" -a -n "$tkey" ]
@@ -441,7 +498,7 @@ read_cnf()
sockopt=$(parse_cnf sst sockopt "")
progress=$(parse_cnf sst progress "")
ttime=$(parse_cnf sst time 0)
- cpat='.*galera\.cache$\|.*sst_in_progress$\|.*\.sst$\|.*gvwstate\.dat$\|.*grastate\.dat$\|.*\.err$\|.*\.log$\|.*RPM_UPGRADE_MARKER$\|.*RPM_UPGRADE_HISTORY$'
+ cpat='.*\.pem$\|.*galera\.cache$\|.*sst_in_progress$\|.*\.sst$\|.*gvwstate\.dat$\|.*grastate\.dat$\|.*\.err$\|.*\.log$\|.*RPM_UPGRADE_MARKER$\|.*RPM_UPGRADE_HISTORY$'
[ "$OS" = 'FreeBSD' ] && cpat=$(echo "$cpat" | sed 's/\\|/|/g')
cpat=$(parse_cnf sst cpat "$cpat")
scomp=$(parse_cnf sst compressor "")
@@ -476,34 +533,38 @@ read_cnf()
compress_threads=$(parse_cnf "$encgroups" 'compress-threads')
fi
fi
+
+ backup_threads=$(parse_cnf "$encgroups" 'backup-threads')
+
+ if [ "$eformat" = 'xbcrypt' ]; then
+ encrypt_threads=$(parse_cnf "$encgroups" 'encrypt-threads')
+ encrypt_chunk=$(parse_cnf "$encgroups" 'encrypt-chunk-size')
+ fi
}
get_stream()
{
if [ "$sfmt" = 'mbstream' -o "$sfmt" = 'xbstream' ]; then
- wsrep_log_info "Streaming with ${sfmt}"
+ sfmt='mbstream'
+ STREAM_BIN="$(command -v mbstream)"
+ if [ -z "$STREAM_BIN" ]; then
+ wsrep_log_error "Streaming with $sfmt, but $sfmt not found in path"
+ exit 42
+ fi
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
- strmcmd="$MBSTREAM_BIN -x"
+ strmcmd="'$STREAM_BIN' -x"
else
- strmcmd="$MBSTREAM_BIN -c '$INFO_FILE'"
+ strmcmd="'$STREAM_BIN' -c '$INFO_FILE'"
fi
else
- sfmt="tar"
- wsrep_log_info "Streaming with tar"
- if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]]; then
- strmcmd="tar xfi -"
+ sfmt='tar'
+ if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
+ strmcmd='tar xfi -'
else
strmcmd="tar cf - '$INFO_FILE'"
fi
fi
-}
-
-get_proc()
-{
- set +e
- nproc=$(grep -c processor /proc/cpuinfo)
- [ -z $nproc -o $nproc -eq 0 ] && nproc=1
- set -e
+ wsrep_log_info "Streaming with $sfmt"
}
sig_joiner_cleanup()
@@ -512,48 +573,7 @@ sig_joiner_cleanup()
[ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
}
-cleanup_joiner()
-{
- # Since this is invoked just after exit NNN
- local estatus=$?
- if [ $estatus -ne 0 ]; then
- wsrep_log_error "Cleanup after exit with status:$estatus"
- elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
- wsrep_log_info "Removing the sst_in_progress file"
- wsrep_cleanup_progress_file
- fi
- if [ -n "$progress" -a -p "$progress" ]; then
- wsrep_log_info "Cleaning up fifo file $progress"
- rm "$progress"
- fi
-
- if [ -n "$STATDIR" ]; then
- [ -d "$STATDIR" ] && rm -rf "$STATDIR"
- fi
-
- # 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
- kill -KILL -$$ || true
- fi
- fi
-
- exit $estatus
-}
-
-check_pid()
-{
- local pid_file="$1"
- [ -r "$pid_file" ] && ps -p $(cat "$pid_file") 2>&1 >/dev/null
-}
-
-cleanup_donor()
+cleanup_at_exit()
{
# Since this is invoked just after exit NNN
local estatus=$?
@@ -561,16 +581,19 @@ cleanup_donor()
wsrep_log_error "Cleanup after exit with status:$estatus"
fi
- if [ -n "$MARIABACKUP_PID" ]; then
- if check_pid $MARIABACKUP_PID
- then
- wsrep_log_error "mariabackup process is still running. Killing..."
- kill_mariabackup
+ if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
+ wsrep_log_info "Removing the sst_in_progress file"
+ wsrep_cleanup_progress_file
+ else
+ if [ -n "$BACKUP_PID" ]; then
+ if check_pid "$BACKUP_PID" 1; then
+ wsrep_log_error "mariabackup process is still running. Killing..."
+ cleanup_pid $CHECK_PID "$BACKUP_PID"
+ fi
fi
+ [ -f "$DATA/$IST_FILE" ] && rm -f "$DATA/$IST_FILE"
fi
- [ -f "$DATA/$IST_FILE" ] && rm -f "$DATA/$IST_FILE"
-
if [ -n "$progress" -a -p "$progress" ]; then
wsrep_log_info "Cleaning up fifo file $progress"
rm -f "$progress" || true
@@ -578,8 +601,14 @@ cleanup_donor()
wsrep_log_info "Cleaning up temporary directories"
- [ -n "$xtmpdir" -a -d "$xtmpdir" ] && rm -rf "$xtmpdir" || true
- [ -n "$itmpdir" -a -d "$itmpdir" ] && rm -rf "$itmpdir" || true
+ if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
+ if [ -n "$STATDIR" ]; then
+ [ -d "$STATDIR" ] && rm -rf "$STATDIR"
+ fi
+ else
+ [ -n "$xtmpdir" -a -d "$xtmpdir" ] && rm -rf "$xtmpdir" || true
+ [ -n "$itmpdir" -a -d "$itmpdir" ] && rm -rf "$itmpdir" || true
+ fi
# Final cleanup
pgid=$(ps -o pgid= $$ | grep -o '[0-9]*')
@@ -590,21 +619,13 @@ cleanup_donor()
# This means a signal was delivered to the process.
# So, more cleanup.
if [ $estatus -ge 128 ]; then
- kill -KILL -$$ || true
+ kill -KILL -- -$$ || true
fi
fi
exit $estatus
}
-kill_mariabackup()
-{
- local PID=$(cat "$MARIABACKUP_PID")
- [ -n "$PID" -a "0" != "$PID" ] && kill $PID && (kill $PID && kill -9 $PID) || :
- wsrep_log_info "Removing mariabackup pid file ($MARIABACKUP_PID)"
- rm -f "$MARIABACKUP_PID" || true
-}
-
setup_ports()
{
SST_PORT="$WSREP_SST_OPT_PORT"
@@ -615,51 +636,17 @@ setup_ports()
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)
+#
+# Waits ~30 seconds for socat or nc to open the port and
+# then reports ready, regardless of timeout.
+#
wait_for_listen()
{
local PORT="$1"
local ADDR="$2"
local MODULE="$3"
-
- for i in {1..50}
- do
- if check_port "$PORT" 'socat|nc'
- then
+ for i in {1..150}; do
+ if check_port "" "$PORT" 'socat|nc'; then
break
fi
sleep 0.2
@@ -675,8 +662,8 @@ check_extra()
if [ "$thread_handling" = 'pool-of-threads' ]; then
local eport=$(parse_cnf '--mysqld' 'extra-port')
if [ -n "$eport" ]; then
- # mariabackup 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="$INNOEXTRA --host=127.0.0.1 --port=$eport"
use_socket=0
@@ -792,30 +779,29 @@ 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 2>&1; then
wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly."
+ kill -- -"$WSREP_SST_OPT_PARENT"
exit 32
fi
- if ! ps -p "$sst_stream_pid" &>/dev/null; then
+ if ! ps -p "$sst_stream_pid" >/dev/null 2>&1; then
break
fi
sleep 0.1
done
}
-wsrep_check_programs "$MARIABACKUP_BIN"
-
[ -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}"
+ wsrep_log_error "Invalid role '$WSREP_SST_OPT_ROLE'"
exit 22
fi
read_cnf
setup_ports
-if "$MARIABACKUP_BIN" --help 2>/dev/null | grep -qw -- '--version-check'; then
+if "$BACKUP_BIN" --help 2>/dev/null | grep -qw -- '--version-check'; then
disver='--no-version-check'
fi
@@ -838,7 +824,6 @@ INNODB_DATA_HOME_DIR=$(pwd -P)
cd "$OLD_PWD"
if [ $ssyslog -eq 1 ]; then
-
if [ -n "$(command -v logger)" ]; then
wsrep_log_info "Logging all stderr of SST/mariabackup to syslog"
@@ -856,70 +841,65 @@ if [ $ssyslog -eq 1 ]; then
else
wsrep_log_error "logger not in path: $PATH. Ignoring"
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 ]
+ then
+ ARCHIVETIMESTAMP=$(date "+%Y.%m.%d-%H.%M.%S.%N")
-if [ $sstlogarchive -eq 1 ]
-then
- ARCHIVETIMESTAMP=$(date "+%Y.%m.%d-%H.%M.%S.%N")
-
- if [ -n "$sstlogarchivedir" ]; then
- if [ ! -d "$sstlogarchivedir" ]; then
- mkdir -p "$sstlogarchivedir"
+ if [ -n "$sstlogarchivedir" ]; then
+ if [ ! -d "$sstlogarchivedir" ]; then
+ mkdir -p "$sstlogarchivedir"
+ fi
fi
- fi
- if [ -e "$INNOAPPLYLOG" ]
- then
- if [ -n "$sstlogarchivedir" ]
+ if [ -e "$INNOAPPLYLOG" ]
then
- newfile=$(basename "$INNOAPPLYLOG")
- newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
- else
- newfile="$INNOAPPLYLOG.$ARCHIVETIMESTAMP"
+ if [ -n "$sstlogarchivedir" ]
+ then
+ newfile=$(basename "$INNOAPPLYLOG")
+ newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
+ else
+ newfile="$INNOAPPLYLOG.$ARCHIVETIMESTAMP"
+ fi
+ wsrep_log_info "Moving '$INNOAPPLYLOG' to '$newfile'"
+ mv "$INNOAPPLYLOG" "$newfile"
+ gzip "$newfile"
fi
- wsrep_log_info "Moving '$INNOAPPLYLOG' to '$newfile'"
- mv "$INNOAPPLYLOG" "$newfile"
- gzip "$newfile"
- fi
- if [ -e "$INNOMOVELOG" ]
- then
- if [ -n "$sstlogarchivedir" ]
+ if [ -e "$INNOMOVELOG" ]
then
- newfile=$(basename "$INNOMOVELOG")
- newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
- else
- newfile="$INNOMOVELOG.$ARCHIVETIMESTAMP"
+ if [ -n "$sstlogarchivedir" ]
+ then
+ newfile=$(basename "$INNOMOVELOG")
+ newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
+ else
+ newfile="$INNOMOVELOG.$ARCHIVETIMESTAMP"
+ fi
+ wsrep_log_info "Moving '$INNOMOVELOG' to '$newfile'"
+ mv "$INNOMOVELOG" "$newfile"
+ gzip "$newfile"
fi
- wsrep_log_info "Moving '$INNOMOVELOG' to '$newfile'"
- mv "$INNOMOVELOG" "$newfile"
- gzip "$newfile"
- fi
- if [ -e "$INNOBACKUPLOG" ]
- then
- if [ -n "$sstlogarchivedir" ]
+ if [ -e "$INNOBACKUPLOG" ]
then
- newfile=$(basename "$INNOBACKUPLOG")
- newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
- else
- newfile="$INNOBACKUPLOG.$ARCHIVETIMESTAMP"
+ if [ -n "$sstlogarchivedir" ]
+ then
+ newfile=$(basename "$INNOBACKUPLOG")
+ newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
+ else
+ newfile="$INNOBACKUPLOG.$ARCHIVETIMESTAMP"
+ fi
+ wsrep_log_info "Moving '$INNOBACKUPLOG' to '$newfile'"
+ mv "$INNOBACKUPLOG" "$newfile"
+ gzip "$newfile"
fi
- wsrep_log_info "Moving '$INNOBACKUPLOG' to '$newfile'"
- mv "$INNOBACKUPLOG" "$newfile"
- gzip "$newfile"
fi
-fi
-
- INNOAPPLY="&> '$INNOAPPLYLOG'"
- INNOMOVE="&> '$INNOMOVELOG'"
+ INNOAPPLY="> '$INNOAPPLYLOG' 2>&1"
+ INNOMOVE="> '$INNOMOVELOG' 2>&1"
INNOBACKUP="2> '$INNOBACKUPLOG'"
-
fi
setup_commands()
@@ -928,9 +908,9 @@ setup_commands()
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"
+ INNOAPPLY="$BACKUP_BIN --prepare $disver $iapts $INNOEXTRA --target-dir='$DATA' --datadir='$DATA' $mysqld_args $INNOAPPLY"
+ INNOMOVE="$BACKUP_BIN $WSREP_SST_OPT_CONF --move-back $disver $impts --force-non-empty-directories --target-dir='$DATA' --datadir='${TDATA:-$DATA}' $INNOMOVE"
+ INNOBACKUP="$BACKUP_BIN $WSREP_SST_OPT_CONF --backup $disver $iopts $tmpopts $INNOEXTRA --galera-info --stream=$sfmt --target-dir='$itmpdir' --datadir='$DATA' $mysqld_args $INNOBACKUP"
}
get_stream
@@ -938,7 +918,7 @@ get_transfer
if [ "$WSREP_SST_OPT_ROLE" = 'donor' ]
then
- trap cleanup_donor EXIT
+ trap cleanup_at_exit EXIT
if [ $WSREP_SST_OPT_BYPASS -eq 0 ]
then
@@ -951,12 +931,15 @@ then
tmpdir=$(parse_cnf "$encgroups" 'tmpdir')
if [ -z "$tmpdir" ]; then
xtmpdir="$(mktemp -d)"
- tmpopts="--tmpdir='$xtmpdir'"
- wsrep_log_info "Using $xtmpdir as mariabackup temporary directory"
+ else
+ xtmpdir=$(mktemp '-d' "--tmpdir=$tmpdir")
fi
+ wsrep_log_info "Using '$xtmpdir' as mariabackup temporary directory"
+ tmpopts="--tmpdir='$xtmpdir'"
+
itmpdir="$(mktemp -d)"
- wsrep_log_info "Using $itmpdir as mariabackup temporary directory"
+ wsrep_log_info "Using '$itmpdir' as mariabackup working directory"
usrst=0
if [ -n "$WSREP_SST_OPT_USER" ]; then
@@ -997,9 +980,9 @@ then
send_donor "$DATA" "$stagemsg-gtid"
+ # Restore the transport commmand to its original state
tcmd="$ttcmd"
- # Restore the transport commmand to its original state
if [ -n "$progress" ]; then
get_footprint
tcmd="$pcmd | $tcmd"
@@ -1011,7 +994,7 @@ then
wsrep_log_info "Sleeping before data transfer for SST"
sleep 10
- wsrep_log_info "Streaming the backup to joiner at ${REMOTEIP}:${SST_PORT}"
+ 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
@@ -1023,33 +1006,37 @@ then
tcmd="$ecmd | $tcmd"
fi
- iopts="$iopts --databases-exclude='lost+found'"
+ iopts="--databases-exclude='lost+found' $iopts"
if [ ${FORCE_FTWRL:-0} -eq 1 ]; then
- wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL"
- iopts="$iopts --no-backup-locks"
+ wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL"
+ iopts="--no-backup-locks $iopts"
fi
# if compression is enabled for backup files, then add the
# appropriate options to the mariabackup command line:
if [ "$compress" != 'none' ]; then
- iopts="$iopts --compress${compress:+=$compress}"
+ iopts="--compress${compress:+=$compress} $iopts"
if [ -n "$compress_threads" ]; then
- iopts="$iopts --compress-threads=$compress_threads"
+ iopts="--compress-threads=$compress_threads $iopts"
fi
if [ -n "$compress_chunk" ]; then
- iopts="$iopts --compress-chunk-size=$compress_chunk"
+ iopts="--compress-chunk-size=$compress_chunk $iopts"
fi
fi
+ if [ -n "$backup_threads" ]; then
+ iopts="--parallel=$backup_threads $iopts"
+ fi
+
setup_commands
set +e
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"
+ wsrep_log_error "mariabackup 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]}"
@@ -1057,7 +1044,7 @@ then
fi
# mariabackup implicitly writes PID to fixed location in $xtmpdir
- MARIABACKUP_PID="$xtmpdir/xtrabackup_pid"
+ BACKUP_PID="$xtmpdir/xtrabackup_pid"
else # BYPASS FOR IST
@@ -1109,6 +1096,10 @@ then
ib_undo_dir="$INNODB_UNDO_DIR"
+ if [ -n "$backup_threads" ]; then
+ impts="--parallel=$backup_threads $impts"
+ fi
+
stagemsg='Joiner-Recv'
sencrypted=1
@@ -1148,7 +1139,7 @@ then
fi
trap sig_joiner_cleanup HUP PIPE INT TERM
- trap cleanup_joiner EXIT
+ trap cleanup_at_exit EXIT
if [ -n "$progress" ]; then
adjust_progress
@@ -1171,7 +1162,7 @@ then
recv_joiner "$STATDIR" "$stagemsg-gtid" $stimeout 1 1
- if ! ps -p "$WSREP_SST_OPT_PARENT" &>/dev/null
+ if ! ps -p "$WSREP_SST_OPT_PARENT" >/dev/null 2>&1
then
wsrep_log_error "Parent mysqld process (PID: $WSREP_SST_OPT_PARENT) terminated unexpectedly."
exit 32
@@ -1181,7 +1172,7 @@ then
then
if [ -d "$DATA/.sst" ]; then
- wsrep_log_info "WARNING: Stale temporary SST directory: ${DATA}/.sst from previous state transfer. Removing"
+ wsrep_log_info "WARNING: Stale temporary SST directory: '$DATA/.sst' from previous state transfer. Removing"
rm -rf "$DATA/.sst"
fi
mkdir -p "$DATA/.sst"
@@ -1291,37 +1282,37 @@ then
fi
- wsrep_log_info "Preparing the backup at ${DATA}"
+ wsrep_log_info "Preparing the backup at $DATA"
setup_commands
timeit "mariabackup prepare stage" "$INNOAPPLY"
if [ $? -ne 0 ]; then
- wsrep_log_error "${MARIABACKUP_BIN} apply finished with errors. Check syslog or ${INNOAPPLYLOG} for details"
+ wsrep_log_error "mariabackup apply finished with errors. Check syslog or '$INNOAPPLYLOG' for details"
exit 22
fi
MAGIC_FILE="$TDATA/$INFO_FILE"
- wsrep_log_info "Moving the backup to ${TDATA}"
- timeit "mariabackup move stage" "$INNOMOVE"
+ wsrep_log_info "Moving the backup to $TDATA"
+ timeit "mariabackup move stage" "$INNOMOVE"
if [ $? -eq 0 ]; then
- wsrep_log_info "Move successful, removing ${DATA}"
+ wsrep_log_info "Move successful, removing $DATA"
rm -rf "$DATA"
DATA="$TDATA"
else
- wsrep_log_error "Move failed, keeping ${DATA} for further diagnosis"
- wsrep_log_error "Check syslog or ${INNOMOVELOG} for details"
+ wsrep_log_error "Move failed, keeping '$DATA' for further diagnosis"
+ wsrep_log_error "Check syslog or '$INNOMOVELOG' for details"
exit 22
fi
else
- wsrep_log_info "${IST_FILE} received from donor: Running IST"
+ wsrep_log_info "'$IST_FILE' received from donor: Running IST"
fi
if [ ! -r "$MAGIC_FILE" ]; then
- wsrep_log_error "SST magic file ${MAGIC_FILE} not found/readable"
+ wsrep_log_error "SST magic file '$MAGIC_FILE' not found/readable"
exit 2
fi
diff --git a/scripts/wsrep_sst_mysqldump.sh b/scripts/wsrep_sst_mysqldump.sh
index 4aa3f8e63d8..798bee1ac10 100644
--- a/scripts/wsrep_sst_mysqldump.sh
+++ b/scripts/wsrep_sst_mysqldump.sh
@@ -103,7 +103,7 @@ then
DROP PREPARE stmt;"
fi
-MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF "\
+MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF_UNQUOTED "\
"$AUTH -h$WSREP_SST_OPT_HOST_UNESCAPED "\
"-P$WSREP_SST_OPT_PORT --disable-reconnect --connect_timeout=10"
@@ -140,7 +140,7 @@ then
fi
# NOTE: we don't use --routines here because we're dumping mysql.proc table
-MYSQLDUMP="$MYSQLDUMP $WSREP_SST_OPT_CONF $AUTH -S$WSREP_SST_OPT_SOCKET \
+MYSQLDUMP="$MYSQLDUMP $WSREP_SST_OPT_CONF_UNQUOTED $AUTH -S$WSREP_SST_OPT_SOCKET \
--add-drop-database --add-drop-table --skip-add-locks --create-options \
--disable-keys --extended-insert --skip-lock-tables --quick --set-charset \
--skip-comments --flush-privileges --all-databases --events"
diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh
index 92f77eec331..19a4d19fded 100644
--- a/scripts/wsrep_sst_rsync.sh
+++ b/scripts/wsrep_sst_rsync.sh
@@ -1,7 +1,7 @@
#!/bin/bash -ue
-# Copyright (C) 2010-2014 Codership Oy
# Copyright (C) 2017-2021 MariaDB
+# Copyright (C) 2010-2014 Codership Oy
#
# 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,9 +19,8 @@
# This is a reference script for rsync-based state snapshot tansfer
-RSYNC_PID= # rsync pid file
-RSYNC_CONF= # rsync configuration file
-RSYNC_REAL_PID= # rsync process id
+RSYNC_REAL_PID=0 # rsync process id
+STUNNEL_REAL_PID=0 # stunnel process id
OS="$(uname)"
[ "$OS" = 'Darwin' ] && export -n LD_LIBRARY_PATH
@@ -36,95 +35,95 @@ wsrep_check_programs rsync
cleanup_joiner()
{
- wsrep_log_info "Joiner cleanup. rsync PID: $RSYNC_REAL_PID"
- [ "0" != "$RSYNC_REAL_PID" ] && \
- kill $RSYNC_REAL_PID && \
- sleep 0.5 && \
- kill -9 $RSYNC_REAL_PID >/dev/null 2>&1 || :
- [ -f "$RSYNC_CONF" ] && rm -f "$RSYNC_CONF"
- [ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF"
- [ -f "$STUNNEL_PID" ] && rm -f "$STUNNEL_PID"
- [ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
- [ -f "$RSYNC_PID" ] && rm -f "$RSYNC_PID"
+ local failure=0
+
+ wsrep_log_info "Joiner cleanup: rsync PID=$RSYNC_REAL_PID, stunnel PID=$STUNNEL_REAL_PID"
+
+ if [ -n "$STUNNEL" ]; then
+ if cleanup_pid $STUNNEL_REAL_PID "$STUNNEL_PID" "$STUNNEL_CONF"; then
+ if [ $RSYNC_REAL_PID -eq 0 ]; then
+ if [ -r "$RSYNC_PID" ]; then
+ RSYNC_REAL_PID=$(cat "$RSYNC_PID" 2>/dev/null)
+ if [ -z "$RSYNC_REAL_PID" ]; then
+ RSYNC_REAL_PID=0
+ fi
+ fi
+ fi
+ else
+ wsrep_log_warning "stunnel cleanup failed."
+ failure=1
+ fi
+ fi
+
+ if [ $failure -eq 0 ]; then
+ if cleanup_pid $RSYNC_REAL_PID "$RSYNC_PID" "$RSYNC_CONF"; then
+ [ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
+ else
+ wsrep_log_warning "rsync cleanup failed."
+ fi
+ fi
+
wsrep_log_info "Joiner cleanup done."
+
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
wsrep_cleanup_progress_file
fi
}
-# Check whether rsync process is still running.
-check_pid()
-{
- local pid_file="$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"
+ local pid=$2
+ local addr="$3"
+ local 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 utils='rsync|stunnel'
- 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 ! check_port "$pid" "$port" "$utils"; then
+ local port_info
+ local busy=0
- 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:]]")
+ port_info=$(lsof -Pnl -i ":$port" 2>/dev/null | \
+ grep -F '(LISTEN)')
+ echo "$port_info" | \
+ grep -q -E "[[:space:]](\\*|\\[?::\\]?):$port[[:space:]]" && busy=1
else
- if [ $sockstat_available -eq 0 ]; then
- port_info=$(echo "$port_info" | grep -q -F 'users:(')
+ local filter='([^[:space:]]+[[:space:]]+){4}[^[:space:]]+'
+ if [ $sockstat_available -eq 1 ]; then
+ port_info=$(sockstat -p "$port" 2>/dev/null | \
+ grep -E '[[:space:]]LISTEN' | grep -o -E "$filter")
+ else
+ port_info=$(ss -nlpH "( sport = :$port )" 2>/dev/null | \
+ grep -F 'users:(' | grep -o -E "$filter")
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\$")
+ echo "$port_info" | \
+ grep -q -E "[[:space:]](\\*|\\[?::\\]?):$port\$" && busy=1
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")
+
+ if [ $busy -eq 0 ]; then
+ if echo "$port_info" | grep -qw -F "[$addr]:$port" || \
+ echo "$port_info" | grep -qw -F -- "$addr:$port"
+ then
+ busy=1
+ fi
+ fi
+
+ if [ $busy -eq 0 ]; then
+ return 1
fi
- if [ -n "$is_listening_all" -o -n "$is_listening_addr" ]; then
- wsrep_log_error "rsync or stunnel daemon port '$rsync_port' " \
+
+ if ! check_port "$pid" "$port" "$utils"; then
+ wsrep_log_error "rsync or stunnel daemon port '$port' " \
"has been taken by another program"
exit 16 # EBUSY
fi
- return 1
fi
- check_pid "$pid_file" && [ $(cat "$pid_file") -eq $rsync_pid ]
+ check_pid "$pid_file" && [ $CHECK_PID -eq $pid ]
}
STUNNEL_CONF="$WSREP_SST_OPT_DATA/stunnel.conf"
-
STUNNEL_PID="$WSREP_SST_OPT_DATA/stunnel.pid"
MAGIC_FILE="$WSREP_SST_OPT_DATA/rsync_sst_complete"
@@ -201,6 +200,8 @@ FILTER="-f '- /lost+found'
-f '- /.zfs'
-f '- /.fseventsd'
-f '- /.Trashes'
+ -f '- /.pid'
+ -f '- /.conf'
-f '+ /wsrep_sst_binlog.tar'
-f '- $INNODB_DATA_HOME_DIR/ib_lru_dump'
-f '- $INNODB_DATA_HOME_DIR/ibdata*'
@@ -250,19 +251,31 @@ else
CAFILE_OPT=""
fi
+VERIFY_OPT=""
+CHECK_OPT=""
+CHECK_OPT_LOCAL=""
if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ]
then
case "$SSLMODE" in
'VERIFY_IDENTITY')
VERIFY_OPT='verifyPeer = yes'
- CHECK_OPT=""
;;
'VERIFY_CA')
VERIFY_OPT='verifyChain = yes'
- if is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then
- CHECK_OPT='checkHost = localhost'
+ if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then
+ CHECK_OPT="checkHost = $WSREP_SST_OPT_REMOTE_USER"
else
- CHECK_OPT='checkHost = $WSREP_SST_OPT_HOST_UNESCAPED'
+ # check if the address is an ip-address (v4 or v6):
+ if echo "$WSREP_SST_OPT_HOST_UNESCAPED" | \
+ grep -q -E '^([0-9]+(\.[0-9]+){3}|[0-9a-fA-F]*(\:[0-9a-fA-F]*)+)$'
+ then
+ CHECK_OPT="checkIP = $WSREP_SST_OPT_HOST_UNESCAPED"
+ else
+ CHECK_OPT="checkHost = $WSREP_SST_OPT_HOST"
+ fi
+ if is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then
+ CHECK_OPT_LOCAL="checkHost = localhost"
+ fi
fi
;;
*)
@@ -273,9 +286,6 @@ then
wsrep_log_error "Can't have ssl-mode='$SSLMODE' without CA file"
exit 22 # EINVAL
fi
-else
- VERIFY_OPT=""
- CHECK_OPT=""
fi
STUNNEL=""
@@ -294,10 +304,10 @@ then
[ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
[ -f "$BINLOG_TAR_FILE" ] && rm -f "$BINLOG_TAR_FILE"
+ [ -f "$STUNNEL_PID" ] && rm -f "$STUNNEL_PID"
if [ -n "$STUNNEL" ]
then
- [ -f "$STUNNEL_PID" ] && rm -f "$STUNNEL_PID"
cat << EOF > "$STUNNEL_CONF"
key = $SSTKEY
cert = $SSTCERT
@@ -310,7 +320,10 @@ connect = $WSREP_SST_OPT_HOST_UNESCAPED:$WSREP_SST_OPT_PORT
TIMEOUTclose = 0
${VERIFY_OPT}
${CHECK_OPT}
+${CHECK_OPT_LOCAL}
EOF
+ else
+ [ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF"
fi
if [ $WSREP_SST_OPT_BYPASS -eq 0 ]
@@ -319,13 +332,8 @@ EOF
FLUSHED="$WSREP_SST_OPT_DATA/tables_flushed"
ERROR="$WSREP_SST_OPT_DATA/sst_error"
- rm -rf "$FLUSHED"
- rm -rf "$ERROR"
-
- # Use deltaxfer only for WAN
- inv=$(basename "$0")
- [ "$inv" = "wsrep_sst_rsync_wan" ] && WHOLE_FILE_OPT="" \
- || WHOLE_FILE_OPT="--whole-file"
+ [ -f "$FLUSHED" ] && rm -f "$FLUSHED"
+ [ -f "$ERROR" ] && rm -f "$ERROR"
echo "flush tables"
@@ -340,15 +348,14 @@ EOF
if [ -f "$ERROR" ]
then
# Flush tables operation failed.
- rm -rf "$ERROR"
+ rm -f "$ERROR"
exit 255
fi
-
sleep 0.2
done
STATE=$(cat "$FLUSHED")
- rm -rf "$FLUSHED"
+ rm -f "$FLUSHED"
sync
@@ -375,6 +382,13 @@ EOF
cd "$OLD_PWD"
fi
+ # Use deltaxfer only for WAN
+ inv=$(basename "$0")
+ WHOLE_FILE_OPT=""
+ if [ "${inv%wsrep_sst_rsync_wan*}" != "$inv" ]; then
+ WHOLE_FILE_OPT="--whole-file"
+ fi
+
# first, the normal directories, so that we can detect incompatible protocol
RC=0
eval rsync ${STUNNEL:+"'--rsh=$STUNNEL'"} \
@@ -426,16 +440,18 @@ EOF
fi
# then, we parallelize the transfer of database directories,
- # use . so that path concatenation works:
+ # 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)
+ backup_threads=$(parse_cnf "--mysqld|sst" 'backup-threads')
+ if [ -z "$backup_threads" ]; then
+ get_proc
+ backup_threads=$nproc
+ fi
find . -maxdepth 1 -mindepth 1 -type d -not -name 'lost+found' \
- -not -name '.zfs' -print0 | xargs -I{} -0 -P $count \
+ -not -name '.zfs' -print0 | xargs -I{} -0 -P $backup_threads \
rsync ${STUNNEL:+--rsh="$STUNNEL"} \
--owner --group --perms --links --specials \
--ignore-times --inplace --recursive --delete --quiet \
@@ -474,35 +490,52 @@ EOF
echo "done $STATE"
+ if [ -n "$STUNNEL" ]; then
+ [ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF"
+ [ -f "$STUNNEL_PID" ] && rm -f "$STUNNEL_PID"
+ fi
+
elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]
then
check_sockets_utils
- touch "$SST_PROGRESS_FILE"
- MYSQLD_PID="$WSREP_SST_OPT_PARENT"
+ # give some time for lingering stunnel from previous SST to complete
+ check_round=0
+ while check_pid "$STUNNEL_PID" 1
+ do
+ wsrep_log_info "lingering stunnel daemon found at startup, waiting for it to exit"
+ check_round=$(( check_round + 1 ))
+ if [ $check_round -eq 10 ]; then
+ wsrep_log_error "stunnel daemon already running."
+ exit 114 # EALREADY
+ fi
+ sleep 1
+ done
MODULE="rsync_sst"
-
RSYNC_PID="$WSREP_SST_OPT_DATA/$MODULE.pid"
+ RSYNC_CONF="$WSREP_SST_OPT_DATA/$MODULE.conf"
+
# 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" 1
do
wsrep_log_info "lingering rsync daemon found at startup, waiting for it to exit"
check_round=$(( check_round + 1 ))
+ if [ $check_round -eq 10 ]; then
+ wsrep_log_error "rsync daemon already running."
+ exit 114 # EALREADY
+ fi
sleep 1
done
- if check_pid "$RSYNC_PID"
- then
- wsrep_log_error "rsync daemon already running."
- exit 114 # EALREADY
- fi
-
- [ -f "$RSYNC_PID" ] && rm -f "$RSYNC_PID"
[ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
[ -f "$BINLOG_TAR_FILE" ] && rm -f "$BINLOG_TAR_FILE"
+ if [ -z "$STUNNEL" ]; then
+ [ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF"
+ fi
+
ADDR="$WSREP_SST_OPT_ADDR"
RSYNC_PORT="$WSREP_SST_OPT_PORT"
RSYNC_ADDR="$WSREP_SST_OPT_HOST"
@@ -512,7 +545,7 @@ then
trap "exit 3" INT TERM ABRT
trap cleanup_joiner EXIT
- RSYNC_CONF="$WSREP_SST_OPT_DATA/$MODULE.conf"
+ touch "$SST_PROGRESS_FILE"
if [ -n "${MYSQL_TMP_DIR:-}" ]; then
SILENT="log file = $MYSQL_TMP_DIR/rsyncd.log"
@@ -535,18 +568,18 @@ $SILENT
path = $INNODB_DATA_HOME_DIR
EOF
-# rm -rf "$DATA"/ib_logfile* # we don't want old logs around
+# rm -rf "$DATA/ib_logfile"* # we don't want old logs around
- # If the IP is local listen only in it
+ # If the IP is local, listen only on it:
if is_local_ip "$RSYNC_ADDR_UNESCAPED"
then
RSYNC_EXTRA_ARGS="--address $RSYNC_ADDR_UNESCAPED"
STUNNEL_ACCEPT="$RSYNC_ADDR_UNESCAPED:$RSYNC_PORT"
else
- # Not local, possibly a NAT, listen on all interfaces
+ # Not local, possibly a NAT, listen on all interfaces:
RSYNC_EXTRA_ARGS=""
STUNNEL_ACCEPT="$RSYNC_PORT"
- # Overwrite address with all
+ # Overwrite address with all:
RSYNC_ADDR="*"
fi
@@ -554,8 +587,9 @@ EOF
then
rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS &
RSYNC_REAL_PID=$!
+ TRANSFER_REAL_PID="$RSYNC_REAL_PID"
+ TRANSFER_PID=$RSYNC_PID
else
- [ -f "$STUNNEL_PID" ] && rm -f "$STUNNEL_PID"
# Let's check if the path to the config file contains a space?
if [ "${RSYNC_CONF#* }" = "$RSYNC_CONF" ]; then
cat << EOF > "$STUNNEL_CONF"
@@ -566,6 +600,9 @@ foreground = yes
pid = $STUNNEL_PID
debug = warning
client = no
+${VERIFY_OPT}
+${CHECK_OPT}
+${CHECK_OPT_LOCAL}
[rsync]
accept = $STUNNEL_ACCEPT
exec = $(command -v rsync)
@@ -583,6 +620,9 @@ foreground = yes
pid = $STUNNEL_PID
debug = warning
client = no
+${VERIFY_OPT}
+${CHECK_OPT}
+${CHECK_OPT_LOCAL}
[rsync]
accept = $STUNNEL_ACCEPT
exec = $SHELL
@@ -590,15 +630,11 @@ execargs = $SHELL -c \$RSYNC_CMD
EOF
fi
stunnel "$STUNNEL_CONF" &
- RSYNC_REAL_PID=$!
- RSYNC_PID="$STUNNEL_PID"
+ STUNNEL_REAL_PID=$!
+ TRANSFER_REAL_PID="$STUNNEL_REAL_PID"
+ TRANSFER_PID=$STUNNEL_PID
fi
- until check_pid_and_port "$RSYNC_PID" "$RSYNC_REAL_PID" "$RSYNC_ADDR_UNESCAPED" "$RSYNC_PORT"
- do
- sleep 0.2
- done
-
if [ "${SSLMODE#VERIFY}" != "$SSLMODE" ]
then # backward-incompatible behavior
CN=""
@@ -619,19 +655,26 @@ EOF
ADDR="$CN:$MY_SECRET@$WSREP_SST_OPT_HOST"
else
MY_SECRET="" # for check down in recv_joiner()
- ADDR=$WSREP_SST_OPT_HOST
+ ADDR="$WSREP_SST_OPT_HOST"
fi
+ until check_pid_and_port "$TRANSFER_PID" $TRANSFER_REAL_PID "$RSYNC_ADDR_UNESCAPED" "$RSYNC_PORT"
+ do
+ sleep 0.2
+ done
+
echo "ready $ADDR:$RSYNC_PORT/$MODULE"
+ MYSQLD_PID="$WSREP_SST_OPT_PARENT"
+
# wait for SST to complete by monitoring magic file
- while [ ! -r "$MAGIC_FILE" ] && check_pid "$RSYNC_PID" && \
- ps -p $MYSQLD_PID >/dev/null
+ while [ ! -r "$MAGIC_FILE" ] && check_pid "$TRANSFER_PID" && \
+ ps -p $MYSQLD_PID >/dev/null 2>&1
do
sleep 1
done
- if ! ps -p $MYSQLD_PID >/dev/null
+ if ! ps -p $MYSQLD_PID >/dev/null 2>&1
then
wsrep_log_error \
"Parent mysqld process (PID: $MYSQLD_PID) terminated unexpectedly."
@@ -682,7 +725,7 @@ EOF
echo "rsync process ended without creating '$MAGIC_FILE'"
fi
- wsrep_cleanup_progress_file
+# wsrep_cleanup_progress_file
# cleanup_joiner
else
wsrep_log_error "Unrecognized role: '$WSREP_SST_OPT_ROLE'"