Commit 27ae7f2a authored by Julius Goryavsky's avatar Julius Goryavsky

MDEV-23580: WSREP_SST: [ERROR] rsync daemon port has been taken

This commit contains a large set of further bug fixes and
improvements to SST scripts for Galera, continuing the work
that was started in MDEV-24962 to make SST scripts work smoothly
in different network configurations (especially using ipv6) and
with different environment settings:

 1) The ipv6 addresses were incorrectly handled in the SST script
    for rsync (incorrect address substitution for establishing a
    connection, incorrect address substitution for bind, and so on);
 2) Checking the locality of the ip-address in SST scripts did not
    support ipv6 addresses (such as "[::1]"), which were falsely
    identified as non-local ip, which further did not allow running
    two SSTs on different local addresses on the same machine.
    On the other hand, this bug masked some other errors (related
    to handling ipv6 addresses);
 3) The code for checking the locality of the ip address was different
    in the SST scripts for rsync and for mysqldump, with individual
    flaws. This code is now made common and moved to wsrep_sst_common;
 4) Waiting for the start of the transport channel (socat, nc, rsync,
    stunnel) in the wait_for_listen() and check_pid_and_port() functions
    did not process ipv6 addresses correctly in all cases (not for all
    branches);
 5) Waiting for the start of the transport channel (socat, nc, rsync,
    stunnel) in the wait_for_listen() and check_pid_and_port() functions
    for some code branches could give a false positive result due to
    the textual match of prefixes in the port number and/or PID of
    the process;
 6) Waiting for the start of the transport channel (socat, nc, rsync,
    stunnel) was supported through different utilities in SST scripts
    for mariabackup and for rsync, and with various minor flaws in
    the code. Now the code is still different in these scripts, but
    it supports a common set of utilities (lsof, ss, sockstat) and
    is synchronized across patterns that used to check the output
    of  these utilities;
 7) In SST via mariabackup, the signal about readiness to receive data
    is sometimes sent too early - immediately after listen(), and not
    after accept() (which are called by socat or netcat utility).
 8) Checking availability of the some options of some utilities was
    done using the grep pattern, which easily gives false positives;
 9) Common name (CN) for local addresses, if not explicitly specified,
    is now always replaced to "localhost" to avoid the need to generate
    many separate certificates for local addresses of one machine and
    not to depend on which the local address is currently used in test
    (ipv4 or ipv6, etc.);
10) In tests galera_sst_mariabackup_encrypt_with_key_server and
    galera_sst_rsync_encrypt_with_key_server the correct certificate
    is selected to avoid commonname (CN) mismatch problems;
11) Further refactoring to protect against spaces in file names.
12) Further general refactoring to eliminate bash-specific constructs
    or to improve code readability;
13) The code for setting options for the nc (netcat) utility was
    different in different scripts for SST - now it is made identical.
14) Fixed long-time broken encryption via xbcrypt in combination with
    mariabackup and added support for key-based encryption via openssl
    utility, which is now enabled by default for encrypt=1 mode (this
    default mode can be changed using a new configuration file option
    "encypt-format=openssl|xbcrypt", which can be placed in the [mysqld],
    [sst] or in the [xtrabackup] section) - this change will allow us
    to use and to test the encypt=1 encryption without installing
    non-standard third-party utilities.
