MDEV-25818: RSYNC SST failed due to busy port
This commit reduces the likelihood of getting a busy port on quick restarts with rsync SST (problem MDEV-25818) and fixes a number of other flaws in SST scripts, adds new functionality, and also synchronizes the xtrabackup-v2 script with the mariabackup script (the latter applies only to the 10.2 branch): 1) SST via rsync: rsync and stunnel does not always get the right time to complete by correctly handling SIGTERM. These utilities are now given more time to complete normally (via normal SIGTERM processing) before we move on to using "kill -9"; 2) SST via rsync: attempts to terminate an rsync or stunnel process (via "kill" utility) are only made if it did not terminated on its own; 3) SST via rsync: if a combination of stunnel and rsync is used, then we need to wait for both utilities to finish or stop, not just one of them; 4) The config file and pid file for stunnel are now deleted after successful completion of SST on the donor node; 5) The configs and pid files from rsync and stunnel should not be deleted unless these utilities succeed (or are sucessfully terminated) on the joiner node; 6) The configs and pid files now excluded from transfer via rsync; 7) Spaces in paths are now valid for config files as well (when used with SST via rsync or mariabackup / xtrabackup[-v2]); 8) SST via mariabackup: added preliminary verification of keys and certificates that are used when establishing a connection using SSL (to avoid long timeouts and improve diagnostics) - by analogy with how it is done for the xtrabackup-v2 (plus check for CA file), while that check is skipped if the user does not have openssl installed (or does not have diff utility); 9) Added backup-threads=<n> configuration option which adds "--parallel=<n>" for mariabackup / xtrabackup at backup and move-back stages; 10) Added encrypt-threads and encrypt-chunk-size configuration options for xbcrypt management (when xbcrypt is used); 11) Small optimization: checking the socat version and adding a file with parameters for 2048-bit Diffie-Hellman (if necessary) is done only if the user has not specified "dhparam=" in the "sockopt" option value; 12) SST via rsync now supports "backup-threads" configuration option (in server-related sections or in the "[sst]"); 13) Determining the number of available processors is now supported for FreeBSD + mariabackup/xtrabackup: before that we might have problems with "--compact" (rebuild indexes) or qpress on FreeBSD; 14) The check_pid() function should not raise an error state in the rare cases when the pid file was created, but it is empty, or if it is deleted right during the check, or when zero is read from the pid file; 15) Iproved templates that are used to check if a requested socket is "listening" when using the ss utility; 16) Shortened some other templates for socket state utilities; 17) Temporary files created by mariabackup / xtrabackup are moved to a separate subdirectory inside tmpdir (so they don't get mixed with other temporary files, which can make debugging more difficult); 18) 10.2 only: the script for SST via xtrabackup-v2 has been brought in full compliance with all the bugfixes made for mariabackup (as it previously contained many flaws compared to the updated script for mariabackup).
This commit is contained in:
parent
d3c77e08ae
commit
2fb4407827
@ -10,4 +10,3 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore
|
||||
|
||||
[mysqld.2]
|
||||
wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'
|
||||
|
||||
|
@ -9,4 +9,3 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true'
|
||||
|
||||
[mysqld.2]
|
||||
wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true'
|
||||
|
||||
|
@ -11,4 +11,3 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true'
|
||||
|
||||
[mysqld.2]
|
||||
wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true'
|
||||
|
||||
|
@ -8,5 +8,3 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true'
|
||||
|
||||
[mysqld.2]
|
||||
wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true'
|
||||
|
||||
|
||||
|
@ -5,10 +5,8 @@ wsrep_sst_method=xtrabackup-v2
|
||||
wsrep_sst_auth=root:
|
||||
innodb_safe_truncate=OFF
|
||||
|
||||
|
||||
[mysqld.1]
|
||||
wsrep_provider_options='base_port=@mysqld.1.#galera_port;pc.ignore_sb=true'
|
||||
|
||||
[mysqld.2]
|
||||
wsrep_provider_options='base_port=@mysqld.2.#galera_port;pc.ignore_sb=true'
|
||||
|
||||
|
@ -13,4 +13,4 @@ wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore
|
||||
|
||||
[sst]
|
||||
transferfmt=@ENV.MTR_GALERA_TFMT
|
||||
streamfmt=xbstream
|
||||
streamfmt=mbstream
|
||||
|
@ -10,3 +10,4 @@ transferfmt=@ENV.MTR_GALERA_TFMT
|
||||
compress=quicklz
|
||||
compress-threads=2
|
||||
compress-chunk-size=32768
|
||||
backup-threads=2
|
||||
|
@ -15,4 +15,4 @@ wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore
|
||||
|
||||
[sst]
|
||||
transferfmt=@ENV.MTR_GALERA_TFMT
|
||||
streamfmt=xbstream
|
||||
streamfmt=mbstream
|
||||
|
@ -8,4 +8,3 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore
|
||||
|
||||
[mysqld.2]
|
||||
wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'
|
||||
|
||||
|
@ -12,4 +12,3 @@ log_bin_index=@ENV.MYSQLTEST_VARDIR/tmp/server1_binlog_index.index
|
||||
wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'
|
||||
log_bin=@ENV.MYSQLTEST_VARDIR/server2_binlog
|
||||
log_bin_index=@ENV.MYSQLTEST_VARDIR/tmp/server2_binlog_index.index
|
||||
|
||||
|
@ -9,3 +9,6 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore
|
||||
[mysqld.2]
|
||||
innodb_data_home_dir=@ENV.MYSQL_TMP_DIR/rsync_test_2
|
||||
wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'
|
||||
|
||||
[sst]
|
||||
backup_threads=2
|
||||
|
@ -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')
|
||||
@ -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 \
|
||||
@ -959,6 +986,43 @@ check_sockets_utils()
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# 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
|
||||
@ -966,28 +1030,95 @@ check_sockets_utils()
|
||||
#
|
||||
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;
|
||||
@ -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
|
||||
@ -1032,8 +1163,8 @@ trim_string()
|
||||
if [ $x -ne $z ]; then
|
||||
local y="${1%$pattern*}"
|
||||
y=${#y}
|
||||
x=$(( $z-$x-1 ))
|
||||
y=$(( $y-$x+1 ))
|
||||
x=$(( z-x-1 ))
|
||||
y=$(( y-x+1 ))
|
||||
printf '%s' "${1:$x:$y}"
|
||||
else
|
||||
printf ''
|
||||
@ -1043,3 +1174,105 @@ trim_string()
|
||||
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
|
||||
}
|
||||
|
@ -29,11 +29,10 @@ eformat=""
|
||||
ekey=""
|
||||
ekeyfile=""
|
||||
encrypt=0
|
||||
nproc=1
|
||||
ecode=0
|
||||
ssyslog=""
|
||||
ssystag=""
|
||||
MARIABACKUP_PID=""
|
||||
BACKUP_PID=""
|
||||
tcert=""
|
||||
tpem=""
|
||||
tkey=""
|
||||
@ -77,6 +76,11 @@ compress='none'
|
||||
compress_chunk=""
|
||||
compress_threads=""
|
||||
|
||||
backup_threads=""
|
||||
|
||||
encrypt_threads=""
|
||||
encrypt_chunk=""
|
||||
|
||||
readonly SECRET_TAG="secret"
|
||||
|
||||
# Required for backup locks
|
||||
@ -90,8 +94,8 @@ fi
|
||||
pcmd="pv $pvopts"
|
||||
declare -a RC
|
||||
|
||||
MARIABACKUP_BIN="$(command -v mariabackup)"
|
||||
if [ ! -x "$MARIABACKUP_BIN" ]; then
|
||||
BACKUP_BIN="$(command -v mariabackup)"
|
||||
if [ ! -x "$BACKUP_BIN" ]; then
|
||||
wsrep_log_error 'mariabackup binary not found in path'
|
||||
exit 42
|
||||
fi
|
||||
@ -108,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="$@"
|
||||
@ -198,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
|
||||
@ -298,15 +309,6 @@ get_transfer()
|
||||
exit 2
|
||||
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 "***************************************"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
local action='Decrypting'
|
||||
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
||||
tcmd="socat -u openssl-listen:$SST_PORT,reuseaddr"
|
||||
@ -315,10 +317,22 @@ get_transfer()
|
||||
action='Encrypting'
|
||||
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
|
||||
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
|
||||
@ -330,6 +344,11 @@ get_transfer()
|
||||
wsrep_log_error "Both PEM and CRT files required"
|
||||
exit 22
|
||||
fi
|
||||
if [ ! -r "$tpem" -o ! -r "$tcert" ]; then
|
||||
wsrep_log_error "Both PEM and CRT files must be readable"
|
||||
exit 22
|
||||
fi
|
||||
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"
|
||||
@ -339,6 +358,11 @@ get_transfer()
|
||||
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
|
||||
if [ $encrypt -eq 4 ]; then
|
||||
@ -350,6 +374,11 @@ get_transfer()
|
||||
wsrep_log_info "$action with cert=$tpem, key=$tkey, verify=0"
|
||||
else
|
||||
# CA verification
|
||||
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
|
||||
@ -440,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" ]
|
||||
@ -504,21 +533,28 @@ 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
|
||||
sfmt='mbstream'
|
||||
MBSTREAM_BIN="$(command -v mbstream)"
|
||||
if [ -z "$MBSTREAM_BIN" ]; then
|
||||
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'
|
||||
@ -531,79 +567,33 @@ get_stream()
|
||||
wsrep_log_info "Streaming with $sfmt"
|
||||
}
|
||||
|
||||
get_proc()
|
||||
{
|
||||
set +e
|
||||
nproc=$(grep -c processor /proc/cpuinfo)
|
||||
[ -z $nproc -o $nproc -eq 0 ] && nproc=1
|
||||
set -e
|
||||
}
|
||||
|
||||
sig_joiner_cleanup()
|
||||
{
|
||||
wsrep_log_error "Removing $MAGIC_FILE file due to signal"
|
||||
[ -f "$MAGIC_FILE" ] && rm -f "$MAGIC_FILE"
|
||||
}
|
||||
|
||||
cleanup_joiner()
|
||||
cleanup_at_exit()
|
||||
{
|
||||
# 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
|
||||
fi
|
||||
|
||||
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
||||
wsrep_log_info "Removing the sst_in_progress file"
|
||||
wsrep_cleanup_progress_file
|
||||
fi
|
||||
if [ -n "$progress" -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
|
||||
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
|
||||
|
||||
exit $estatus
|
||||
}
|
||||
|
||||
check_pid()
|
||||
{
|
||||
local pid_file="$1"
|
||||
[ -r "$pid_file" ] && ps -p $(cat "$pid_file") 2>&1 >/dev/null
|
||||
}
|
||||
|
||||
cleanup_donor()
|
||||
{
|
||||
# Since this is invoked just after exit NNN
|
||||
local estatus=$?
|
||||
if [ $estatus -ne 0 ]; then
|
||||
wsrep_log_error "Cleanup after exit with status:$estatus"
|
||||
fi
|
||||
|
||||
if [ -n "$MARIABACKUP_PID" ]; then
|
||||
if check_pid $MARIABACKUP_PID
|
||||
then
|
||||
wsrep_log_error "mariabackup process is still running. Killing..."
|
||||
kill_mariabackup
|
||||
fi
|
||||
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
|
||||
@ -611,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]*')
|
||||
@ -623,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"
|
||||
@ -648,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
|
||||
@ -708,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
|
||||
@ -825,11 +779,12 @@ 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
|
||||
@ -839,14 +794,14 @@ monitor_process()
|
||||
[ -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
|
||||
|
||||
@ -942,8 +897,8 @@ else
|
||||
gzip "$newfile"
|
||||
fi
|
||||
fi
|
||||
INNOAPPLY="&> '$INNOAPPLYLOG'"
|
||||
INNOMOVE="&> '$INNOMOVELOG'"
|
||||
INNOAPPLY="> '$INNOAPPLYLOG' 2>&1"
|
||||
INNOMOVE="> '$INNOMOVELOG' 2>&1"
|
||||
INNOBACKUP="2> '$INNOBACKUPLOG'"
|
||||
fi
|
||||
|
||||
@ -953,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
|
||||
@ -963,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
|
||||
@ -976,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
|
||||
@ -1048,25 +1006,29 @@ 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"
|
||||
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[@]}" )"
|
||||
@ -1082,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
|
||||
|
||||
@ -1134,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
|
||||
@ -1173,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
|
||||
@ -1196,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
|
||||
@ -1316,7 +1282,7 @@ 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"
|
||||
|
||||
@ -1327,26 +1293,26 @@ then
|
||||
|
||||
MAGIC_FILE="$TDATA/$INFO_FILE"
|
||||
|
||||
wsrep_log_info "Moving the backup to ${TDATA}"
|
||||
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 "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
|
||||
|
||||
|
@ -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"
|
||||
|
@ -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 ! check_port "$pid" "$port" "$utils"; then
|
||||
local port_info
|
||||
local busy=0
|
||||
|
||||
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_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 [ -n "$is_listening_all" -o -n "$is_listening_addr" ]; then
|
||||
wsrep_log_error "rsync or stunnel daemon port '$rsync_port' " \
|
||||
|
||||
if [ $busy -eq 0 ]; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
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*'
|
||||
@ -266,7 +267,7 @@ then
|
||||
else
|
||||
# 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,3}|[0-9a-fA-F]*(\:[0-9a-fA-F]*)+)$'
|
||||
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
|
||||
@ -303,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
|
||||
@ -321,6 +322,8 @@ ${VERIFY_OPT}
|
||||
${CHECK_OPT}
|
||||
${CHECK_OPT_LOCAL}
|
||||
EOF
|
||||
else
|
||||
[ -f "$STUNNEL_CONF" ] && rm -f "$STUNNEL_CONF"
|
||||
fi
|
||||
|
||||
if [ $WSREP_SST_OPT_BYPASS -eq 0 ]
|
||||
@ -329,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"
|
||||
|
||||
@ -350,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
|
||||
|
||||
@ -385,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'"} \
|
||||
@ -436,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 \
|
||||
@ -484,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"
|
||||
|
||||
MODULE="rsync_sst"
|
||||
|
||||
RSYNC_PID="$WSREP_SST_OPT_DATA/$MODULE.pid"
|
||||
# give some time for lingering rsync from previous SST to complete
|
||||
# give some time for lingering stunnel from previous SST to complete
|
||||
check_round=0
|
||||
while check_pid "$RSYNC_PID" && [ $check_round -lt 10 ]
|
||||
while check_pid "$STUNNEL_PID" 1
|
||||
do
|
||||
wsrep_log_info "lingering rsync daemon found at startup, waiting for it to exit"
|
||||
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
|
||||
|
||||
if check_pid "$RSYNC_PID"
|
||||
then
|
||||
wsrep_log_error "rsync daemon already running."
|
||||
exit 114 # EALREADY
|
||||
fi
|
||||
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" 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
|
||||
|
||||
[ -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"
|
||||
@ -522,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"
|
||||
@ -545,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
|
||||
|
||||
@ -564,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"
|
||||
@ -606,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=""
|
||||
@ -635,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."
|
||||
@ -698,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'"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -97,8 +97,9 @@ 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
|
||||
@ -324,12 +325,6 @@ cleanup_joiner()
|
||||
fi
|
||||
}
|
||||
|
||||
check_pid()
|
||||
{
|
||||
local pid_file="$1"
|
||||
[ -r "$pid_file" ] && ps -p $(cat "$pid_file") >/dev/null 2>&1
|
||||
}
|
||||
|
||||
cleanup_donor()
|
||||
{
|
||||
# Since this is invoked just after exit NNN
|
||||
@ -339,12 +334,11 @@ cleanup_donor()
|
||||
fi
|
||||
|
||||
if [[ -n "$XTRABACKUP_PID" ]];then
|
||||
if check_pid "$XTRABACKUP_PID"
|
||||
if check_pid "$XTRABACKUP_PID" 1
|
||||
then
|
||||
wsrep_log_error "xtrabackup process is still running. Killing... "
|
||||
kill_xtrabackup
|
||||
cleanup_pid $CHECK_PID "$XTRABACKUP_PID"
|
||||
fi
|
||||
rm -f "$XTRABACKUP_PID"
|
||||
fi
|
||||
|
||||
rm -f "${DATA}/${IST_FILE}"
|
||||
@ -355,13 +349,6 @@ cleanup_donor()
|
||||
fi
|
||||
}
|
||||
|
||||
kill_xtrabackup()
|
||||
{
|
||||
local PID=$(cat "$XTRABACKUP_PID")
|
||||
[ -n "$PID" -a $PID -ne 0 ] && kill $PID && (kill $PID && kill -9 $PID) || :
|
||||
rm -f "$XTRABACKUP_PID"
|
||||
}
|
||||
|
||||
# waits ~10 seconds for nc to open the port and then reports ready
|
||||
# (regardless of timeout)
|
||||
wait_for_listen()
|
||||
|
Loading…
x
Reference in New Issue
Block a user