parent b2bb747f
!include ../galera_2nodes.cnf
[mysqld]
wsrep_sst_method=mariabackup
wsrep_sst_auth="root:"
wsrep_debug=ON
[sst]
encrypt-format=openssl
encrypt=1
encrypt-algo=aes-256-ctr
encrypt-key=4FA92C5873672E20FB163A0BCB2BB4A4
transferfmt=@ENV.MTR_GALERA_TFMT
#
# This test checks that encryption with key using openssl with options
# passed to mariabackup via the my.cnf file
#
--source include/galera_cluster.inc
--source include/have_innodb.inc
--source include/have_mariabackup.inc
SELECT 1;
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
--source include/wait_condition.inc
...@@ -5,8 +5,8 @@ wsrep_sst_method=mariabackup ...@@ -5,8 +5,8 @@ wsrep_sst_method=mariabackup
wsrep_sst_auth="root:" wsrep_sst_auth="root:"
wsrep_debug=ON wsrep_debug=ON
ssl-cert=@ENV.MYSQL_TEST_DIR/std_data/client-cert.pem ssl-cert=@ENV.MYSQL_TEST_DIR/std_data/server-cert.pem
ssl-key=@ENV.MYSQL_TEST_DIR/std_data/client-key.pem ssl-key=@ENV.MYSQL_TEST_DIR/std_data/server-key.pem
ssl-ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem ssl-ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem
[sst] [sst]
......
...@@ -18,7 +18,7 @@ SELECT 1; ...@@ -18,7 +18,7 @@ SELECT 1;
# Confirm that transfer was SSL-encrypted # Confirm that transfer was SSL-encrypted
--let $assert_text = Using openssl based encryption with socat --let $assert_text = Using openssl based encryption with socat
--let $assert_select = Using openssl based encryption with socat: with key and c --let $assert_select = Using openssl based encryption with socat: with key and crt
--let $assert_count = 1 --let $assert_count = 1
--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err --let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err
--let $assert_only_after = CURRENT_TEST --let $assert_only_after = CURRENT_TEST
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
[mysqld] [mysqld]
wsrep_sst_method=rsync wsrep_sst_method=rsync
ssl-cert=@ENV.MYSQL_TEST_DIR/std_data/client-cert.pem ssl-cert=@ENV.MYSQL_TEST_DIR/std_data/server-cert.pem
ssl-key=@ENV.MYSQL_TEST_DIR/std_data/client-key.pem ssl-key=@ENV.MYSQL_TEST_DIR/std_data/server-key.pem
ssl-ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem ssl-ca=@ENV.MYSQL_TEST_DIR/std_data/cacert.pem
[sst] [sst]
......
...@@ -51,7 +51,7 @@ case "$1" in ...@@ -51,7 +51,7 @@ case "$1" in
# #
# Break address string into host:port/path parts # Break address string into host:port/path parts
# #
case "${WSREP_SST_OPT_ADDR}" in case "$WSREP_SST_OPT_ADDR" in
\[*) \[*)
# IPv6 # IPv6
# Remove the starting and ending square brackets, if present: # Remove the starting and ending square brackets, if present:
...@@ -81,7 +81,7 @@ case "$1" in ...@@ -81,7 +81,7 @@ case "$1" in
# up to "/" (if present): # up to "/" (if present):
WSREP_SST_OPT_ADDR_PORT="${remain%%/*}" WSREP_SST_OPT_ADDR_PORT="${remain%%/*}"
# If the "/" character is present, then the path is not empty: # If the "/" character is present, then the path is not empty:
if [ "${remain#*/}" != "${remain}" ]; then if [ "${remain#*/}" != "$remain" ]; then
# This operation removes everything up to the "/" character, # This operation removes everything up to the "/" character,
# effectively removing the port number from the string: # effectively removing the port number from the string:
readonly WSREP_SST_OPT_PATH="${remain#*/}" readonly WSREP_SST_OPT_PATH="${remain#*/}"
...@@ -89,10 +89,10 @@ case "$1" in ...@@ -89,10 +89,10 @@ case "$1" in
readonly WSREP_SST_OPT_PATH="" readonly WSREP_SST_OPT_PATH=""
fi fi
# The rest of the string is the same as the path (for now): # The rest of the string is the same as the path (for now):
remain="${WSREP_SST_OPT_PATH}" remain="$WSREP_SST_OPT_PATH"
# If there is one more "/" in the string, then everything before # If there is one more "/" in the string, then everything before
# it will be the module name, otherwise the module name is empty: # it will be the module name, otherwise the module name is empty:
if [ "${remain%%/*}" != "${remain}" ]; then if [ "${remain%%/*}" != "$remain" ]; then
# This operation removes the tail after the very first # This operation removes the tail after the very first
# occurrence of the "/" character (inclusively): # occurrence of the "/" character (inclusively):
readonly WSREP_SST_OPT_MODULE="${remain%%/*}" readonly WSREP_SST_OPT_MODULE="${remain%%/*}"
...@@ -103,7 +103,7 @@ case "$1" in ...@@ -103,7 +103,7 @@ case "$1" in
remain="${WSREP_SST_OPT_PATH#*/}" remain="${WSREP_SST_OPT_PATH#*/}"
# If the rest of the string does not match the original, then there # If the rest of the string does not match the original, then there
# was something else besides the module name: # was something else besides the module name:
if [ "$remain" != "${WSREP_SST_OPT_PATH}" ]; then if [ "$remain" != "$WSREP_SST_OPT_PATH" ]; then
# Extract the part that matches the LSN by removing all # Extract the part that matches the LSN by removing all
# characters starting from the very first "/": # characters starting from the very first "/":
readonly WSREP_SST_OPT_LSN="${remain%%/*}" readonly WSREP_SST_OPT_LSN="${remain%%/*}"
...@@ -113,7 +113,7 @@ case "$1" in ...@@ -113,7 +113,7 @@ case "$1" in
# If the remainder does not match the original string, # If the remainder does not match the original string,
# then there is something else (the version number in # then there is something else (the version number in
# our case): # our case):
if [ "$remain" != "${WSREP_SST_OPT_LSN}" ]; then if [ "$remain" != "$WSREP_SST_OPT_LSN" ]; then
# Let's extract the version number by removing the tail # Let's extract the version number by removing the tail
# after the very first occurence of the "/" character # after the very first occurence of the "/" character
# (inclusively): # (inclusively):
...@@ -535,7 +535,8 @@ readonly WSREP_SST_OPT_ADDR_PORT ...@@ -535,7 +535,8 @@ readonly WSREP_SST_OPT_ADDR_PORT
# try to use my_print_defaults, mysql and mysqldump that come with the sources # try to use my_print_defaults, mysql and mysqldump that come with the sources
# (for MTR suite) # (for MTR suite)
SCRIPTS_DIR="$(cd $(dirname "$0"); pwd -P)" script_binary=$(dirname "$0")
SCRIPTS_DIR=$(cd "$script_binary"; pwd -P)
EXTRA_DIR="$SCRIPTS_DIR/../extra" EXTRA_DIR="$SCRIPTS_DIR/../extra"
CLIENT_DIR="$SCRIPTS_DIR/../client" CLIENT_DIR="$SCRIPTS_DIR/../client"
...@@ -581,30 +582,45 @@ readonly MY_PRINT_DEFAULTS="$MY_PRINT_DEFAULTS $WSREP_SST_OPT_CONF" ...@@ -581,30 +582,45 @@ readonly MY_PRINT_DEFAULTS="$MY_PRINT_DEFAULTS $WSREP_SST_OPT_CONF"
# #
parse_cnf() parse_cnf()
{ {
local group="$1" local groups="$1"
local var="$2" local var="$2"
local reval="" local reval=""
# normalize the variable names specified in cnf file (user can use _ or - for example log-bin or log_bin) # normalize the variable names specified in the .cnf file
# then search for needed variable # (user can use '_' or '-', for example, log-bin or log_bin),
# finally get the variable value (if variables has been specified multiple time use the last value only) # then search for the last instance of the desired variable
# and finally get the value of that variable (if the variable
if [ "$group" = '--mysqld' -o \ # was specified several times - we use only its last instance):
"$group" = 'mysqld' ]; then
if [ -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then local pattern='BEGIN {OFS=FS="="} {sub(/^--loose/,"-",$0); gsub(/_/,"-",$1); if ($1=="--'"$var"'") lastval=substr($0,length($1)+2)} END {print lastval}'
reval=$($MY_PRINT_DEFAULTS "mysqld$WSREP_SST_OPT_SUFFIX_VALUE" | awk 'BEGIN {OFS=FS="="} {sub(/^--loose/,"-",$0); gsub(/_/,"-",$1); if ($1=="--'"$var"'") lastval=substr($0,length($1)+2)} END {print lastval}')
fi while [ -n "$groups" ]; do
fi # Remove the largest suffix starting with the '|' character:
local group="${groups%%\|*}"
if [ -z "$reval" ]; then # Remove the remainder (the group name) from the rest
reval=$($MY_PRINT_DEFAULTS "$group" | awk 'BEGIN {OFS=FS="="} {sub(/^--loose/,"-",$0); gsub(/_/,"-",$1); if ($1=="--'"$var"'") lastval=substr($0,length($1)+2)} END {print lastval}') # of the groups list (as if it were a prefix):
fi groups="${groups#$group}"
groups="${groups#\|}"
# if the group name is the same as the "[--]mysqld", then
# try to use it together with the group suffix:
if [ "${group#--}" = 'mysqld' -a -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then
reval=$($MY_PRINT_DEFAULTS "mysqld$WSREP_SST_OPT_SUFFIX_VALUE" | awk "$pattern")
if [ -n "$reval" ]; then
break
fi
fi
# Let's try to use the group name as it is:
reval=$($MY_PRINT_DEFAULTS "$group" | awk "$pattern")
if [ -n "$reval" ]; then
break
fi
done
# use default if we haven't found a value # use default if we haven't found a value:
if [ -z "$reval" ]; then if [ -z "$reval" ]; then
[ -n "${3:-}" ] && reval="$3" [ -n "${3:-}" ] && reval="$3"
fi fi
echo $reval echo "$reval"
} }
# #
...@@ -615,18 +631,37 @@ parse_cnf() ...@@ -615,18 +631,37 @@ parse_cnf()
# #
in_config() in_config()
{ {
local group="$1" local groups="$1"
local var="$2" local var="$2"
local found=0 local found=0
if [ "$group" = '--mysqld' -o \
"$group" = 'mysqld' ]; then # normalize the variable names specified in the .cnf file
if [ -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then # (user can use '_' or '-', for example, log-bin or log_bin),
found=$($MY_PRINT_DEFAULTS "mysqld$WSREP_SST_OPT_SUFFIX_VALUE" | awk 'BEGIN {OFS=FS="="; found=0} {sub(/^--loose/,"-",$0); gsub(/_/,"-",$1); if ($1=="--'"$var"'") found=1} END {print found}') # then search for the last instance(s) of the desired variable:
fi
fi local pattern='BEGIN {OFS=FS="="; found=0} {sub(/^--loose/,"-",$0); gsub(/_/,"-",$1); if ($1=="--'"$var"'") found=1} END {print found}'
if [ $found -eq 0 ]; then
found=$($MY_PRINT_DEFAULTS "$group" | awk 'BEGIN {OFS=FS="="; found=0} {sub(/^--loose/,"-",$0); gsub(/_/,"-",$1); if ($1=="--'"$var"'") found=1} END {print found}') while [ -n "$groups" ]; do
fi # Remove the largest suffix starting with the '|' character:
local group="${groups%%\|*}"
# Remove the remainder (the group name) from the rest
# of the groups list (as if it were a prefix):
groups="${groups#$group}"
groups="${groups#\|}"
# if the group name is the same as the "[--]mysqld", then
# try to use it together with the group suffix:
if [ "${group#--}" = 'mysqld' -a -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then
found=$($MY_PRINT_DEFAULTS "mysqld$WSREP_SST_OPT_SUFFIX_VALUE" | awk "$pattern")
if [ $found -ne 0 ]; then
break
fi
fi
# Let's try to use the group name as it is:
found=$($MY_PRINT_DEFAULTS "$group" | awk "$pattern")
if [ $found -ne 0 ]; then
break
fi
done
echo $found echo $found
} }
...@@ -747,7 +782,7 @@ wsrep_check_programs() ...@@ -747,7 +782,7 @@ wsrep_check_programs()
while [ $# -gt 0 ] while [ $# -gt 0 ]
do do
wsrep_check_program $1 || ret=$? wsrep_check_program "$1" || ret=$?
shift shift
done done
...@@ -793,3 +828,52 @@ wsrep_gen_secret() ...@@ -793,3 +828,52 @@ wsrep_gen_secret()
$RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM $RANDOM
fi fi
} }
is_local_ip()
{
[ "$1" = '127.0.0.1' ] && return 0
[ "$1" = '127.0.0.2' ] && return 0
[ "$1" = 'localhost' ] && return 0
[ "$1" = '[::1]' ] && return 0
[ "$1" = "$(hostname -s)" ] && return 0
[ "$1" = "$(hostname -f)" ] && return 0
[ "$1" = "$(hostname -d)" ] && return 0
local ip_util="$(command -v ip)"
if [ -x "$ip_util" ]; then
# ip address show ouput format is " inet[6] <address>/<mask>":
"$ip_util" address show \
| grep -E "^[[:space:]]*inet.? [^[:space:]]+/" -o \
| grep -F " $1/" >/dev/null && return 0
else
local ifconfig_util="$(command -v ifconfig)"
if [ -x "$ifconfig_util" ]; then
# ifconfig output format is " inet[6] <address> ...":
"$ifconfig_util" \
| grep -E "^[[:space:]]*inet.? [^[:space:]]+ " -o \
| grep -F " $1 " >/dev/null && return 0
fi
fi
return 1
}
check_sockets_utils()
{
lsof_available=0
sockstat_available=0
ss_available=0
[ -x "$(command -v lsof)" ] && lsof_available=1
[ -x "$(command -v sockstat)" ] && sockstat_available=1
[ -x "$(command -v ss)" ] && ss_available=1
if [ $lsof_available -eq 0 -a \
$sockstat_available -eq 0 -a \
$ss_available -eq 0 ]
then
wsrep_log_error "Neither lsof tool, nor ss or sockstat was found in " \
"the PATH! Make sure you have it installed."
exit 2 # ENOENT
fi
}
#!/bin/bash -ue #!/bin/bash -ue
# Copyright (C) 2013 Percona Inc
# Copyright (C) 2017-2021 MariaDB # Copyright (C) 2017-2021 MariaDB
# Copyright (C) 2013 Percona Inc
# #
# This program is free software; you can redistribute it and/or modify # 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 # it under the terms of the GNU General Public License as published by
...@@ -17,14 +17,15 @@ ...@@ -17,14 +17,15 @@
# MA 02110-1335 USA. # MA 02110-1335 USA.
# Documentation: # Documentation:
# http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html # https://mariadb.com/kb/en/mariabackup-overview/
# Make sure to read that before proceeding! # Make sure to read that before proceeding!
. $(dirname $0)/wsrep_sst_common . $(dirname "$0")/wsrep_sst_common
wsrep_check_datadir wsrep_check_datadir
OS=$(uname) OS="$(uname)"
ealgo="" ealgo=""
eformat=""
ekey="" ekey=""
ekeyfile="" ekeyfile=""
encrypt=0 encrypt=0
...@@ -32,7 +33,7 @@ nproc=1 ...@@ -32,7 +33,7 @@ nproc=1
ecode=0 ecode=0
ssyslog="" ssyslog=""
ssystag="" ssystag=""
XTRABACKUP_PID="" MARIABACKUP_PID=""
SST_PORT="" SST_PORT=""
REMOTEIP="" REMOTEIP=""
tcert="" tcert=""
...@@ -47,7 +48,7 @@ lsn="" ...@@ -47,7 +48,7 @@ lsn=""
ecmd="" ecmd=""
rlimit="" rlimit=""
# Initially # Initially
stagemsg="${WSREP_SST_OPT_ROLE}" stagemsg="$WSREP_SST_OPT_ROLE"
cpat="" cpat=""
speciald=1 speciald=1
ib_home_dir="" ib_home_dir=""
...@@ -59,8 +60,8 @@ strmcmd="" ...@@ -59,8 +60,8 @@ strmcmd=""
tfmt="" tfmt=""
tcmd="" tcmd=""
payload=0 payload=0
pvformat="-F '%N => Rate:%r Avg:%a Elapsed:%t %e Bytes: %b %p' " pvformat="-F '%N => Rate:%r Avg:%a Elapsed:%t %e Bytes: %b %p'"
pvopts="-f -i 10 -N $WSREP_SST_OPT_ROLE " pvopts="-f -i 10 -N $WSREP_SST_OPT_ROLE"
STATDIR="" STATDIR=""
uextra=0 uextra=0
disver="" disver=""
...@@ -79,23 +80,22 @@ readonly SECRET_TAG="secret" ...@@ -79,23 +80,22 @@ readonly SECRET_TAG="secret"
# 5.6.21 PXC and later can't donate to an older joiner # 5.6.21 PXC and later can't donate to an older joiner
sst_ver=1 sst_ver=1
if pv --help 2>/dev/null | grep -q FORMAT;then if [ -x "$(command -v pv)" ] && pv --help | grep -qw -- '-F'; then
pvopts+=$pvformat pvopts="$pvopts $pvformat"
fi fi
pcmd="pv $pvopts" pcmd="pv $pvopts"
declare -a RC declare -a RC
set +e set +e
MARIABACKUP_BIN="$(command -v mariabackup)" MARIABACKUP_BIN="$(command -v mariabackup)"
if [ -z "$MARIABACKUP_BIN" ]; then if [ ! -x "$MARIABACKUP_BIN" ]; then
wsrep_log_error 'mariabackup binary not found in $PATH' wsrep_log_error 'mariabackup binary not found in $PATH'
exit 42 exit 42
fi fi
set -e set -e
MBSTREAM_BIN=mbstream MBSTREAM_BIN=mbstream
XBCRYPT_BIN=xbcrypt # Not available in MariaBackup
DATA="${WSREP_SST_OPT_DATA}" DATA="$WSREP_SST_OPT_DATA"
INFO_FILE="xtrabackup_galera_info" INFO_FILE="xtrabackup_galera_info"
IST_FILE="xtrabackup_ist" IST_FILE="xtrabackup_ist"
MAGIC_FILE="$DATA/$INFO_FILE" MAGIC_FILE="$DATA/$INFO_FILE"
...@@ -112,7 +112,7 @@ timeit(){ ...@@ -112,7 +112,7 @@ timeit(){
local cmd="$@" local cmd="$@"
local x1 x2 took extcode local x1 x2 took extcode
if [[ $ttime -eq 1 ]];then if [ $ttime -eq 1 ]; then
x1=$(date +%s) x1=$(date +%s)
wsrep_log_info "Evaluating $cmd" wsrep_log_info "Evaluating $cmd"
eval "$cmd" eval "$cmd"
...@@ -137,19 +137,21 @@ get_keys() ...@@ -137,19 +137,21 @@ get_keys()
fi fi
if [ $encrypt -eq 0 ]; then if [ $encrypt -eq 0 ]; then
if $MY_PRINT_DEFAULTS xtrabackup | grep -q -- "--encrypt"; then if [ -n "$ealgo" -o -n "$ekey" -o -n "$ekeyfile" ]; then
wsrep_log_error "Unexpected option combination. SST may fail. Refer to http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html" wsrep_log_error "Options for encryption are specified, " \
"but encryption itself is disabled. SST may fail."
fi fi
return return
fi fi
if [ $sfmt = 'tar' ]; then if [ $sfmt = 'tar' ]; then
wsrep_log_info "NOTE: Xtrabackup-based encryption - encrypt=1 - cannot be enabled with tar format" wsrep_log_info "NOTE: key-based encryption (encrypt=1) " \
"cannot be enabled with tar format"
encrypt=-1 encrypt=-1
return return
fi fi
wsrep_log_info "Xtrabackup based encryption enabled in my.cnf - Supported only from Xtrabackup 2.1.4" wsrep_log_info "Key based encryption enabled in my.cnf"
if [ -z "$ealgo" ]; then if [ -z "$ealgo" ]; then
wsrep_log_error "FATAL: Encryption algorithm empty from my.cnf, bailing out" wsrep_log_error "FATAL: Encryption algorithm empty from my.cnf, bailing out"
...@@ -161,17 +163,49 @@ get_keys() ...@@ -161,17 +163,49 @@ get_keys()
exit 3 exit 3
fi fi
if [ -z "$ekey" ]; then if [ "$eformat" = 'openssl' ]; then
ecmd="$XBCRYPT_BIN --encrypt-algo='$ealgo' --encrypt-key-file='$ekeyfile'" get_openssl
if [ -z "$OPENSSL_BINARY" ]; then
wsrep_log_error "If encryption using the openssl is enabled, " \
"then you need to install openssl"
exit 2
fi
ecmd="'$OPENSSL_BINARY' enc -$ealgo"
if "$OPENSSL_BINARY" enc -help 2>&1 | grep -qw -- '-pbkdf2'; then
ecmd="$ecmd -pbkdf2"
elif "$OPENSSL_BINARY" enc -help 2>&1 | grep -qw -- '-iter'; then
ecmd="$ecmd -iter 1"
elif "$OPENSSL_BINARY" enc -help 2>&1 | grep -qw -- '-md'; then
ecmd="$ecmd -md sha256"
fi
if [ -z "$ekey" ]; then
ecmd="$ecmd -kfile '$ekeyfile'"
else
ecmd="$ecmd -k '$ekey'"
fi
elif [ "$eformat" = 'xbcrypt' ]; then
if [ ! -x "$(command -v xbcrypt)" ]; then
wsrep_log_error "If encryption using the xbcrypt is enabled, " \
"then you need to install xbcrypt"
exit 2
fi
wsrep_log_info "NOTE: xbcrypt-based encryption, " \
"supported only from Xtrabackup 2.1.4"
if [ -z "$ekey" ]; then
ecmd="xbcrypt --encrypt-algo='$ealgo' --encrypt-key-file='$ekeyfile'"
else
ecmd="xbcrypt --encrypt-algo='$ealgo' --encrypt-key='$ekey'"
fi
else else
ecmd="$XBCRYPT_BIN --encrypt-algo='$ealgo' --encrypt-key='$ekey'" wsrep_log_error "Unknown encryption format='$eformat'"
exit 2
fi fi
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
ecmd="$ecmd -d" ecmd="$ecmd -d"
fi fi
stagemsg+="-XB-Encrypted" stagemsg="$stagemsg-XB-Encrypted"
} }
get_transfer() get_transfer()
...@@ -179,27 +213,27 @@ get_transfer() ...@@ -179,27 +213,27 @@ get_transfer()
TSST_PORT="$SST_PORT" TSST_PORT="$SST_PORT"
if [ $tfmt = 'nc' ]; then if [ $tfmt = 'nc' ]; then
wsrep_check_programs nc
wsrep_log_info "Using netcat as streamer" wsrep_log_info "Using netcat as streamer"
wsrep_check_programs nc
tcmd="nc"
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
if nc -h 2>&1 | grep -q ncat; then if nc -h 2>&1 | grep -q 'ncat'; then
# Ncat wsrep_log_info "Using Ncat as streamer"
tcmd="nc -l $TSST_PORT" tcmd="$tcmd -l"
elif nc -h 2>&1 | grep -qw -- '-d\>'; then elif nc -h 2>&1 | grep -qw -- '-d'; then
# Debian netcat wsrep_log_info "Using Debian netcat as streamer"
tcmd="$tcmd -dl"
if [ $WSREP_SST_OPT_HOST_IPv6 -eq 1 ]; then if [ $WSREP_SST_OPT_HOST_IPv6 -eq 1 ]; then
# When host is not explicitly specified (when only the port # When host is not explicitly specified (when only the port
# is specified) netcat can only bind to an IPv4 address if # is specified) netcat can only bind to an IPv4 address if
# the "-6" option is not explicitly specified: # the "-6" option is not explicitly specified:
tcmd="nc -dl -6 $TSST_PORT" tcmd="$tcmd -6"
else
tcmd="nc -dl $TSST_PORT"
fi fi
else else
# traditional netcat wsrep_log_info "Using traditional netcat as streamer"
tcmd="nc -l -p $TSST_PORT" tcmd="$tcmd -l -p"
fi fi
tcmd="$tcmd $TSST_PORT"
else else
# Check to see if netcat supports the '-N' flag. # Check to see if netcat supports the '-N' flag.
# -N Shutdown the network socket after EOF on stdin # -N Shutdown the network socket after EOF on stdin
...@@ -208,33 +242,28 @@ get_transfer() ...@@ -208,33 +242,28 @@ get_transfer()
# transfer and cause the command to timeout. # transfer and cause the command to timeout.
# Older versions of netcat did not need this flag and will # Older versions of netcat did not need this flag and will
# return an error if the flag is used. # return an error if the flag is used.
# if nc -h 2>&1 | grep -qw -- '-N'; then
tcmd_extra="" tcmd="$tcmd -N"
if nc -h 2>&1 | grep -qw -- -N; then
tcmd_extra="-N"
wsrep_log_info "Using nc -N" wsrep_log_info "Using nc -N"
fi fi
# netcat doesn't understand [] around IPv6 address # netcat doesn't understand [] around IPv6 address
if nc -h 2>&1 | grep -q ncat; then if nc -h 2>&1 | grep -q ncat; then
# Ncat
wsrep_log_info "Using Ncat as streamer" wsrep_log_info "Using Ncat as streamer"
tcmd="nc $tcmd_extra $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT" elif nc -h 2>&1 | grep -qw -- '-d'; then
elif nc -h 2>&1 | grep -qw -- '-d\>'; then
# Debian netcat
wsrep_log_info "Using Debian netcat as streamer" wsrep_log_info "Using Debian netcat as streamer"
tcmd="nc $tcmd_extra $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT"
else else
# traditional netcat
wsrep_log_info "Using traditional netcat as streamer" wsrep_log_info "Using traditional netcat as streamer"
tcmd="nc -q0 $tcmd_extra $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT" tcmd="$tcmd -q0"
fi fi
tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT"
fi fi
else else
tfmt='socat' tfmt='socat'
wsrep_check_programs socat
wsrep_log_info "Using socat as streamer" wsrep_log_info "Using socat as streamer"
wsrep_check_programs socat
if [[ $encrypt -eq 2 || $encrypt -eq 3 ]] && ! socat -V | grep -q "WITH_OPENSSL 1";then if [ $encrypt -eq 2 -o $encrypt -eq 3 ] && ! socat -V | grep -q -F 'WITH_OPENSSL 1'; then
wsrep_log_error "Encryption requested, but socat is not OpenSSL enabled (encrypt=$encrypt)" wsrep_log_error "Encryption requested, but socat is not OpenSSL enabled (encrypt=$encrypt)"
exit 2 exit 2
fi fi
...@@ -245,7 +274,7 @@ get_transfer() ...@@ -245,7 +274,7 @@ get_transfer()
wsrep_log_error "Both PEM and CRT files required" wsrep_log_error "Both PEM and CRT files required"
exit 22 exit 22
fi fi
stagemsg+="-OpenSSL-Encrypted-2" stagemsg="$stagemsg-OpenSSL-Encrypted-2"
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
wsrep_log_info "Decrypting with cert=${tpem}, cafile=${tcert}" wsrep_log_info "Decrypting with cert=${tpem}, cafile=${tcert}"
tcmd="socat -u openssl-listen:$TSST_PORT,reuseaddr,cert='$tpem',cafile='$tcert'$sockopt stdio" tcmd="socat -u openssl-listen:$TSST_PORT,reuseaddr,cert='$tpem',cafile='$tcert'$sockopt stdio"
...@@ -259,7 +288,7 @@ get_transfer() ...@@ -259,7 +288,7 @@ get_transfer()
wsrep_log_error "Both certificate and key files required" wsrep_log_error "Both certificate and key files required"
exit 22 exit 22
fi fi
stagemsg+="-OpenSSL-Encrypted-3" stagemsg="$stagemsg-OpenSSL-Encrypted-3"
if [ -z "$tcert" ]; then if [ -z "$tcert" ]; then
# no verification # no verification
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
...@@ -278,6 +307,8 @@ get_transfer() ...@@ -278,6 +307,8 @@ get_transfer()
CN_option="" CN_option=""
if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then
CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'" CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'"
elif is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED"; then
CN_option=',commonname=localhost'
fi fi
wsrep_log_info "Encrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}" 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" tcmd="socat -u stdio openssl-connect:$REMOTEIP:$TSST_PORT,cert='$tpem',key='$tkey',cafile='$tcert'$CN_option$sockopt"
...@@ -297,13 +328,13 @@ get_footprint() ...@@ -297,13 +328,13 @@ get_footprint()
{ {
pushd "$WSREP_SST_OPT_DATA" 1>/dev/null pushd "$WSREP_SST_OPT_DATA" 1>/dev/null
payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c | awk 'END { print $1 }') payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c | awk 'END { print $1 }')
if $MY_PRINT_DEFAULTS xtrabackup | grep -q -- "--compress";then if $MY_PRINT_DEFAULTS xtrabackup | grep -q -- "--compress"; then
# QuickLZ has around 50% compression ratio # QuickLZ has around 50% compression ratio
# When compression/compaction used, the progress is only an approximate. # When compression/compaction used, the progress is only an approximate.
payload=$(( payload*1/2 )) payload=$(( payload*1/2 ))
fi fi
popd 1>/dev/null popd 1>/dev/null
pcmd+=" -s $payload" pcmd="$pcmd -s $payload"
adjust_progress adjust_progress
} }
...@@ -320,9 +351,9 @@ adjust_progress() ...@@ -320,9 +351,9 @@ adjust_progress()
if [ -n "$progress" -a "$progress" != '1' ]; then if [ -n "$progress" -a "$progress" != '1' ]; then
if [ -e "$progress" ]; then if [ -e "$progress" ]; then
pcmd+=" 2>>'$progress'" pcmd="$pcmd 2>>'$progress'"
else else
pcmd+=" 2>'$progress'" pcmd="$pcmd 2>'$progress'"
fi fi
elif [ -z "$progress" -a -n "$rlimit" ]; then elif [ -z "$progress" -a -n "$rlimit" ]; then
# When rlimit is non-zero # When rlimit is non-zero
...@@ -331,25 +362,26 @@ adjust_progress() ...@@ -331,25 +362,26 @@ adjust_progress()
if [ -n "$rlimit" -a "$WSREP_SST_OPT_ROLE" = 'donor' ]; then if [ -n "$rlimit" -a "$WSREP_SST_OPT_ROLE" = 'donor' ]; then
wsrep_log_info "Rate-limiting SST to $rlimit" wsrep_log_info "Rate-limiting SST to $rlimit"
pcmd+=" -L \$rlimit" pcmd="$pcmd -L \$rlimit"
fi fi
} }
encgroups='--mysqld|sst|xtrabackup'
check_server_ssl_config() check_server_ssl_config()
{ {
local section="$1" tcert=$(parse_cnf "$encgroups" 'ssl-ca')
tcert=$(parse_cnf "$section" 'ssl-ca') tpem=$(parse_cnf "$encgroups" 'ssl-cert')
tpem=$(parse_cnf "$section" 'ssl-cert') tkey=$(parse_cnf "$encgroups" 'ssl-key')
tkey=$(parse_cnf "$section" 'ssl-key')
} }
read_cnf() read_cnf()
{ {
sfmt=$(parse_cnf sst streamfmt "mbstream") sfmt=$(parse_cnf sst streamfmt 'mbstream')
tfmt=$(parse_cnf sst transferfmt "socat") tfmt=$(parse_cnf sst transferfmt 'socat')
encrypt=$(parse_cnf 'sst' 'encrypt' 0) encrypt=$(parse_cnf "$encgroups" 'encrypt' 0)
tmode=$(parse_cnf 'sst' 'ssl-mode' 'DISABLED' | tr [:lower:] [:upper:]) tmode=$(parse_cnf "$encgroups" 'ssl-mode' 'DISABLED' | tr [:lower:] [:upper:])
if [ $encrypt -eq 0 -o $encrypt -ge 2 ] if [ $encrypt -eq 0 -o $encrypt -ge 2 ]
then then
...@@ -363,11 +395,7 @@ read_cnf() ...@@ -363,11 +395,7 @@ read_cnf()
then # backward-incompatible behavior then # backward-incompatible behavior
if [ -z "$tpem" -a -z "$tkey" -a -z "$tcert" ] if [ -z "$tpem" -a -z "$tkey" -a -z "$tcert" ]
then # no old-style SSL config in [sst] then # no old-style SSL config in [sst]
check_server_ssl_config 'sst' check_server_ssl_config
if [ -z "$tpem" -a -z "$tkey" -a -z "$tcert" ]
then # no new-stype SSL config in [sst], try server-wide SSL config
check_server_ssl_config '--mysqld'
fi
fi fi
if [ 0 -eq $encrypt -a -n "$tpem" -a -n "$tkey" ] if [ 0 -eq $encrypt -a -n "$tpem" -a -n "$tkey" ]
then then
...@@ -380,29 +408,21 @@ read_cnf() ...@@ -380,29 +408,21 @@ read_cnf()
[ "${tmode#VERIFY}" != "$tmode" ] || tcert="" [ "${tmode#VERIFY}" != "$tmode" ] || tcert=""
fi fi
fi fi
elif [ $encrypt -eq 1 ]; then
ealgo=$(parse_cnf "$encgroups" 'encrypt-algo')
eformat=$(parse_cnf "$encgroups" 'encrypt-format' 'openssl')
ekey=$(parse_cnf "$encgroups" 'encrypt-key')
ekeyfile=$(parse_cnf "$encgroups" 'encrypt-key-file')
fi fi
if [ $encrypt -eq 1 ]; then wsrep_log_info "SSL configuration: CA='$tcert', CERT='$tpem'," \
# Refer to http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html "KEY='$tkey', MODE='$tmode', encrypt='$encrypt'"
ealgo=$(parse_cnf xtrabackup encrypt "")
if [ -z "$ealgo" ]; then
ealgo=$(parse_cnf sst encrypt-algo "")
ekey=$(parse_cnf sst encrypt-key "")
ekeyfile=$(parse_cnf sst encrypt-key-file "")
else
ekey=$(parse_cnf xtrabackup encrypt-key "")
ekeyfile=$(parse_cnf xtrabackup encrypt-key-file "")
fi
fi
wsrep_log_info "SSL configuration: CA='"$tcert"', CERT='"$tpem"'," \
"KEY='"$tkey"', MODE='"$tmode"', encrypt="$encrypt
sockopt=$(parse_cnf sst sockopt "") sockopt=$(parse_cnf sst sockopt "")
progress=$(parse_cnf sst progress "") progress=$(parse_cnf sst progress "")
ttime=$(parse_cnf sst time 0) ttime=$(parse_cnf sst time 0)
cpat=$(parse_cnf sst cpat '.*galera\.cache$\|.*sst_in_progress$\|.*\.sst$\|.*gvwstate\.dat$\|.*grastate\.dat$\|.*\.err$\|.*\.log$\|.*RPM_UPGRADE_MARKER$\|.*RPM_UPGRADE_HISTORY$') cpat=$(parse_cnf sst cpat '.*galera\.cache$\|.*sst_in_progress$\|.*\.sst$\|.*gvwstate\.dat$\|.*grastate\.dat$\|.*\.err$\|.*\.log$\|.*RPM_UPGRADE_MARKER$\|.*RPM_UPGRADE_HISTORY$')
[[ $OS == "FreeBSD" ]] && cpat=$(parse_cnf sst cpat '.*galera\.cache$|.*sst_in_progress$|.*\.sst$|.*gvwstate\.dat$|.*grastate\.dat$|.*\.err$|.*\.log$|.*RPM_UPGRADE_MARKER$|.*RPM_UPGRADE_HISTORY$') [ $OS = 'FreeBSD' ] && cpat=$(parse_cnf sst cpat '.*galera\.cache$|.*sst_in_progress$|.*\.sst$|.*gvwstate\.dat$|.*grastate\.dat$|.*\.err$|.*\.log$|.*RPM_UPGRADE_MARKER$|.*RPM_UPGRADE_HISTORY$')
scomp=$(parse_cnf sst compressor "") scomp=$(parse_cnf sst compressor "")
sdecomp=$(parse_cnf sst decompressor "") sdecomp=$(parse_cnf sst decompressor "")
...@@ -415,26 +435,20 @@ read_cnf() ...@@ -415,26 +435,20 @@ read_cnf()
stimeout=$(parse_cnf sst sst-initial-timeout 300) stimeout=$(parse_cnf sst sst-initial-timeout 300)
ssyslog=$(parse_cnf sst sst-syslog 0) ssyslog=$(parse_cnf sst sst-syslog 0)
ssystag=$(parse_cnf mysqld_safe syslog-tag "${SST_SYSLOG_TAG:-}") ssystag=$(parse_cnf mysqld_safe syslog-tag "${SST_SYSLOG_TAG:-}")
ssystag+="-" ssystag="$ssystag-"
sstlogarchive=$(parse_cnf sst sst-log-archive 1) sstlogarchive=$(parse_cnf sst sst-log-archive 1)
sstlogarchivedir=$(parse_cnf sst sst-log-archive-dir "/tmp/sst_log_archive") sstlogarchivedir=$(parse_cnf sst sst-log-archive-dir '/tmp/sst_log_archive')
if [[ $speciald -eq 0 ]];then if [ $speciald -eq 0 ]; then
wsrep_log_error "sst-special-dirs equal to 0 is not supported, falling back to 1" wsrep_log_error "sst-special-dirs equal to 0 is not supported, falling back to 1"
speciald=1 speciald=1
fi fi
if [[ $ssyslog -ne -1 ]];then if [ $ssyslog -ne -1 ]; then
if $MY_PRINT_DEFAULTS mysqld_safe | grep -q -- "--syslog";then if $MY_PRINT_DEFAULTS mysqld_safe | grep -q -- "--syslog"; then
ssyslog=1 ssyslog=1
fi fi
fi fi
if [[ $encrypt -eq 1 ]]; then
wsrep_log_error "Xtrabackup-based encryption is currently not" \
"supported with MariaBackup"
exit 2
fi
} }
get_stream() get_stream()
...@@ -461,7 +475,7 @@ get_proc() ...@@ -461,7 +475,7 @@ get_proc()
{ {
set +e set +e
nproc=$(grep -c processor /proc/cpuinfo) nproc=$(grep -c processor /proc/cpuinfo)
[[ -z $nproc || $nproc -eq 0 ]] && nproc=1 [ -z $nproc -o $nproc -eq 0 ] && nproc=1
set -e set -e
} }
...@@ -477,7 +491,7 @@ cleanup_joiner() ...@@ -477,7 +491,7 @@ cleanup_joiner()
local estatus=$? local estatus=$?
if [ $estatus -ne 0 ]; then if [ $estatus -ne 0 ]; then
wsrep_log_error "Cleanup after exit with status:$estatus" wsrep_log_error "Cleanup after exit with status:$estatus"
elif [ "${WSREP_SST_OPT_ROLE}" = 'joiner' ]; then elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
wsrep_log_info "Removing the sst_in_progress file" wsrep_log_info "Removing the sst_in_progress file"
wsrep_cleanup_progress_file wsrep_cleanup_progress_file
fi fi
...@@ -495,10 +509,10 @@ cleanup_joiner() ...@@ -495,10 +509,10 @@ cleanup_joiner()
# This means no setsid done in mysqld. # This means no setsid done in mysqld.
# We don't want to kill mysqld here otherwise. # We don't want to kill mysqld here otherwise.
if [[ $$ -eq $pgid ]];then if [ $$ -eq $pgid ]; then
# This means a signal was delivered to the process. # This means a signal was delivered to the process.
# So, more cleanup. # So, more cleanup.
if [[ $estatus -ge 128 ]];then if [ $estatus -ge 128 ]; then
kill -KILL -$$ || true kill -KILL -$$ || true
fi fi
fi fi
...@@ -509,7 +523,7 @@ cleanup_joiner() ...@@ -509,7 +523,7 @@ cleanup_joiner()
check_pid() check_pid()
{ {
local pid_file="$1" local pid_file="$1"
[ -r "$pid_file" ] && ps -p $(cat "$pid_file") >/dev/null 2>&1 [ -r "$pid_file" ] && ps -p $(cat "$pid_file") 2>&1 >/dev/null
} }
cleanup_donor() cleanup_donor()
...@@ -520,11 +534,11 @@ cleanup_donor() ...@@ -520,11 +534,11 @@ cleanup_donor()
wsrep_log_error "Cleanup after exit with status:$estatus" wsrep_log_error "Cleanup after exit with status:$estatus"
fi fi
if [ -n "$XTRABACKUP_PID" ]; then if [ -n "$MARIABACKUP_PID" ]; then
if check_pid $XTRABACKUP_PID if check_pid $MARIABACKUP_PID
then then
wsrep_log_error "xtrabackup process is still running. Killing..." wsrep_log_error "mariabackup process is still running. Killing..."
kill_xtrabackup kill_mariabackup
fi fi
fi fi
...@@ -550,10 +564,10 @@ cleanup_donor() ...@@ -550,10 +564,10 @@ cleanup_donor()
# This means no setsid done in mysqld. # This means no setsid done in mysqld.
# We don't want to kill mysqld here otherwise. # We don't want to kill mysqld here otherwise.
if [[ $$ -eq $pgid ]];then if [ $$ -eq $pgid ]; then
# This means a signal was delivered to the process. # This means a signal was delivered to the process.
# So, more cleanup. # So, more cleanup.
if [[ $estatus -ge 128 ]];then if [ $estatus -ge 128 ]; then
kill -KILL -$$ || true kill -KILL -$$ || true
fi fi
fi fi
...@@ -561,24 +575,57 @@ cleanup_donor() ...@@ -561,24 +575,57 @@ cleanup_donor()
exit $estatus exit $estatus
} }
kill_xtrabackup() kill_mariabackup()
{ {
local PID=$(cat "$XTRABACKUP_PID") local PID=$(cat "$MARIABACKUP_PID")
[ -n "$PID" -a "0" != "$PID" ] && kill $PID && (kill $PID && kill -9 $PID) || : [ -n "$PID" -a "0" != "$PID" ] && kill $PID && (kill $PID && kill -9 $PID) || :
wsrep_log_info "Removing xtrabackup pid file $XTRABACKUP_PID" wsrep_log_info "Removing mariabackup pid file ($MARIABACKUP_PID)"
rm -f "$XTRABACKUP_PID" || true rm -f "$MARIABACKUP_PID" || true
} }
setup_ports() setup_ports()
{ {
SST_PORT="$WSREP_SST_OPT_PORT" SST_PORT="$WSREP_SST_OPT_PORT"
if [ "$WSREP_SST_OPT_ROLE" = "donor" ]; then if [ "$WSREP_SST_OPT_ROLE" = 'donor' ]; then
REMOTEIP="${WSREP_SST_OPT_HOST}" REMOTEIP="$WSREP_SST_OPT_HOST"
lsn="${WSREP_SST_OPT_LSN}" lsn="$WSREP_SST_OPT_LSN"
sst_ver="${WSREP_SST_OPT_SST_VER}" sst_ver="$WSREP_SST_OPT_SST_VER"
fi 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 # waits ~10 seconds for nc to open the port and then reports ready
# (regardless of timeout) # (regardless of timeout)
wait_for_listen() wait_for_listen()
...@@ -586,16 +633,16 @@ wait_for_listen() ...@@ -586,16 +633,16 @@ wait_for_listen()
local PORT="$1" local PORT="$1"
local ADDR="$2" local ADDR="$2"
local MODULE="$3" local MODULE="$3"
for i in {1..50} for i in {1..50}
do do
if [ "$OS" = "FreeBSD" ];then if check_port "$PORT" 'socat|nc'
sockstat -46lp $PORT | grep -qE "^[^ ]* *(socat|nc) *[^ ]* *[^ ]* *[^ ]* *[^ ]*:$PORT" && break then
else break
ss -p state listening "( sport = :$PORT )" | grep -qE 'socat|nc' && break
fi fi
sleep 0.2 sleep 0.2
done done
echo "ready ${ADDR}/${MODULE}//$sst_ver" echo "ready $ADDR/$MODULE//$sst_ver"
} }
check_extra() check_extra()
...@@ -606,10 +653,10 @@ check_extra() ...@@ -606,10 +653,10 @@ check_extra()
if [ "$thread_handling" = 'pool-of-threads' ]; then if [ "$thread_handling" = 'pool-of-threads' ]; then
local eport=$(parse_cnf '--mysqld' 'extra-port') local eport=$(parse_cnf '--mysqld' 'extra-port')
if [ -n "$eport" ]; then if [ -n "$eport" ]; then
# Xtrabackup works only locally. # mariabackup works only locally, hence,
# Hence, setting host to 127.0.0.1 unconditionally. # setting host to 127.0.0.1 unconditionally:
wsrep_log_info "SST through extra_port $eport" wsrep_log_info "SST through extra_port $eport"
INNOEXTRA+=" --host=127.0.0.1 --port=$eport" INNOEXTRA="$INNOEXTRA --host=127.0.0.1 --port=$eport"
use_socket=0 use_socket=0
else else
wsrep_log_error "Extra port $eport null, failing" wsrep_log_error "Extra port $eport null, failing"
...@@ -620,7 +667,7 @@ check_extra() ...@@ -620,7 +667,7 @@ check_extra()
fi fi
fi fi
if [ $use_socket -eq 1 -a -n "$WSREP_SST_OPT_SOCKET" ]; then if [ $use_socket -eq 1 -a -n "$WSREP_SST_OPT_SOCKET" ]; then
INNOEXTRA+=" --socket='$WSREP_SST_OPT_SOCKET'" INNOEXTRA="$INNOEXTRA --socket='$WSREP_SST_OPT_SOCKET'"
fi fi
} }
...@@ -630,7 +677,7 @@ recv_joiner() ...@@ -630,7 +677,7 @@ recv_joiner()
local msg="$2" local msg="$2"
local tmt=$3 local tmt=$3
local checkf=$4 local checkf=$4
local ltcmd local wait=$5
if [ ! -d "$dir" ]; then if [ ! -d "$dir" ]; then
# This indicates that IST is in progress # This indicates that IST is in progress
...@@ -640,28 +687,34 @@ recv_joiner() ...@@ -640,28 +687,34 @@ recv_joiner()
pushd "$dir" 1>/dev/null pushd "$dir" 1>/dev/null
set +e set +e
if [ $tmt -gt 0 -a -x "$(command -v timeout)" ]; then local ltcmd="$tcmd"
if timeout --help | grep -q -- '-k'; then if [ $tmt -gt 0 ]; then
ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd" if [ -x "$(command -v timeout)" ]; then
else if timeout --help | grep -qw -- '-k'; then
ltcmd="timeout -s9 $tmt $tcmd" ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd"
else
ltcmd="timeout -s9 $tmt $tcmd"
fi
fi fi
timeit "$msg" "$ltcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )"
else
timeit "$msg" "$tcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )"
fi fi
if [ $wait -ne 0 ]; then
wait_for_listen "$SST_PORT" "$ADDR" "$MODULE" &
fi
timeit "$msg" "$ltcmd | $strmcmd; RC=( "\${PIPESTATUS[@]}" )"
set -e set -e
popd 1>/dev/null popd 1>/dev/null
if [[ ${RC[0]} -eq 124 ]];then if [ ${RC[0]} -eq 124 ]; then
wsrep_log_error "Possible timeout in receiving first data from " \ wsrep_log_error "Possible timeout in receiving first data from " \
"donor in gtid stage: exit codes: ${RC[@]}" "donor in gtid stage: exit codes: ${RC[@]}"
exit 32 exit 32
fi fi
for ecode in "${RC[@]}";do for ecode in "${RC[@]}"; do
if [[ $ecode -ne 0 ]];then if [ $ecode -ne 0 ]; then
wsrep_log_error "Error while getting data from donor node: " \ wsrep_log_error "Error while getting data from donor node: " \
"exit codes: ${RC[@]}" "exit codes: ${RC[@]}"
exit 32 exit 32
...@@ -672,14 +725,14 @@ recv_joiner() ...@@ -672,14 +725,14 @@ recv_joiner()
if [ ! -r "$MAGIC_FILE" ]; then if [ ! -r "$MAGIC_FILE" ]; then
# this message should cause joiner to abort # this message should cause joiner to abort
wsrep_log_error "receiving process ended without creating " \ wsrep_log_error "receiving process ended without creating " \
"'${MAGIC_FILE}'" "'$MAGIC_FILE'"
wsrep_log_info "Contents of datadir" wsrep_log_info "Contents of datadir"
wsrep_log_info "$(ls -l ${dir}/*)" wsrep_log_info $(ls -l "$dir/"*)
exit 32 exit 32
fi fi
# check donor supplied secret # check donor supplied secret
SECRET=$(grep "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2) SECRET=$(grep -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2)
if [ "$SECRET" != "$MY_SECRET" ]; then if [ "$SECRET" != "$MY_SECRET" ]; then
wsrep_log_error "Donor does not know my secret!" wsrep_log_error "Donor does not know my secret!"
wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'" wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'"
...@@ -687,7 +740,7 @@ recv_joiner() ...@@ -687,7 +740,7 @@ recv_joiner()
fi fi
# remove secret from magic file # remove secret from magic file
grep -v "$SECRET_TAG " "$MAGIC_FILE" > "$MAGIC_FILE.new" grep -v -- "$SECRET_TAG " "$MAGIC_FILE" > "$MAGIC_FILE.new"
mv "$MAGIC_FILE.new" "$MAGIC_FILE" mv "$MAGIC_FILE.new" "$MAGIC_FILE"
fi fi
} }
...@@ -703,8 +756,8 @@ send_donor() ...@@ -703,8 +756,8 @@ send_donor()
set -e set -e
popd 1>/dev/null popd 1>/dev/null
for ecode in "${RC[@]}";do for ecode in "${RC[@]}"; do
if [[ $ecode -ne 0 ]];then if [ $ecode -ne 0 ]; then
wsrep_log_error "Error while sending data to joiner node: " \ wsrep_log_error "Error while sending data to joiner node: " \
"exit codes: ${RC[@]}" "exit codes: ${RC[@]}"
exit 32 exit 32
...@@ -717,11 +770,11 @@ monitor_process() ...@@ -717,11 +770,11 @@ monitor_process()
local sst_stream_pid=$1 local sst_stream_pid=$1
while true ; do while true ; do
if ! ps -p "${WSREP_SST_OPT_PARENT}" &>/dev/null; then if ! ps -p "$WSREP_SST_OPT_PARENT" &>/dev/null; then
wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly." wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly."
exit 32 exit 32
fi fi
if ! ps -p "${sst_stream_pid}" &>/dev/null; then if ! ps -p "$sst_stream_pid" &>/dev/null; then
break break
fi fi
sleep 0.1 sleep 0.1
...@@ -730,7 +783,7 @@ monitor_process() ...@@ -730,7 +783,7 @@ monitor_process()
wsrep_check_programs "$MARIABACKUP_BIN" wsrep_check_programs "$MARIABACKUP_BIN"
rm -f "${MAGIC_FILE}" rm -f "$MAGIC_FILE"
if [ "$WSREP_SST_OPT_ROLE" != 'joiner' -a "$WSREP_SST_OPT_ROLE" != 'donor' ]; then 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}"
...@@ -740,15 +793,15 @@ fi ...@@ -740,15 +793,15 @@ fi
read_cnf read_cnf
setup_ports setup_ports
if "${MARIABACKUP_BIN}" --help 2>/dev/null | grep -q -- '--version-check'; then if "$MARIABACKUP_BIN" --help 2>/dev/null | grep -qw -- '--version-check'; then
disver='--no-version-check' disver='--no-version-check'
fi fi
iopts+=" --databases-exclude='lost+found'" iopts="$iopts --databases-exclude='lost+found'"
if [ ${FORCE_FTWRL:-0} -eq 1 ]; then if [ ${FORCE_FTWRL:-0} -eq 1 ]; then
wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL" wsrep_log_info "Forcing FTWRL due to environment variable FORCE_FTWRL equal to $FORCE_FTWRL"
iopts+=' --no-backup-locks' iopts="$iopts --no-backup-locks"
fi fi
# if no command line argument and INNODB_DATA_HOME_DIR environment variable # if no command line argument and INNODB_DATA_HOME_DIR environment variable
...@@ -769,11 +822,9 @@ fi ...@@ -769,11 +822,9 @@ fi
cd "$OLD_PWD" cd "$OLD_PWD"
if [[ $ssyslog -eq 1 ]];then if [ $ssyslog -eq 1 ]; then
if [ ! -x "$(command -v logger)" ]; then if [ -x "$(command -v logger)" ]; then
wsrep_log_error "logger not in path: $PATH. Ignoring"
else
wsrep_log_info "Logging all stderr of SST/mariabackup to syslog" wsrep_log_info "Logging all stderr of SST/mariabackup to syslog"
exec 2> >(logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE) exec 2> >(logger -p daemon.err -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE)
...@@ -787,6 +838,8 @@ if [[ $ssyslog -eq 1 ]];then ...@@ -787,6 +838,8 @@ if [[ $ssyslog -eq 1 ]];then
{ {
logger -p daemon.info -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@" logger -p daemon.info -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@"
} }
else
wsrep_log_error "logger not in path: $PATH. Ignoring"
fi fi
INNOAPPLY="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply" INNOAPPLY="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply"
...@@ -795,10 +848,9 @@ if [[ $ssyslog -eq 1 ]];then ...@@ -795,10 +848,9 @@ if [[ $ssyslog -eq 1 ]];then
else else
if [[ "$sstlogarchive" -eq 1 ]] if [ $sstlogarchive -eq 1 ]
then then
ARCHIVETIMESTAMP=$(date "+%Y.%m.%d-%H.%M.%S.%N") ARCHIVETIMESTAMP=$(date "+%Y.%m.%d-%H.%M.%S.%N")
newfile=""
if [ -n "$sstlogarchivedir" ] if [ -n "$sstlogarchivedir" ]
then then
...@@ -812,11 +864,12 @@ then ...@@ -812,11 +864,12 @@ then
then then
if [ -n "$sstlogarchivedir" ] if [ -n "$sstlogarchivedir" ]
then then
newfile="$sstlogarchivedir/$(basename '$INNOAPPLYLOG').$ARCHIVETIMESTAMP" newfile=$(basename "$INNOAPPLYLOG")
newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
else else
newfile="$INNOAPPLYLOG.$ARCHIVETIMESTAMP" newfile="$INNOAPPLYLOG.$ARCHIVETIMESTAMP"
fi fi
wsrep_log_info "Moving ${INNOAPPLYLOG} to ${newfile}" wsrep_log_info "Moving '$INNOAPPLYLOG' to '$newfile'"
mv "$INNOAPPLYLOG" "$newfile" mv "$INNOAPPLYLOG" "$newfile"
gzip "$newfile" gzip "$newfile"
fi fi
...@@ -825,11 +878,12 @@ then ...@@ -825,11 +878,12 @@ then
then then
if [ -n "$sstlogarchivedir" ] if [ -n "$sstlogarchivedir" ]
then then
newfile="$sstlogarchivedir/$(basename '$INNOMOVELOG').$ARCHIVETIMESTAMP" newfile=$(basename "$INNOMOVELOG")
newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
else else
newfile="$INNOMOVELOG.$ARCHIVETIMESTAMP" newfile="$INNOMOVELOG.$ARCHIVETIMESTAMP"
fi fi
wsrep_log_info "Moving ${INNOMOVELOG} to ${newfile}" wsrep_log_info "Moving '$INNOMOVELOG' to '$newfile'"
mv "$INNOMOVELOG" "$newfile" mv "$INNOMOVELOG" "$newfile"
gzip "$newfile" gzip "$newfile"
fi fi
...@@ -838,11 +892,12 @@ then ...@@ -838,11 +892,12 @@ then
then then
if [ -n "$sstlogarchivedir" ] if [ -n "$sstlogarchivedir" ]
then then
newfile="$sstlogarchivedir/$(basename '$INNOBACKUPLOG').$ARCHIVETIMESTAMP" newfile=$(basename "$INNOBACKUPLOG")
newfile="$sstlogarchivedir/$newfile.$ARCHIVETIMESTAMP"
else else
newfile="$INNOBACKUPLOG.$ARCHIVETIMESTAMP" newfile="$INNOBACKUPLOG.$ARCHIVETIMESTAMP"
fi fi
wsrep_log_info "Moving ${INNOBACKUPLOG} to ${newfile}" wsrep_log_info "Moving '$INNOBACKUPLOG' to '$newfile'"
mv "$INNOBACKUPLOG" "$newfile" mv "$INNOBACKUPLOG" "$newfile"
gzip "$newfile" gzip "$newfile"
fi fi
...@@ -868,7 +923,7 @@ setup_commands() ...@@ -868,7 +923,7 @@ setup_commands()
get_stream get_stream
get_transfer get_transfer
if [ "$WSREP_SST_OPT_ROLE" = "donor" ] if [ "$WSREP_SST_OPT_ROLE" = 'donor' ]
then then
trap cleanup_donor EXIT trap cleanup_donor EXIT
...@@ -881,18 +936,18 @@ then ...@@ -881,18 +936,18 @@ then
exit 93 exit 93
fi fi
if [ -z "$(parse_cnf --mysqld tmpdir)" -a \ tmpdir=$(parse_cnf "$encgroups" 'tmpdir')
-z "$(parse_cnf xtrabackup tmpdir)" ]; then if [ -z "$tmpdir" ]; then
xtmpdir=$(mktemp -d) xtmpdir="$(mktemp -d)"
tmpopts="--tmpdir='$xtmpdir'" tmpopts="--tmpdir='$xtmpdir'"
wsrep_log_info "Using $xtmpdir as xtrabackup temporary directory" wsrep_log_info "Using $xtmpdir as mariabackup temporary directory"
fi fi
itmpdir=$(mktemp -d) itmpdir="$(mktemp -d)"
wsrep_log_info "Using $itmpdir as mariabackup temporary directory" wsrep_log_info "Using $itmpdir as mariabackup temporary directory"
if [ -n "$WSREP_SST_OPT_USER" ]; then if [ -n "$WSREP_SST_OPT_USER" ]; then
INNOEXTRA+=" --user='$WSREP_SST_OPT_USER'" INNOEXTRA="$INNOEXTRA --user='$WSREP_SST_OPT_USER'"
usrst=1 usrst=1
fi fi
...@@ -927,10 +982,11 @@ then ...@@ -927,10 +982,11 @@ then
tcmd="$ecmd | $tcmd" tcmd="$ecmd | $tcmd"
fi fi
send_donor "$DATA" "${stagemsg}-gtid" send_donor "$DATA" "$stagemsg-gtid"
tcmd="$ttcmd" tcmd="$ttcmd"
# Restore the transport commmand to its original state
if [ -n "$progress" ]; then if [ -n "$progress" ]; then
get_footprint get_footprint
tcmd="$pcmd | $tcmd" tcmd="$pcmd | $tcmd"
...@@ -944,26 +1000,32 @@ then ...@@ -944,26 +1000,32 @@ then
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 if [ -n "$scomp" ]; then
tcmd="$scomp | $tcmd" tcmd="$scomp | $tcmd"
fi fi
# Add encryption to the head of the stream (if specified)
if [ $encrypt -eq 1 ]; then
tcmd="$ecmd | $tcmd"
fi
setup_commands setup_commands
set +e set +e
timeit "${stagemsg}-SST" "$INNOBACKUP | $tcmd; RC=( "\${PIPESTATUS[@]}" )" timeit "$stagemsg-SST" "$INNOBACKUP | $tcmd; RC=( "\${PIPESTATUS[@]}" )"
set -e set -e
if [ ${RC[0]} -ne 0 ]; then if [ ${RC[0]} -ne 0 ]; then
wsrep_log_error "${MARIABACKUP_BIN} finished with error: ${RC[0]}. " \ wsrep_log_error "${MARIABACKUP_BIN} finished with error: ${RC[0]}. " \
"Check syslog or ${INNOBACKUPLOG} for details" "Check syslog or ${INNOBACKUPLOG} for details"
exit 22 exit 22
elif [[ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]]; then elif [ ${RC[$(( ${#RC[@]}-1 ))]} -eq 1 ]; then
wsrep_log_error "$tcmd finished with error: ${RC[1]}" wsrep_log_error "$tcmd finished with error: ${RC[1]}"
exit 22 exit 22
fi fi
# mariabackup implicitly writes PID to fixed location in $xtmpdir # mariabackup implicitly writes PID to fixed location in $xtmpdir
XTRABACKUP_PID="$xtmpdir/xtrabackup_pid" MARIABACKUP_PID="$xtmpdir/xtrabackup_pid"
else # BYPASS FOR IST else # BYPASS FOR IST
...@@ -984,19 +1046,19 @@ then ...@@ -984,19 +1046,19 @@ then
tcmd="$ecmd | $tcmd" tcmd="$ecmd | $tcmd"
fi fi
strmcmd+=" '$IST_FILE'" strmcmd="$strmcmd '$IST_FILE'"
send_donor "$DATA" "${stagemsg}-IST" send_donor "$DATA" "$stagemsg-IST"
fi fi
echo "done ${WSREP_SST_OPT_GTID}" echo "done $WSREP_SST_OPT_GTID"
wsrep_log_info "Total time on donor: $totime seconds" wsrep_log_info "Total time on donor: $totime seconds"
elif [ "${WSREP_SST_OPT_ROLE}" = "joiner" ] elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]
then then
[[ -e "$SST_PROGRESS_FILE" ]] && wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE" [ -e "$SST_PROGRESS_FILE" ] && wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE"
[[ -n "$SST_PROGRESS_FILE" ]] && touch "$SST_PROGRESS_FILE" [ -n "$SST_PROGRESS_FILE" ] && touch "$SST_PROGRESS_FILE"
ib_home_dir="$INNODB_DATA_HOME_DIR" ib_home_dir="$INNODB_DATA_HOME_DIR"
...@@ -1015,7 +1077,7 @@ then ...@@ -1015,7 +1077,7 @@ then
ib_undo_dir="$INNODB_UNDO_DIR" ib_undo_dir="$INNODB_UNDO_DIR"
stagemsg="Joiner-Recv" stagemsg='Joiner-Recv'
sencrypted=1 sencrypted=1
nthreads=1 nthreads=1
...@@ -1041,42 +1103,41 @@ then ...@@ -1041,42 +1103,41 @@ then
exit 42 exit 42
fi fi
CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$tpem" | \ CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$tpem" | \
tr "," "\n" | grep "CN =" | cut -d= -f2 | sed s/^\ // | \ tr "," "\n" | grep -F 'CN =' | cut -d= -f2 | sed s/^\ // | \
sed s/\ %//) sed s/\ %//)
fi fi
MY_SECRET=$(wsrep_gen_secret) MY_SECRET="$(wsrep_gen_secret)"
# Add authentication data to address # Add authentication data to address
ADDR="$CN:$MY_SECRET@$ADDR" ADDR="$CN:$MY_SECRET@$ADDR"
else else
MY_SECRET="" # for check down in recv_joiner() MY_SECRET="" # for check down in recv_joiner()
fi fi
wait_for_listen "$SST_PORT" "$ADDR" "$MODULE" &
trap sig_joiner_cleanup HUP PIPE INT TERM trap sig_joiner_cleanup HUP PIPE INT TERM
trap cleanup_joiner EXIT trap cleanup_joiner EXIT
if [ -n "$progress" ]; then if [ -n "$progress" ]; then
adjust_progress adjust_progress
tcmd+=" | $pcmd" tcmd="$tcmd | $pcmd"
fi fi
get_keys get_keys
if [ $encrypt -eq 1 -a $sencrypted -eq 1 ]; then if [ $encrypt -eq 1 -a $sencrypted -eq 1 ]; then
if [ -n "$sdecomp" ]; then strmcmd="$ecmd | $strmcmd"
strmcmd="$sdecomp | $ecmd | $strmcmd" fi
else
strmcmd="$ecmd | $strmcmd" if [ -n "$sdecomp" ]; then
fi strmcmd="$sdecomp | $strmcmd"
elif [ -n "$sdecomp" ]; then
strmcmd="$sdecomp | $strmcmd"
fi fi
STATDIR=$(mktemp -d) check_sockets_utils
STATDIR="$(mktemp -d)"
MAGIC_FILE="$STATDIR/$INFO_FILE" MAGIC_FILE="$STATDIR/$INFO_FILE"
recv_joiner "$STATDIR" "${stagemsg}-gtid" $stimeout 1
if ! ps -p ${WSREP_SST_OPT_PARENT} &>/dev/null recv_joiner "$STATDIR" "$stagemsg-gtid" $stimeout 1 1
if ! ps -p "$WSREP_SST_OPT_PARENT" &>/dev/null
then then
wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly." wsrep_log_error "Parent mysqld process (PID:${WSREP_SST_OPT_PARENT}) terminated unexpectedly."
exit 32 exit 32
...@@ -1090,12 +1151,12 @@ then ...@@ -1090,12 +1151,12 @@ then
rm -rf "$DATA/.sst" rm -rf "$DATA/.sst"
fi fi
mkdir -p "$DATA/.sst" mkdir -p "$DATA/.sst"
(recv_joiner "$DATA/.sst" "${stagemsg}-SST" 0 0) & (recv_joiner "$DATA/.sst" "$stagemsg-SST" 0 0 0) &
jpid=$! jpid=$!
wsrep_log_info "Proceeding with SST" wsrep_log_info "Proceeding with SST"
wsrep_log_info "Cleaning the existing datadir and innodb-data/log directories" wsrep_log_info "Cleaning the existing datadir and innodb-data/log directories"
if [ "${OS}" = "FreeBSD" ]; then if [ "$OS" = 'FreeBSD' ]; then
find -E ${ib_home_dir:+"$ib_home_dir"} \ find -E ${ib_home_dir:+"$ib_home_dir"} \
${ib_undo_dir:+"$ib_undo_dir"} \ ${ib_undo_dir:+"$ib_undo_dir"} \
${ib_log_dir:+"$ib_log_dir"} \ ${ib_log_dir:+"$ib_log_dir"} \
...@@ -1128,13 +1189,13 @@ then ...@@ -1128,13 +1189,13 @@ then
get_proc get_proc
if [[ ! -s "$DATA/xtrabackup_checkpoints" ]];then if [ ! -s "$DATA/xtrabackup_checkpoints" ]; then
wsrep_log_error "xtrabackup_checkpoints missing, failed mariabackup/SST on donor" wsrep_log_error "xtrabackup_checkpoints missing, failed mariabackup/SST on donor"
exit 2 exit 2
fi fi
# Compact backups are not supported by mariabackup # Compact backups are not supported by mariabackup
if grep -q 'compact = 1' "$DATA/xtrabackup_checkpoints"; then if grep -q -F 'compact = 1' "$DATA/xtrabackup_checkpoints"; then
wsrep_log_info "Index compaction detected" wsrep_log_info "Index compaction detected"
wsrel_log_error "Compact backups are not supported by mariabackup" wsrel_log_error "Compact backups are not supported by mariabackup"
exit 2 exit 2
...@@ -1149,13 +1210,12 @@ then ...@@ -1149,13 +1210,12 @@ then
exit 22 exit 22
fi fi
if [[ -n "$progress" ]] && pv --help | grep -q 'line-mode';then if [ -n "$progress" ] && pv --help | grep -qw -- '--line-mode'; then
count=$(find "$DATA" -type f -name '*.qp' | wc -l) count=$(find "$DATA" -type f -name '*.qp' | wc -l)
count=$(( count*2 )) count=$(( count*2 ))
if pv --help | grep -q FORMAT;then pvopts="-f -s $count -l -N Decompression"
pvopts="-f -s $count -l -N Decompression -F '%N => Rate:%r Elapsed:%t %e Progress: [%b/$count]'" if pv --help | grep -qw -- '-F'; then
else pvopts="$pvopts -F '%N => Rate:%r Elapsed:%t %e Progress: [%b/$count]'"
pvopts="-f -s $count -l -N Decompression"
fi fi
pcmd="pv $pvopts" pcmd="pv $pvopts"
adjust_progress adjust_progress
...@@ -1169,10 +1229,10 @@ then ...@@ -1169,10 +1229,10 @@ then
timeit "Joiner-Decompression" "find '$DATA' -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd" timeit "Joiner-Decompression" "find '$DATA' -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd"
extcode=$? extcode=$?
if [[ $extcode -eq 0 ]];then if [ $extcode -eq 0 ]; then
wsrep_log_info "Removing qpress files after decompression" wsrep_log_info "Removing qpress files after decompression"
find "$DATA" -type f -name '*.qp' -delete find "$DATA" -type f -name '*.qp' -delete
if [[ $? -ne 0 ]];then if [ $? -ne 0 ]; then
wsrep_log_error "Something went wrong with deletion of qpress files. Investigate" wsrep_log_error "Something went wrong with deletion of qpress files. Investigate"
fi fi
else else
...@@ -1199,7 +1259,7 @@ then ...@@ -1199,7 +1259,7 @@ then
wsrep_log_info "Preparing the backup at ${DATA}" wsrep_log_info "Preparing the backup at ${DATA}"
setup_commands setup_commands
timeit "Xtrabackup prepare stage" "$INNOAPPLY" timeit "mariabackup prepare stage" "$INNOAPPLY"
if [ $? -ne 0 ]; then if [ $? -ne 0 ]; then
wsrep_log_error "${MARIABACKUP_BIN} apply finished with errors. Check syslog or ${INNOAPPLYLOG} for details" wsrep_log_error "${MARIABACKUP_BIN} apply finished with errors. Check syslog or ${INNOAPPLYLOG} for details"
...@@ -1208,8 +1268,8 @@ then ...@@ -1208,8 +1268,8 @@ then
MAGIC_FILE="$TDATA/$INFO_FILE" MAGIC_FILE="$TDATA/$INFO_FILE"
wsrep_log_info "Moving the backup to ${TDATA}" wsrep_log_info "Moving the backup to ${TDATA}"
timeit "Xtrabackup move stage" "$INNOMOVE" timeit "mariabackup move stage" "$INNOMOVE"
if [[ $? -eq 0 ]];then if [ $? -eq 0 ]; then
wsrep_log_info "Move successful, removing ${DATA}" wsrep_log_info "Move successful, removing ${DATA}"
rm -rf "$DATA" rm -rf "$DATA"
DATA="$TDATA" DATA="$TDATA"
...@@ -1229,7 +1289,9 @@ then ...@@ -1229,7 +1289,9 @@ 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 exit 2
fi fi
wsrep_log_info "Galera co-ords from recovery: $(cat '${MAGIC_FILE}')"
coords=$(cat "$MAGIC_FILE")
wsrep_log_info "Galera co-ords from recovery: $coords"
cat "$MAGIC_FILE" # Output : UUID:seqno wsrep_gtid_domain_id cat "$MAGIC_FILE" # Output : UUID:seqno wsrep_gtid_domain_id
wsrep_log_info "Total time on joiner: $totime seconds" wsrep_log_info "Total time on joiner: $totime seconds"
......
...@@ -18,35 +18,18 @@ ...@@ -18,35 +18,18 @@
# This is a reference script for mysqldump-based state snapshot tansfer # This is a reference script for mysqldump-based state snapshot tansfer
. $(dirname $0)/wsrep_sst_common . $(dirname "$0")/wsrep_sst_common
PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin PATH=$PATH:/usr/sbin:/usr/bin:/sbin:/bin
EINVAL=22 EINVAL=22
local_ip()
{
[ "$1" = "127.0.0.1" ] && return 0
[ "$1" = "127.0.0.2" ] && return 0
[ "$1" = "localhost" ] && return 0
[ "$1" = "[::1]" ] && return 0
[ "$1" = "$(hostname -s)" ] && return 0
[ "$1" = "$(hostname -f)" ] && return 0
[ "$1" = "$(hostname -d)" ] && return 0
# Now if ip program is not found in the path, we can't return 0 since
# it would block any address. Thankfully grep should fail in this case
ip route get "$1" | grep local >/dev/null && return 0
return 1
}
if test -z "$WSREP_SST_OPT_HOST"; then wsrep_log_error "HOST cannot be nil"; exit $EINVAL; fi if test -z "$WSREP_SST_OPT_HOST"; then wsrep_log_error "HOST cannot be nil"; exit $EINVAL; fi
if test -z "$WSREP_SST_OPT_PORT"; then wsrep_log_error "PORT cannot be nil"; exit $EINVAL; fi if test -z "$WSREP_SST_OPT_PORT"; then wsrep_log_error "PORT cannot be nil"; exit $EINVAL; fi
if test -z "$WSREP_SST_OPT_LPORT"; then wsrep_log_error "LPORT cannot be nil"; exit $EINVAL; fi if test -z "$WSREP_SST_OPT_LPORT"; then wsrep_log_error "LPORT cannot be nil"; exit $EINVAL; fi
if test -z "$WSREP_SST_OPT_SOCKET";then wsrep_log_error "SOCKET cannot be nil";exit $EINVAL; fi if test -z "$WSREP_SST_OPT_SOCKET";then wsrep_log_error "SOCKET cannot be nil";exit $EINVAL; fi
if test -z "$WSREP_SST_OPT_GTID"; then wsrep_log_error "GTID cannot be nil"; exit $EINVAL; fi if test -z "$WSREP_SST_OPT_GTID"; then wsrep_log_error "GTID cannot be nil"; exit $EINVAL; fi
if local_ip $WSREP_SST_OPT_HOST && \ if is_local_ip "$WSREP_SST_OPT_HOST_UNESCAPED" && \
[ "$WSREP_SST_OPT_PORT" = "$WSREP_SST_OPT_LPORT" ] [ "$WSREP_SST_OPT_PORT" = "$WSREP_SST_OPT_LPORT" ]
then then
wsrep_log_error \ wsrep_log_error \
...@@ -111,7 +94,7 @@ then ...@@ -111,7 +94,7 @@ then
fi fi
MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF "\ MYSQL="$MYSQL_CLIENT $WSREP_SST_OPT_CONF "\
"$AUTH -h${WSREP_SST_OPT_HOST_UNESCAPED} "\ "$AUTH -h$WSREP_SST_OPT_HOST_UNESCAPED "\
"-P$WSREP_SST_OPT_PORT --disable-reconnect --connect_timeout=10" "-P$WSREP_SST_OPT_PORT --disable-reconnect --connect_timeout=10"
# Check if binary logging is enabled on the joiner node. # Check if binary logging is enabled on the joiner node.
...@@ -139,7 +122,7 @@ then ...@@ -139,7 +122,7 @@ then
# executed to erase binary logs (if any). Binary logging should also be # executed to erase binary logs (if any). Binary logging should also be
# turned off for the session so that gtid state does not get altered while # turned off for the session so that gtid state does not get altered while
# the dump gets replayed on joiner. # the dump gets replayed on joiner.
if [[ "$LOG_BIN" == 'ON' ]]; then if [ "$LOG_BIN" = 'ON' ]; then
RESET_MASTER="SET GLOBAL wsrep_on=OFF; RESET MASTER; SET GLOBAL wsrep_on=ON;" RESET_MASTER="SET GLOBAL wsrep_on=OFF; RESET MASTER; SET GLOBAL wsrep_on=ON;"
SET_GTID_BINLOG_STATE="SET GLOBAL wsrep_on=OFF; SET @@global.gtid_binlog_state='$GTID_BINLOG_STATE'; SET GLOBAL wsrep_on=ON;" SET_GTID_BINLOG_STATE="SET GLOBAL wsrep_on=OFF; SET @@global.gtid_binlog_state='$GTID_BINLOG_STATE'; SET GLOBAL wsrep_on=ON;"
SQL_LOG_BIN_OFF="SET @@session.sql_log_bin=OFF;" SQL_LOG_BIN_OFF="SET @@session.sql_log_bin=OFF;"
...@@ -164,7 +147,6 @@ $MYSQL -e "$STOP_WSREP SET GLOBAL SLOW_QUERY_LOG=OFF" ...@@ -164,7 +147,6 @@ $MYSQL -e "$STOP_WSREP SET GLOBAL SLOW_QUERY_LOG=OFF"
RESTORE_GENERAL_LOG="SET GLOBAL GENERAL_LOG=$GENERAL_LOG_OPT;" RESTORE_GENERAL_LOG="SET GLOBAL GENERAL_LOG=$GENERAL_LOG_OPT;"
RESTORE_SLOW_QUERY_LOG="SET GLOBAL SLOW_QUERY_LOG=$SLOW_LOG_OPT;" RESTORE_SLOW_QUERY_LOG="SET GLOBAL SLOW_QUERY_LOG=$SLOW_LOG_OPT;"
if [ $WSREP_SST_OPT_BYPASS -eq 0 ] if [ $WSREP_SST_OPT_BYPASS -eq 0 ]
then then
(echo $STOP_WSREP && echo $RESET_MASTER && \ (echo $STOP_WSREP && echo $RESET_MASTER && \
......
...@@ -23,13 +23,13 @@ RSYNC_PID= # rsync pid file ...@@ -23,13 +23,13 @@ RSYNC_PID= # rsync pid file
RSYNC_CONF= # rsync configuration file RSYNC_CONF= # rsync configuration file
RSYNC_REAL_PID= # rsync process id RSYNC_REAL_PID= # rsync process id
OS=$(uname) OS="$(uname)"
[ "$OS" = 'Darwin' ] && export -n LD_LIBRARY_PATH [ "$OS" = 'Darwin' ] && export -n LD_LIBRARY_PATH
# Setting the path for lsof on CentOS # Setting the path for lsof on CentOS
export PATH="/usr/sbin:/sbin:$PATH" export PATH="/usr/sbin:/sbin:$PATH"
. $(dirname $0)/wsrep_sst_common . $(dirname "$0")/wsrep_sst_common
wsrep_check_datadir wsrep_check_datadir
wsrep_check_programs rsync wsrep_check_programs rsync
...@@ -48,7 +48,7 @@ cleanup_joiner() ...@@ -48,7 +48,7 @@ cleanup_joiner()
rm -rf "$MAGIC_FILE" rm -rf "$MAGIC_FILE"
rm -rf "$RSYNC_PID" rm -rf "$RSYNC_PID"
wsrep_log_info "Joiner cleanup done." wsrep_log_info "Joiner cleanup done."
if [ "${WSREP_SST_OPT_ROLE}" = "joiner" ];then if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
wsrep_cleanup_progress_file wsrep_cleanup_progress_file
fi fi
} }
...@@ -57,68 +57,71 @@ cleanup_joiner() ...@@ -57,68 +57,71 @@ cleanup_joiner()
check_pid() check_pid()
{ {
local pid_file="$1" local pid_file="$1"
[ -r "$pid_file" ] && ps -p $(cat "$pid_file") >/dev/null 2>&1 [ -r "$pid_file" ] && ps -p $(cat "$pid_file") 2>&1 >/dev/null
} }
check_pid_and_port() check_pid_and_port()
{ {
local pid_file="$1" local pid_file="$1"
local rsync_pid=$2 local rsync_pid=$2
local rsync_addr=$3 local rsync_addr="$3"
local rsync_port=$4 local rsync_port="$4"
case $OS in if [ -z "$rsync_port" -o -z "$rsync_addr" -o -z "$rsync_pid" ]; then
FreeBSD) wsrep_log_error "check_pid_and_port(): bad arguments"
local port_info="$(sockstat -46lp ${rsync_port} 2>/dev/null | \ exit 2 # ENOENT
grep ":${rsync_port}")" fi
local is_rsync="$(echo $port_info | \
grep -E '[[:space:]]+(rsync|stunnel)[[:space:]]+'"$rsync_pid" 2>/dev/null)"
;;
*)
if [ ! -x "$(command -v lsof)" ]; then
wsrep_log_error "lsof tool not found in PATH! Make sure you have it installed."
exit 2 # ENOENT
fi
local port_info="$(lsof -i :$rsync_port -Pn 2>/dev/null | \
grep "(LISTEN)")"
local is_rsync="$(echo $port_info | \
grep -E '^(rsync|stunnel)[[:space:]]+'"$rsync_pid" 2>/dev/null)"
;;
esac
local is_listening_all="$(echo $port_info | \ local port_info is_rsync
grep "*:$rsync_port" 2>/dev/null)"
local is_listening_addr="$(echo $port_info | \ if [ $lsof_available -ne 0 ]; then
grep -F "$rsync_addr:$rsync_port" 2>/dev/null)" port_info=$(lsof -i ":$rsync_port" -Pn 2>/dev/null | \
grep -F '(LISTEN)')
is_rsync=$(echo "$port_info" | \
grep -E "^(rsync|stunnel)[^[:space:]]*[[:space:]]+$rsync_pid[[:space:]]+")
elif [ $sockstat_available -ne 0 ]; then
port_info=$(sockstat -p "$rsync_port" 2>/dev/null | \
grep -F 'LISTEN')
is_rsync=$(echo "$port_info" | \
grep -E "[[:space:]]+(rsync|stunnel)[^[:space:]]*[[:space:]]+$rsync_pid[[:space:]]+")
elif [ $ss_available -ne 0 ]; then
port_info=$(ss -H -p -n -l "( sport = :$rsync_port )" 2>/dev/null)
is_rsync=$(echo "$port_info" | \
grep -E "users:\\(.*\\(\"(rsync|stunnel)[^[:space:]]*\".*\<pid=$rsync_pid\>.*\\)")
else
wsrep_log_error "unknown sockets utility"
exit 2 # ENOENT
fi
if [ ! -z "$is_listening_all" -o ! -z "$is_listening_addr" ]; then if [ -z "$is_rsync" ]; then
if [ -z "$is_rsync" ]; then local is_listening_all
wsrep_log_error "rsync daemon port '$rsync_port' has been taken" if [ $lsof_available -ne 0 ]; then
is_listening_all=$(echo "$port_info" | \
grep -E "[[:space:]](\\*|\\[?::\\]?):$rsync_port[[:space:]]")
else
if [ $sockstat_available -eq 0 ]; then
port_info=$(echo "$port_info" | grep -q -F 'users:(')
fi
port_info=$(echo "$port_info" | \
grep -E "[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+[[:space:]]+[^[:space:]]+" -o)
is_listening_all=$(echo "$port_info" | \
grep -E "[[:space:]](\\*|\\[?::\\]?):$rsync_port\$")
fi
local is_listening_addr=$(echo "$port_info" | \
grep -w -F -- "$rsync_addr:$rsync_port")
if [ -z "$is_listening_addr" ]; then
is_listening_addr=$(echo "$port_info" | \
grep -w -F "[$rsync_addr]:$rsync_port")
fi
if [ -n "$is_listening_all" -o -n "$is_listening_addr" ]; then
wsrep_log_error "rsync or stunnel daemon port '$rsync_port' " \
"has been taken by another program"
exit 16 # EBUSY exit 16 # EBUSY
fi fi
return 1
fi fi
check_pid "$pid_file" && \
[ -n "$port_info" ] && [ -n "$is_rsync" ] && \
[ $(cat "$pid_file") -eq $rsync_pid ]
}
is_local_ip() check_pid "$pid_file" && [ $(cat "$pid_file") -eq $rsync_pid ]
{
local address="$1"
local get_addr_bin="$(command -v ifconfig)"
if [ -z "$get_addr_bin" ]
then
get_addr_bin="$(command -v ip) address show"
# Add an slash at the end, so we don't get false positive : 172.18.0.4 matches 172.18.0.41
# ip output format is "X.X.X.X/mask"
address="$address/"
else
# Add an space at the end, so we don't get false positive : 172.18.0.4 matches 172.18.0.41
# ifconfig output format is "X.X.X.X "
address="$address "
fi
$get_addr_bin | grep -F "$address" > /dev/null
} }
STUNNEL_CONF="$WSREP_SST_OPT_DATA/stunnel.conf" STUNNEL_CONF="$WSREP_SST_OPT_DATA/stunnel.conf"
...@@ -225,11 +228,11 @@ check_server_ssl_config() ...@@ -225,11 +228,11 @@ check_server_ssl_config()
SSLMODE=$(parse_cnf 'sst' 'ssl-mode' | tr [:lower:] [:upper:]) SSLMODE=$(parse_cnf 'sst' 'ssl-mode' | tr [:lower:] [:upper:])
if [ -z "$SSTKEY" -a -z "$SSTCERT" ] if [ -z "$SSTKEY" -a -z "$SSTCERT" -a -z "$SSTCA" ]
then then
# no old-style SSL config in [sst], check for new one # no old-style SSL config in [sst], check for new one
check_server_ssl_config 'sst' check_server_ssl_config 'sst'
if [ -z "$SSTKEY" -a -z "$SSTCERT" ]; then if [ -z "$SSTKEY" -a -z "$SSTCERT" -a -z "$SSTCA" ]; then
check_server_ssl_config '--mysqld' check_server_ssl_config '--mysqld'
fi fi
fi fi
...@@ -279,7 +282,7 @@ fi ...@@ -279,7 +282,7 @@ fi
STUNNEL="" STUNNEL=""
if [ -n "$SSLMODE" -a "$SSLMODE" != 'DISABLED' ] && wsrep_check_programs stunnel if [ -n "$SSLMODE" -a "$SSLMODE" != 'DISABLED' ] && wsrep_check_programs stunnel
then then
wsrep_log_info "Using stunnel for SSL encryption: CAfile: $SSTCA, SSLMODE: $SSLMODE" wsrep_log_info "Using stunnel for SSL encryption: CAfile: '$SSTCA', SSLMODE: '$SSLMODE'"
STUNNEL="stunnel $STUNNEL_CONF" STUNNEL="stunnel $STUNNEL_CONF"
fi fi
...@@ -296,7 +299,7 @@ foreground = yes ...@@ -296,7 +299,7 @@ foreground = yes
pid = $STUNNEL_PID pid = $STUNNEL_PID
debug = warning debug = warning
client = yes client = yes
connect = ${WSREP_SST_OPT_ADDR%/*} connect = $WSREP_SST_OPT_HOST_UNESCAPED:$WSREP_SST_OPT_PORT
TIMEOUTclose = 0 TIMEOUTclose = 0
${VERIFY_OPT} ${VERIFY_OPT}
EOF EOF
...@@ -322,7 +325,7 @@ EOF ...@@ -322,7 +325,7 @@ EOF
# (b) Cluster state ID & wsrep_gtid_domain_id to be written to the file, OR # (b) Cluster state ID & wsrep_gtid_domain_id to be written to the file, OR
# (c) ERROR file, in case flush tables operation failed. # (c) ERROR file, in case flush tables operation failed.
while [ ! -r "$FLUSHED" ] && ! grep -q ':' "$FLUSHED" >/dev/null 2>&1 while [ ! -r "$FLUSHED" ] && ! grep -q -F ':' "$FLUSHED" >/dev/null 2>&1
do do
# Check whether ERROR file exists. # Check whether ERROR file exists.
if [ -f "$ERROR" ] if [ -f "$ERROR" ]
...@@ -365,15 +368,14 @@ EOF ...@@ -365,15 +368,14 @@ EOF
# first, the normal directories, so that we can detect incompatible protocol # first, the normal directories, so that we can detect incompatible protocol
RC=0 RC=0
eval rsync ${STUNNEL:+--rsh=\"$STUNNEL\"} \ eval rsync "'${STUNNEL:+--rsh=$STUNNEL}'" \
--owner --group --perms --links --specials \ --owner --group --perms --links --specials \
--ignore-times --inplace --dirs --delete --quiet \ --ignore-times --inplace --dirs --delete --quiet \
$WHOLE_FILE_OPT ${FILTER} "$WSREP_SST_OPT_DATA/" \ $WHOLE_FILE_OPT $FILTER "'$WSREP_SST_OPT_DATA/'" \
rsync://$WSREP_SST_OPT_ADDR >&2 || RC=$? "'rsync://$WSREP_SST_OPT_ADDR'" >&2 || RC=$?
if [ $RC -ne 0 ]; then if [ $RC -ne 0 ]; then
wsrep_log_error "rsync returned code $RC:" wsrep_log_error "rsync returned code $RC:"
case $RC in case $RC in
12) RC=71 # EPROTO 12) RC=71 # EPROTO
wsrep_log_error \ wsrep_log_error \
...@@ -394,7 +396,7 @@ EOF ...@@ -394,7 +396,7 @@ EOF
--ignore-times --inplace --dirs --delete --quiet \ --ignore-times --inplace --dirs --delete --quiet \
$WHOLE_FILE_OPT -f '+ /ibdata*' -f '+ /ib_lru_dump' \ $WHOLE_FILE_OPT -f '+ /ibdata*' -f '+ /ib_lru_dump' \
-f '- **' "$INNODB_DATA_HOME_DIR/" \ -f '- **' "$INNODB_DATA_HOME_DIR/" \
rsync://$WSREP_SST_OPT_ADDR-data_dir >&2 || RC=$? "rsync://$WSREP_SST_OPT_ADDR-data_dir" >&2 || RC=$?
if [ $RC -ne 0 ]; then if [ $RC -ne 0 ]; then
wsrep_log_error "rsync innodb_data_home_dir returned code $RC:" wsrep_log_error "rsync innodb_data_home_dir returned code $RC:"
...@@ -405,28 +407,32 @@ EOF ...@@ -405,28 +407,32 @@ EOF
rsync ${STUNNEL:+--rsh="$STUNNEL"} \ rsync ${STUNNEL:+--rsh="$STUNNEL"} \
--owner --group --perms --links --specials \ --owner --group --perms --links --specials \
--ignore-times --inplace --dirs --delete --quiet \ --ignore-times --inplace --dirs --delete --quiet \
$WHOLE_FILE_OPT -f '+ /ib_logfile[0-9]*' -f '+ /aria_log.*' -f '+ /aria_log_control' -f '- **' "$WSREP_LOG_DIR/" \ $WHOLE_FILE_OPT -f '+ /ib_logfile[0-9]*' -f '+ /aria_log.*' \
rsync://$WSREP_SST_OPT_ADDR-log_dir >&2 || RC=$? -f '+ /aria_log_control' -f '- **' "$WSREP_LOG_DIR/" \
"rsync://$WSREP_SST_OPT_ADDR-log_dir" >&2 || RC=$?
if [ $RC -ne 0 ]; then if [ $RC -ne 0 ]; then
wsrep_log_error "rsync innodb_log_group_home_dir returned code $RC:" wsrep_log_error "rsync innodb_log_group_home_dir returned code $RC:"
exit 255 # unknown error exit 255 # unknown error
fi fi
# then, we parallelize the transfer of database directories, use . so that pathconcatenation works # then, we parallelize the transfer of database directories,
# use . so that path concatenation works:
cd "$WSREP_SST_OPT_DATA" cd "$WSREP_SST_OPT_DATA"
count=1 count=1
[ "$OS" = "Linux" ] && count=$(grep -c processor /proc/cpuinfo) [ "$OS" = 'Linux' ] && count=$(grep -c processor /proc/cpuinfo)
[ "$OS" = "Darwin" -o "$OS" = "FreeBSD" ] && count=$(sysctl -n hw.ncpu) [ "$OS" = 'Darwin' -o "$OS" = 'FreeBSD' ] && count=$(sysctl -n hw.ncpu)
find . -maxdepth 1 -mindepth 1 -type d -not -name "lost+found" -not -name ".zfs" \ find . -maxdepth 1 -mindepth 1 -type d -not -name 'lost+found' \
-print0 | xargs -I{} -0 -P $count \ -not -name '.zfs' -print0 | xargs -I{} -0 -P $count \
rsync ${STUNNEL:+--rsh="$STUNNEL"} \ rsync ${STUNNEL:+--rsh="$STUNNEL"} \
--owner --group --perms --links --specials \ --owner --group --perms --links --specials \
--ignore-times --inplace --recursive --delete --quiet \ --ignore-times --inplace --recursive --delete --quiet \
$WHOLE_FILE_OPT --exclude '*/ib_logfile*' --exclude "*/aria_log.*" --exclude "*/aria_log_control" "$WSREP_SST_OPT_DATA"/{}/ \ $WHOLE_FILE_OPT --exclude '*/ib_logfile*' --exclude '*/aria_log.*' \
rsync://$WSREP_SST_OPT_ADDR/{} >&2 || RC=$? --exclude '*/aria_log_control' "$WSREP_SST_OPT_DATA/{}/" \
"rsync://$WSREP_SST_OPT_ADDR/{}" >&2 || RC=$?
cd "$OLD_PWD" cd "$OLD_PWD"
...@@ -455,13 +461,13 @@ EOF ...@@ -455,13 +461,13 @@ EOF
fi fi
rsync ${STUNNEL:+--rsh="$STUNNEL"} \ rsync ${STUNNEL:+--rsh="$STUNNEL"} \
--archive --quiet --checksum "$MAGIC_FILE" rsync://$WSREP_SST_OPT_ADDR --archive --quiet --checksum "$MAGIC_FILE" "rsync://$WSREP_SST_OPT_ADDR"
echo "done $STATE" echo "done $STATE"
elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ] elif [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]
then then
wsrep_check_programs lsof check_sockets_utils
touch "$SST_PROGRESS_FILE" touch "$SST_PROGRESS_FILE"
MYSQLD_PID="$WSREP_SST_OPT_PARENT" MYSQLD_PID="$WSREP_SST_OPT_PARENT"
...@@ -488,6 +494,7 @@ then ...@@ -488,6 +494,7 @@ then
ADDR="$WSREP_SST_OPT_ADDR" ADDR="$WSREP_SST_OPT_ADDR"
RSYNC_PORT="$WSREP_SST_OPT_PORT" RSYNC_PORT="$WSREP_SST_OPT_PORT"
RSYNC_ADDR="$WSREP_SST_OPT_HOST" RSYNC_ADDR="$WSREP_SST_OPT_HOST"
RSYNC_ADDR_UNESCAPED="$WSREP_SST_OPT_HOST_UNESCAPED"
trap "exit 32" HUP PIPE trap "exit 32" HUP PIPE
trap "exit 3" INT TERM ABRT trap "exit 3" INT TERM ABRT
...@@ -519,10 +526,10 @@ EOF ...@@ -519,10 +526,10 @@ 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 in it
if is_local_ip "$RSYNC_ADDR" if is_local_ip "$RSYNC_ADDR_UNESCAPED"
then then
RSYNC_EXTRA_ARGS="--address $RSYNC_ADDR" RSYNC_EXTRA_ARGS="--address $RSYNC_ADDR_UNESCAPED"
STUNNEL_ACCEPT="$RSYNC_ADDR:$RSYNC_PORT" STUNNEL_ACCEPT="$RSYNC_ADDR_UNESCAPED:$RSYNC_PORT"
else else
# Not local, possibly a NAT, listen on all interfaces # Not local, possibly a NAT, listen on all interfaces
RSYNC_EXTRA_ARGS="" RSYNC_EXTRA_ARGS=""
...@@ -533,7 +540,7 @@ EOF ...@@ -533,7 +540,7 @@ EOF
if [ -z "$STUNNEL" ] if [ -z "$STUNNEL" ]
then then
rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" ${RSYNC_EXTRA_ARGS} & rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" $RSYNC_EXTRA_ARGS &
RSYNC_REAL_PID=$! RSYNC_REAL_PID=$!
else else
cat << EOF > "$STUNNEL_CONF" cat << EOF > "$STUNNEL_CONF"
...@@ -543,18 +550,19 @@ ${CAFILE_OPT} ...@@ -543,18 +550,19 @@ ${CAFILE_OPT}
foreground = yes foreground = yes
pid = $STUNNEL_PID pid = $STUNNEL_PID
debug = warning debug = warning
debug = 6
client = no client = no
[rsync] [rsync]
accept = $STUNNEL_ACCEPT accept = $STUNNEL_ACCEPT
exec = $(command -v rsync) exec = $(command -v rsync)
execargs = rsync --server --daemon --config='$RSYNC_CONF' . execargs = rsync --server --daemon --config=$RSYNC_CONF .
EOF EOF
stunnel "$STUNNEL_CONF" & stunnel "$STUNNEL_CONF" &
RSYNC_REAL_PID=$! RSYNC_REAL_PID=$!
RSYNC_PID="$STUNNEL_PID" RSYNC_PID="$STUNNEL_PID"
fi fi
until check_pid_and_port "$RSYNC_PID" "$RSYNC_REAL_PID" "$RSYNC_ADDR" "$RSYNC_PORT" until check_pid_and_port "$RSYNC_PID" "$RSYNC_REAL_PID" "$RSYNC_ADDR_UNESCAPED" "$RSYNC_PORT"
do do
sleep 0.2 sleep 0.2
done done
...@@ -571,10 +579,10 @@ EOF ...@@ -571,10 +579,10 @@ EOF
exit 42 exit 42
fi fi
CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$SSTCERT" | \ CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$SSTCERT" | \
tr "," "\n" | grep "CN =" | cut -d= -f2 | sed s/^\ // | \ tr "," "\n" | grep -F 'CN =' | cut -d= -f2 | sed s/^\ // | \
sed s/\ %//) sed s/\ %//)
fi fi
MY_SECRET=$(wsrep_gen_secret) MY_SECRET="$(wsrep_gen_secret)"
# Add authentication data to address # Add authentication data to address
ADDR="$CN:$MY_SECRET@$WSREP_SST_OPT_HOST" ADDR="$CN:$MY_SECRET@$WSREP_SST_OPT_HOST"
else else
...@@ -624,7 +632,7 @@ EOF ...@@ -624,7 +632,7 @@ EOF
if [ -r "$MAGIC_FILE" ] if [ -r "$MAGIC_FILE" ]
then then
# check donor supplied secret # check donor supplied secret
SECRET=$(grep "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2) SECRET=$(grep -F -- "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2)
if [ "$SECRET" != "$MY_SECRET" ]; then if [ "$SECRET" != "$MY_SECRET" ]; then
wsrep_log_error "Donor does not know my secret!" wsrep_log_error "Donor does not know my secret!"
wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'" wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'"
...@@ -632,7 +640,7 @@ EOF ...@@ -632,7 +640,7 @@ EOF
fi fi
# remove secret from magic file # remove secret from magic file
grep -v "$SECRET_TAG " "$MAGIC_FILE" > "$MAGIC_FILE.new" grep -v -F -- "$SECRET_TAG " "$MAGIC_FILE" > "$MAGIC_FILE.new"
mv "$MAGIC_FILE.new" "$MAGIC_FILE" mv "$MAGIC_FILE.new" "$MAGIC_FILE"
# UUID:seqno & wsrep_gtid_domain_id is received here. # UUID:seqno & wsrep_gtid_domain_id is received here.
...@@ -643,7 +651,7 @@ EOF ...@@ -643,7 +651,7 @@ EOF
fi fi
wsrep_cleanup_progress_file wsrep_cleanup_progress_file
# cleanup_joiner # cleanup_joiner
else else
wsrep_log_error "Unrecognized role: '$WSREP_SST_OPT_ROLE'" wsrep_log_error "Unrecognized role: '$WSREP_SST_OPT_ROLE'"
exit 22 # EINVAL exit 22 # EINVAL
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment