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.
This commit is contained in:
parent
d0785f7731
commit
8fef2b8667
@ -0,0 +1,3 @@
|
|||||||
|
SELECT 1;
|
||||||
|
1
|
||||||
|
1
|
@ -0,0 +1,13 @@
|
|||||||
|
!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
|
@ -0,0 +1,12 @@
|
|||||||
|
#
|
||||||
|
# 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,9 +5,9 @@ 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]
|
||||||
ssl-mode=VERIFY_CA
|
ssl-mode=VERIFY_CA
|
||||||
|
@ -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
|
||||||
|
@ -12,4 +12,3 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore
|
|||||||
|
|
||||||
[mysqld.2]
|
[mysqld.2]
|
||||||
wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'
|
wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'
|
||||||
|
|
||||||
|
@ -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]
|
||||||
@ -14,4 +14,3 @@ wsrep_provider_options='base_port=@mysqld.1.#galera_port;gcache.size=1;pc.ignore
|
|||||||
|
|
||||||
[mysqld.2]
|
[mysqld.2]
|
||||||
wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'
|
wsrep_provider_options='base_port=@mysqld.2.#galera_port;gcache.size=1;pc.ignore_sb=true'
|
||||||
|
|
||||||
|
148
scripts/wsrep_sst_common.sh
Normal file → Executable file
148
scripts/wsrep_sst_common.sh
Normal file → Executable file
@ -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
|
|||||||
# 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
|
|||||||
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
|
|||||||
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
|
|||||||
# 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
|
|||||||
|
|
||||||
# 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"
|
|||||||
#
|
#
|
||||||
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
|
||||||
|
# was specified several times - we use only its last instance):
|
||||||
|
|
||||||
if [ "$group" = '--mysqld' -o \
|
local pattern='BEGIN {OFS=FS="="} {sub(/^--loose/,"-",$0); gsub(/_/,"-",$1); if ($1=="--'"$var"'") lastval=substr($0,length($1)+2)} END {print lastval}'
|
||||||
"$group" = 'mysqld' ]; then
|
|
||||||
if [ -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then
|
|
||||||
reval=$($MY_PRINT_DEFAULTS "mysqld$WSREP_SST_OPT_SUFFIX_VALUE" | awk 'BEGIN {OFS=FS="="} {sub(/^--loose/,"-",$0); gsub(/_/,"-",$1); if ($1=="--'"$var"'") lastval=substr($0,length($1)+2)} END {print lastval}')
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$reval" ]; then
|
while [ -n "$groups" ]; do
|
||||||
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}')
|
# Remove the largest suffix starting with the '|' character:
|
||||||
fi
|
local group="${groups%%\|*}"
|
||||||
|
# Remove the remainder (the group name) from the rest
|
||||||
|
# of the groups list (as if it were a prefix):
|
||||||
|
groups="${groups#$group}"
|
||||||
|
groups="${groups#\|}"
|
||||||
|
# if the group name is the same as the "[--]mysqld", then
|
||||||
|
# try to use it together with the group suffix:
|
||||||
|
if [ "${group#--}" = 'mysqld' -a -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then
|
||||||
|
reval=$($MY_PRINT_DEFAULTS "mysqld$WSREP_SST_OPT_SUFFIX_VALUE" | awk "$pattern")
|
||||||
|
if [ -n "$reval" ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# Let's try to use the group name as it is:
|
||||||
|
reval=$($MY_PRINT_DEFAULTS "$group" | awk "$pattern")
|
||||||
|
if [ -n "$reval" ]; then
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
# use default if we haven't found a value
|
# use default if we haven't found a value:
|
||||||
if [ -z "$reval" ]; then
|
if [ -z "$reval" ]; then
|
||||||
[ -n "${3:-}" ] && reval="$3"
|
[ -n "${3:-}" ] && reval="$3"
|
||||||
fi
|
fi
|
||||||
echo $reval
|
echo "$reval"
|
||||||
}
|
}
|
||||||
|
|
||||||
#
|
#
|
||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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
|
||||||
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -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
|
|||||||
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
|
|||||||
# 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"
|
|||||||
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
|
|||||||
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()
|
|||||||
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()
|
|||||||
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)"
|
local port_info is_rsync
|
||||||
;;
|
|
||||||
*)
|
if [ $lsof_available -ne 0 ]; then
|
||||||
if [ ! -x "$(command -v lsof)" ]; then
|
port_info=$(lsof -i ":$rsync_port" -Pn 2>/dev/null | \
|
||||||
wsrep_log_error "lsof tool not found in PATH! Make sure you have it installed."
|
grep -F '(LISTEN)')
|
||||||
exit 2 # ENOENT
|
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:]]")
|
||||||
|
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
|
fi
|
||||||
local port_info="$(lsof -i :$rsync_port -Pn 2>/dev/null | \
|
local is_listening_addr=$(echo "$port_info" | \
|
||||||
grep "(LISTEN)")"
|
grep -w -F -- "$rsync_addr:$rsync_port")
|
||||||
local is_rsync="$(echo $port_info | \
|
if [ -z "$is_listening_addr" ]; then
|
||||||
grep -E '^(rsync|stunnel)[[:space:]]+'"$rsync_pid" 2>/dev/null)"
|
is_listening_addr=$(echo "$port_info" | \
|
||||||
;;
|
grep -w -F "[$rsync_addr]:$rsync_port")
|
||||||
esac
|
fi
|
||||||
|
if [ -n "$is_listening_all" -o -n "$is_listening_addr" ]; then
|
||||||
local is_listening_all="$(echo $port_info | \
|
wsrep_log_error "rsync or stunnel daemon port '$rsync_port' " \
|
||||||
grep "*:$rsync_port" 2>/dev/null)"
|
"has been taken by another program"
|
||||||
local is_listening_addr="$(echo $port_info | \
|
|
||||||
grep -F "$rsync_addr:$rsync_port" 2>/dev/null)"
|
|
||||||
|
|
||||||
if [ ! -z "$is_listening_all" -o ! -z "$is_listening_addr" ]; then
|
|
||||||
if [ -z "$is_rsync" ]; then
|
|
||||||
wsrep_log_error "rsync daemon port '$rsync_port' has been taken"
|
|
||||||
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"
|
||||||
@ -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
|
|||||||
# (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" ]
|
||||||
@ -368,12 +371,11 @@ EOF
|
|||||||
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 \
|
||||||
@ -414,21 +416,23 @@ EOF
|
|||||||
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.*' \
|
$WHOLE_FILE_OPT --exclude '*/ib_logfile*' --exclude '*/aria_log.*' \
|
||||||
--exclude '*/aria_log_control' "$WSREP_SST_OPT_DATA/"{}"/" \
|
--exclude '*/aria_log_control' "$WSREP_SST_OPT_DATA/{}/" \
|
||||||
"rsync://$WSREP_SST_OPT_ADDR/"{} >&2 || RC=$?
|
"rsync://$WSREP_SST_OPT_ADDR/{}" >&2 || RC=$?
|
||||||
|
|
||||||
cd "$OLD_PWD"
|
cd "$OLD_PWD"
|
||||||
|
|
||||||
@ -463,7 +467,7 @@ EOF
|
|||||||
|
|
||||||
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"
|
||||||
@ -490,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
|
||||||
@ -521,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=""
|
||||||
@ -535,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"
|
||||||
@ -545,6 +550,7 @@ ${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
|
||||||
@ -556,7 +562,7 @@ EOF
|
|||||||
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
|
||||||
@ -573,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
|
||||||
@ -626,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'"
|
||||||
@ -634,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.
|
||||||
@ -645,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
|
||||||
|
@ -16,10 +16,11 @@
|
|||||||
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston
|
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston
|
||||||
# MA 02110-1335 USA.
|
# MA 02110-1335 USA.
|
||||||
|
|
||||||
# Documentation: http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html
|
# Documentation:
|
||||||
|
# http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html
|
||||||
# Make sure to read that before proceeding!
|
# Make sure to read that before proceeding!
|
||||||
|
|
||||||
. $(dirname $0)/wsrep_sst_common
|
. $(dirname "$0")/wsrep_sst_common
|
||||||
wsrep_check_datadir
|
wsrep_check_datadir
|
||||||
|
|
||||||
ealgo=""
|
ealgo=""
|
||||||
@ -72,13 +73,13 @@ ssl_cert=""
|
|||||||
ssl_ca=""
|
ssl_ca=""
|
||||||
ssl_key=""
|
ssl_key=""
|
||||||
|
|
||||||
if which pv &>/dev/null && pv --help | grep -q FORMAT;then
|
if [ -x "$(command -v pv)" ] && pv --help | grep -qw -- '-F'; then
|
||||||
pvopts+=$pvformat
|
pvopts+=$pvformat
|
||||||
fi
|
fi
|
||||||
pcmd="pv $pvopts"
|
pcmd="pv $pvopts"
|
||||||
declare -a RC
|
declare -a RC
|
||||||
|
|
||||||
INNOBACKUPEX_BIN=innobackupex
|
INNOBACKUPEX_BIN='innobackupex'
|
||||||
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"
|
||||||
@ -87,9 +88,9 @@ MAGIC_FILE="${DATA}/${INFO_FILE}"
|
|||||||
# Setting the path for ss and ip
|
# Setting the path for ss and ip
|
||||||
export PATH="/usr/sbin:/sbin:$PATH"
|
export PATH="/usr/sbin:/sbin:$PATH"
|
||||||
|
|
||||||
OS=$(uname)
|
OS="$(uname)"
|
||||||
|
|
||||||
if ! which lsof > /dev/null; then
|
if [ ! -x "$(command -v lsof)" ]; then
|
||||||
wsrep_log_error "lsof tool not found in PATH! Make sure you have it installed."
|
wsrep_log_error "lsof tool not found in PATH! Make sure you have it installed."
|
||||||
exit 2 # ENOENT
|
exit 2 # ENOENT
|
||||||
fi
|
fi
|
||||||
@ -131,7 +132,7 @@ get_keys()
|
|||||||
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: Xtrabackup-based encryption - encrypt=1 - cannot be enabled with tar format"
|
||||||
encrypt=-1
|
encrypt=-1
|
||||||
return
|
return
|
||||||
@ -251,10 +252,8 @@ get_transfer()
|
|||||||
TSST_PORT="$WSREP_SST_OPT_PORT"
|
TSST_PORT="$WSREP_SST_OPT_PORT"
|
||||||
|
|
||||||
if [[ $tfmt == 'nc' ]];then
|
if [[ $tfmt == 'nc' ]];then
|
||||||
if [[ ! -x `which nc` ]];then
|
wsrep_log_info "Using netcat as streamer"
|
||||||
wsrep_log_error "nc(netcat) not found in path: $PATH"
|
wsrep_check_programs nc
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $encrypt -eq 2 || $encrypt -eq 3 || $encrypt -eq 4 ]]; then
|
if [[ $encrypt -eq 2 || $encrypt -eq 3 || $encrypt -eq 4 ]]; then
|
||||||
wsrep_log_error "******** FATAL ERROR *********************** "
|
wsrep_log_error "******** FATAL ERROR *********************** "
|
||||||
@ -264,25 +263,25 @@ get_transfer()
|
|||||||
exit 22
|
exit 22
|
||||||
fi
|
fi
|
||||||
|
|
||||||
wsrep_log_info "Using netcat as streamer"
|
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"
|
||||||
if [ $WSREP_SST_OPT_HOST_IPv6 -eq 1 ];then
|
tcmd="$tcmd -dl"
|
||||||
|
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
|
||||||
@ -291,30 +290,25 @@ 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
|
wsrep_log_info "Using nc -N"
|
||||||
tcmd_extra+="-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"
|
||||||
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
|
wsrep_log_info "Using Debian netcat as streamer"
|
||||||
# Debian netcat
|
|
||||||
tcmd="nc ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}"
|
|
||||||
else
|
else
|
||||||
# traditional netcat
|
wsrep_log_info "Using traditional netcat as streamer"
|
||||||
tcmd="nc -q0 ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}"
|
tcmd="$tcmd -q0"
|
||||||
fi
|
fi
|
||||||
|
tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
tfmt='socat'
|
tfmt='socat'
|
||||||
wsrep_log_info "Using socat as streamer"
|
wsrep_log_info "Using socat as streamer"
|
||||||
if [[ ! -x `which socat` ]];then
|
wsrep_check_programs socat
|
||||||
wsrep_log_error "socat not found in path: $PATH"
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
donor_extra=""
|
donor_extra=""
|
||||||
joiner_extra=""
|
joiner_extra=""
|
||||||
@ -438,7 +432,7 @@ get_footprint()
|
|||||||
|
|
||||||
adjust_progress()
|
adjust_progress()
|
||||||
{
|
{
|
||||||
if [[ ! -x `which pv` ]];then
|
if [ ! -x "$(command -v pv)" ]; then
|
||||||
wsrep_log_error "pv not found in path: $PATH"
|
wsrep_log_error "pv not found in path: $PATH"
|
||||||
wsrep_log_error "Disabling all progress/rate-limiting"
|
wsrep_log_error "Disabling all progress/rate-limiting"
|
||||||
pcmd=""
|
pcmd=""
|
||||||
@ -529,7 +523,7 @@ get_stream()
|
|||||||
{
|
{
|
||||||
if [[ $sfmt == 'xbstream' ]];then
|
if [[ $sfmt == 'xbstream' ]];then
|
||||||
wsrep_log_info "Streaming with xbstream"
|
wsrep_log_info "Streaming with xbstream"
|
||||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||||
strmcmd="xbstream -x"
|
strmcmd="xbstream -x"
|
||||||
else
|
else
|
||||||
strmcmd="xbstream -c '${INFO_FILE}'"
|
strmcmd="xbstream -c '${INFO_FILE}'"
|
||||||
@ -537,7 +531,7 @@ get_stream()
|
|||||||
else
|
else
|
||||||
sfmt="tar"
|
sfmt="tar"
|
||||||
wsrep_log_info "Streaming with tar"
|
wsrep_log_info "Streaming with tar"
|
||||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
||||||
strmcmd="tar xfi -"
|
strmcmd="tar xfi -"
|
||||||
else
|
else
|
||||||
strmcmd="tar cf - '${INFO_FILE}'"
|
strmcmd="tar cf - '${INFO_FILE}'"
|
||||||
@ -720,8 +714,8 @@ recv_joiner()
|
|||||||
pushd "${dir}" 1>/dev/null
|
pushd "${dir}" 1>/dev/null
|
||||||
set +e
|
set +e
|
||||||
|
|
||||||
if [[ $tmt -gt 0 && -x `which timeout` ]];then
|
if [ $tmt -gt 0 -a -x "$(command -v timeout)" ]; then
|
||||||
if timeout --help | grep -q -- '-k';then
|
if timeout --help | grep -qw -- '-k';then
|
||||||
ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd"
|
ltcmd="timeout -k $(( tmt+10 )) $tmt $tcmd"
|
||||||
else
|
else
|
||||||
ltcmd="timeout -s9 $tmt $tcmd"
|
ltcmd="timeout -s9 $tmt $tcmd"
|
||||||
@ -751,7 +745,7 @@ recv_joiner()
|
|||||||
# this message should cause joiner to abort
|
# this message should cause joiner to abort
|
||||||
wsrep_log_error "xtrabackup process ended without creating '${MAGIC_FILE}'"
|
wsrep_log_error "xtrabackup process ended without creating '${MAGIC_FILE}'"
|
||||||
wsrep_log_info "Contents of datadir"
|
wsrep_log_info "Contents of datadir"
|
||||||
wsrep_log_info "$(ls -l ${dir}/*)"
|
wsrep_log_info $(ls -l "$dir/"*)
|
||||||
exit 32
|
exit 32
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@ -802,8 +796,8 @@ normalize_version()
|
|||||||
# Returns 1 (failure) if $1 >= $2, 0 (success) otherwise
|
# Returns 1 (failure) if $1 >= $2, 0 (success) otherwise
|
||||||
check_for_version()
|
check_for_version()
|
||||||
{
|
{
|
||||||
local local_version_str="$( normalize_version $1 )"
|
local local_version_str=$(normalize_version "$1")
|
||||||
local required_version_str="$( normalize_version $2 )"
|
local required_version_str=$(normalize_version "$2")
|
||||||
|
|
||||||
if [[ "$local_version_str" < "$required_version_str" ]]; then
|
if [[ "$local_version_str" < "$required_version_str" ]]; then
|
||||||
return 1
|
return 1
|
||||||
@ -833,7 +827,8 @@ monitor_process()
|
|||||||
done
|
done
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ ! -x `which $INNOBACKUPEX_BIN` ]];then
|
innobackup=$(command -v "$INNOBACKUPEX_BIN")
|
||||||
|
if [ ! -x "$innobackup" ]; then
|
||||||
wsrep_log_error "innobackupex not in path: $PATH"
|
wsrep_log_error "innobackupex not in path: $PATH"
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
@ -848,21 +843,21 @@ if [[ -z "$XB_VERSION" ]]; then
|
|||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if ! check_for_version $XB_VERSION $XB_REQUIRED_VERSION; then
|
if ! check_for_version "$XB_VERSION" "$XB_REQUIRED_VERSION"; then
|
||||||
wsrep_log_error "FATAL: The $INNOBACKUPEX_BIN version is $XB_VERSION. Needs xtrabackup-$XB_REQUIRED_VERSION or higher to perform SST"
|
wsrep_log_error "FATAL: The $INNOBACKUPEX_BIN version is $XB_VERSION. Needs xtrabackup-$XB_REQUIRED_VERSION or higher to perform SST"
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -f "${MAGIC_FILE}"
|
rm -f "${MAGIC_FILE}"
|
||||||
|
|
||||||
if [[ ! ${WSREP_SST_OPT_ROLE} == 'joiner' && ! ${WSREP_SST_OPT_ROLE} == 'donor' ]];then
|
if [[ ! "${WSREP_SST_OPT_ROLE}" == 'joiner' && ! "${WSREP_SST_OPT_ROLE}" == 'donor' ]];then
|
||||||
wsrep_log_error "Invalid role ${WSREP_SST_OPT_ROLE}"
|
wsrep_log_error "Invalid role ${WSREP_SST_OPT_ROLE}"
|
||||||
exit 22
|
exit 22
|
||||||
fi
|
fi
|
||||||
|
|
||||||
read_cnf
|
read_cnf
|
||||||
|
|
||||||
if ${INNOBACKUPEX_BIN} /tmp --help 2>/dev/null | grep -q -- '--version-check'; then
|
if ${INNOBACKUPEX_BIN} /tmp --help 2>/dev/null | grep -qw -- '--version-check'; then
|
||||||
disver='--no-version-check'
|
disver='--no-version-check'
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -874,7 +869,7 @@ if [ ${FORCE_FTWRL:-0} -eq 1 ]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $ssyslog -eq 1 ]];then
|
if [[ $ssyslog -eq 1 ]];then
|
||||||
if [[ ! -x `which logger` ]];then
|
if [ ! -x "$(command -v logger)" ]; then
|
||||||
wsrep_log_error "logger not in path: $PATH. Ignoring"
|
wsrep_log_error "logger not in path: $PATH. Ignoring"
|
||||||
else
|
else
|
||||||
wsrep_log_info "Logging all stderr of SST/Innobackupex to syslog"
|
wsrep_log_info "Logging all stderr of SST/Innobackupex to syslog"
|
||||||
@ -891,8 +886,8 @@ if [[ $ssyslog -eq 1 ]];then
|
|||||||
logger -p daemon.info -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@"
|
logger -p daemon.info -t ${ssystag}wsrep-sst-$WSREP_SST_OPT_ROLE "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
INNOAPPLY="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply "
|
INNOAPPLY="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply"
|
||||||
INNOMOVE="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move "
|
INNOMOVE="2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move"
|
||||||
INNOBACKUP="2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)"
|
INNOBACKUP="2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
@ -1008,7 +1003,7 @@ then
|
|||||||
|
|
||||||
# Add encryption to the head of the stream (if specified)
|
# Add encryption to the head of the stream (if specified)
|
||||||
if [[ $encrypt -eq 1 ]]; then
|
if [[ $encrypt -eq 1 ]]; then
|
||||||
tcmd=" \$ecmd | $tcmd "
|
tcmd="\$ecmd | $tcmd"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
setup_commands
|
setup_commands
|
||||||
@ -1182,15 +1177,15 @@ then
|
|||||||
if [ -n "$qpfiles" ]; then
|
if [ -n "$qpfiles" ]; then
|
||||||
wsrep_log_info "Compressed qpress files found"
|
wsrep_log_info "Compressed qpress files found"
|
||||||
|
|
||||||
if [[ ! -x `which qpress` ]];then
|
if [ ! -x "$(command -v qpress)" ]; then
|
||||||
wsrep_log_error "qpress not found in path: $PATH"
|
wsrep_log_error "qpress not found in path: $PATH"
|
||||||
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
|
if pv --help | grep -qw -F '-F';then
|
||||||
pvopts="-f -s $count -l -N Decompression -F '%N => Rate:%r Elapsed:%t %e Progress: [%b/$count]'"
|
pvopts="-f -s $count -l -N Decompression -F '%N => Rate:%r Elapsed:%t %e Progress: [%b/$count]'"
|
||||||
else
|
else
|
||||||
pvopts="-f -s $count -l -N Decompression"
|
pvopts="-f -s $count -l -N Decompression"
|
||||||
@ -1269,8 +1264,11 @@ 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})"
|
|
||||||
cat "${MAGIC_FILE}" # Output : UUID:seqno wsrep_gtid_domain_id
|
coords=$(cat "$MAGIC_FILE")
|
||||||
|
wsrep_log_info "Galera co-ords from recovery: $coords"
|
||||||
|
cat "$MAGIC_FILE" # Output : UUID:seqno wsrep_gtid_domain_id
|
||||||
|
|
||||||
wsrep_log_info "Total time on joiner: $totime seconds"
|
wsrep_log_info "Total time on joiner: $totime seconds"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
@ -16,10 +16,11 @@
|
|||||||
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston
|
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston
|
||||||
# MA 02110-1335 USA.
|
# MA 02110-1335 USA.
|
||||||
|
|
||||||
# Optional dependencies and options documented here: http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html
|
# Optional dependencies and options documented here:
|
||||||
|
# http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html
|
||||||
# Make sure to read that before proceeding!
|
# Make sure to read that before proceeding!
|
||||||
|
|
||||||
. $(dirname $0)/wsrep_sst_common
|
. $(dirname "$0")/wsrep_sst_common
|
||||||
wsrep_check_datadir
|
wsrep_check_datadir
|
||||||
|
|
||||||
ealgo=""
|
ealgo=""
|
||||||
@ -51,13 +52,13 @@ pvformat="-F '%N => Rate:%r Avg:%a Elapsed:%t %e Bytes: %b %p' "
|
|||||||
pvopts="-f -i 10 -N $WSREP_SST_OPT_ROLE "
|
pvopts="-f -i 10 -N $WSREP_SST_OPT_ROLE "
|
||||||
uextra=0
|
uextra=0
|
||||||
|
|
||||||
if which pv &>/dev/null && pv --help | grep -q FORMAT;then
|
if [ -x "$(command -v pv)" ] && pv --help | grep -qw -- '-F'; then
|
||||||
pvopts+=$pvformat
|
pvopts+=$pvformat
|
||||||
fi
|
fi
|
||||||
pcmd="pv $pvopts"
|
pcmd="pv $pvopts"
|
||||||
declare -a RC
|
declare -a RC
|
||||||
|
|
||||||
INNOBACKUPEX_BIN=innobackupex
|
INNOBACKUPEX_BIN='innobackupex'
|
||||||
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"
|
||||||
@ -67,7 +68,7 @@ MAGIC_FILE="${DATA}/${INFO_FILE}"
|
|||||||
export PATH="/usr/sbin:/sbin:$PATH"
|
export PATH="/usr/sbin:/sbin:$PATH"
|
||||||
|
|
||||||
timeit(){
|
timeit(){
|
||||||
local stage=$1
|
local stage="$1"
|
||||||
shift
|
shift
|
||||||
local cmd="$@"
|
local cmd="$@"
|
||||||
local x1 x2 took extcode
|
local x1 x2 took extcode
|
||||||
@ -102,7 +103,7 @@ get_keys()
|
|||||||
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: Xtrabackup-based encryption - encrypt=1 - cannot be enabled with tar format"
|
||||||
encrypt=0
|
encrypt=0
|
||||||
return
|
return
|
||||||
@ -110,17 +111,17 @@ get_keys()
|
|||||||
|
|
||||||
wsrep_log_info "Xtrabackup based encryption enabled in my.cnf - Supported only from Xtrabackup 2.1.4"
|
wsrep_log_info "Xtrabackup based encryption enabled in my.cnf - Supported only from Xtrabackup 2.1.4"
|
||||||
|
|
||||||
if [[ -z $ealgo ]];then
|
if [[ -z "$ealgo" ]];then
|
||||||
wsrep_log_error "FATAL: Encryption algorithm empty from my.cnf, bailing out"
|
wsrep_log_error "FATAL: Encryption algorithm empty from my.cnf, bailing out"
|
||||||
exit 3
|
exit 3
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z $ekey && ! -r $ekeyfile ]];then
|
if [[ -z "$ekey" && ! -r "$ekeyfile" ]];then
|
||||||
wsrep_log_error "FATAL: Either key or keyfile must be readable"
|
wsrep_log_error "FATAL: Either key or keyfile must be readable"
|
||||||
exit 3
|
exit 3
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -z $ekey ]];then
|
if [[ -z "$ekey" ]];then
|
||||||
ecmd="xbcrypt --encrypt-algo=$ealgo --encrypt-key-file=$ekeyfile"
|
ecmd="xbcrypt --encrypt-algo=$ealgo --encrypt-key-file=$ekeyfile"
|
||||||
else
|
else
|
||||||
ecmd="xbcrypt --encrypt-algo=$ealgo --encrypt-key=$ekey"
|
ecmd="xbcrypt --encrypt-algo=$ealgo --encrypt-key=$ekey"
|
||||||
@ -136,43 +137,56 @@ get_transfer()
|
|||||||
TSST_PORT=$WSREP_SST_OPT_PORT
|
TSST_PORT=$WSREP_SST_OPT_PORT
|
||||||
|
|
||||||
if [[ $tfmt == 'nc' ]];then
|
if [[ $tfmt == 'nc' ]];then
|
||||||
if [[ ! -x `which nc` ]];then
|
|
||||||
wsrep_log_error "nc(netcat) not found in path: $PATH"
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
wsrep_log_info "Using netcat as streamer"
|
wsrep_log_info "Using netcat as streamer"
|
||||||
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
|
wsrep_check_programs nc
|
||||||
if nc -h 2>&1 | grep -q ncat;then
|
tcmd="nc"
|
||||||
# Ncat
|
if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then
|
||||||
tcmd="nc -l ${TSST_PORT}"
|
if nc -h 2>&1 | grep -q 'ncat'; then
|
||||||
elif nc -h 2>&1 | grep -q -- '-d\>';then
|
wsrep_log_info "Using Ncat as streamer"
|
||||||
# Debian netcat
|
tcmd="$tcmd -l"
|
||||||
tcmd="nc -dl ${TSST_PORT}"
|
elif nc -h 2>&1 | grep -qw -- '-d'; then
|
||||||
|
wsrep_log_info "Using Debian netcat as streamer"
|
||||||
|
tcmd="$tcmd -dl"
|
||||||
|
if [ $WSREP_SST_OPT_HOST_IPv6 -eq 1 ]; then
|
||||||
|
# When host is not explicitly specified (when only the port
|
||||||
|
# is specified) netcat can only bind to an IPv4 address if
|
||||||
|
# the "-6" option is not explicitly specified:
|
||||||
|
tcmd="$tcmd -6"
|
||||||
|
fi
|
||||||
else
|
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
|
||||||
if nc -h 2>&1 | grep -q ncat;then
|
# Check to see if netcat supports the '-N' flag.
|
||||||
# Ncat
|
# -N Shutdown the network socket after EOF on stdin
|
||||||
tcmd="nc ${REMOTEIP} ${TSST_PORT}"
|
# If it supports the '-N' flag, then we need to use the '-N'
|
||||||
elif nc -h 2>&1 | grep -q -- '-d\>';then
|
# flag, otherwise the transfer will stay open after the file
|
||||||
# Debian netcat
|
# transfer and cause the command to timeout.
|
||||||
tcmd="nc ${REMOTEIP} ${TSST_PORT}"
|
# Older versions of netcat did not need this flag and will
|
||||||
else
|
# return an error if the flag is used.
|
||||||
# traditional netcat
|
if nc -h 2>&1 | grep -qw -- '-N'; then
|
||||||
tcmd="nc -q0 ${REMOTEIP} ${TSST_PORT}"
|
tcmd="$tcmd -N"
|
||||||
|
wsrep_log_info "Using nc -N"
|
||||||
fi
|
fi
|
||||||
|
# netcat doesn't understand [] around IPv6 address
|
||||||
|
if nc -h 2>&1 | grep -q ncat; then
|
||||||
|
wsrep_log_info "Using Ncat as streamer"
|
||||||
|
elif nc -h 2>&1 | grep -qw -- '-d'; then
|
||||||
|
wsrep_log_info "Using Debian netcat as streamer"
|
||||||
|
else
|
||||||
|
wsrep_log_info "Using traditional netcat as streamer"
|
||||||
|
tcmd="$tcmd -q0"
|
||||||
|
fi
|
||||||
|
tcmd="$tcmd $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT"
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
tfmt='socat'
|
tfmt='socat'
|
||||||
wsrep_log_info "Using socat as streamer"
|
wsrep_log_info "Using socat as streamer"
|
||||||
if [[ ! -x `which socat` ]];then
|
wsrep_check_programs socat
|
||||||
wsrep_log_error "socat not found in path: $PATH"
|
|
||||||
exit 2
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $encrypt -eq 2 ]] && ! socat -V | grep -q OPENSSL;then
|
if [ $encrypt -eq 2 ] && ! socat -V | grep -q -F 'OPENSSL';then
|
||||||
wsrep_log_info "NOTE: socat is not openssl enabled, falling back to plain transfer"
|
wsrep_log_info "NOTE: socat is not openssl enabled, falling back to plain transfer"
|
||||||
encrypt=0
|
encrypt=0
|
||||||
fi
|
fi
|
||||||
@ -202,7 +216,7 @@ get_transfer()
|
|||||||
|
|
||||||
get_footprint()
|
get_footprint()
|
||||||
{
|
{
|
||||||
pushd $WSREP_SST_OPT_DATA 1>/dev/null
|
pushd "$WSREP_SST_OPT_DATA" 1>/dev/null
|
||||||
payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c -s | awk 'END { print $1 }')
|
payload=$(find . -regex '.*\.ibd$\|.*\.MYI$\|.*\.MYD$\|.*ibdata1$' -type f -print0 | du --files0-from=- --block-size=1 -c -s | awk 'END { print $1 }')
|
||||||
if $MY_PRINT_DEFAULTS xtrabackup | grep -q -- "--compress";then
|
if $MY_PRINT_DEFAULTS xtrabackup | grep -q -- "--compress";then
|
||||||
# QuickLZ has around 50% compression ratio
|
# QuickLZ has around 50% compression ratio
|
||||||
@ -216,18 +230,18 @@ get_footprint()
|
|||||||
|
|
||||||
adjust_progress()
|
adjust_progress()
|
||||||
{
|
{
|
||||||
if [[ -n $progress && $progress != '1' ]];then
|
if [[ -n "$progress" && "$progress" != '1' ]];then
|
||||||
if [[ -e $progress ]];then
|
if [[ -e "$progress" ]];then
|
||||||
pcmd+=" 2>>$progress"
|
pcmd+=" 2>>$progress"
|
||||||
else
|
else
|
||||||
pcmd+=" 2>$progress"
|
pcmd+=" 2>$progress"
|
||||||
fi
|
fi
|
||||||
elif [[ -z $progress && -n $rlimit ]];then
|
elif [[ -z "$progress" && -n "$rlimit" ]];then
|
||||||
# When rlimit is non-zero
|
# When rlimit is non-zero
|
||||||
pcmd="pv -q"
|
pcmd="pv -q"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -n $rlimit && "$WSREP_SST_OPT_ROLE" == "donor" ]];then
|
if [[ -n "$rlimit" && "$WSREP_SST_OPT_ROLE" == "donor" ]];then
|
||||||
wsrep_log_info "Rate-limiting SST to $rlimit"
|
wsrep_log_info "Rate-limiting SST to $rlimit"
|
||||||
pcmd+=" -L \$rlimit"
|
pcmd+=" -L \$rlimit"
|
||||||
fi
|
fi
|
||||||
@ -304,7 +318,7 @@ cleanup_joiner()
|
|||||||
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
|
||||||
if [[ -n $progress && -p $progress ]];then
|
if [[ -n "$progress" && -p "$progress" ]];then
|
||||||
wsrep_log_info "Cleaning up fifo file $progress"
|
wsrep_log_info "Cleaning up fifo file $progress"
|
||||||
rm $progress
|
rm $progress
|
||||||
fi
|
fi
|
||||||
@ -324,18 +338,18 @@ 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 "$XTRABACKUP_PID" ]];then
|
||||||
if check_pid $XTRABACKUP_PID
|
if check_pid "$XTRABACKUP_PID"
|
||||||
then
|
then
|
||||||
wsrep_log_error "xtrabackup process is still running. Killing... "
|
wsrep_log_error "xtrabackup process is still running. Killing... "
|
||||||
kill_xtrabackup
|
kill_xtrabackup
|
||||||
fi
|
fi
|
||||||
rm -f $XTRABACKUP_PID
|
rm -f "$XTRABACKUP_PID"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
rm -f ${DATA}/${IST_FILE}
|
rm -f "${DATA}/${IST_FILE}"
|
||||||
|
|
||||||
if [[ -n $progress && -p $progress ]];then
|
if [[ -n "$progress" && -p "$progress" ]];then
|
||||||
wsrep_log_info "Cleaning up fifo file $progress"
|
wsrep_log_info "Cleaning up fifo file $progress"
|
||||||
rm $progress
|
rm $progress
|
||||||
fi
|
fi
|
||||||
@ -343,8 +357,8 @@ cleanup_donor()
|
|||||||
|
|
||||||
kill_xtrabackup()
|
kill_xtrabackup()
|
||||||
{
|
{
|
||||||
local PID=$(cat $XTRABACKUP_PID)
|
local PID=$(cat "$XTRABACKUP_PID")
|
||||||
[ -n "$PID" -a "0" != "$PID" ] && kill $PID && (kill $PID && kill -9 $PID) || :
|
[ -n "$PID" -a $PID -ne 0 ] && kill $PID && (kill $PID && kill -9 $PID) || :
|
||||||
rm -f "$XTRABACKUP_PID"
|
rm -f "$XTRABACKUP_PID"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,7 +406,7 @@ check_extra()
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
if [[ ! -x `which innobackupex` ]];then
|
if [ ! -x "$(command -v innobackupex)" ]; then
|
||||||
wsrep_log_error "innobackupex not in path: $PATH"
|
wsrep_log_error "innobackupex not in path: $PATH"
|
||||||
exit 2
|
exit 2
|
||||||
fi
|
fi
|
||||||
@ -507,10 +521,10 @@ then
|
|||||||
|
|
||||||
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"
|
||||||
touch $SST_PROGRESS_FILE
|
touch "$SST_PROGRESS_FILE"
|
||||||
|
|
||||||
if [[ ! -e ${DATA}/ibdata1 ]];then
|
if [[ ! -e "${DATA}/ibdata1" ]];then
|
||||||
incremental=0
|
incremental=0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -527,11 +541,11 @@ then
|
|||||||
MODULE="xtrabackup_sst"
|
MODULE="xtrabackup_sst"
|
||||||
|
|
||||||
# May need xtrabackup_checkpoints later on
|
# May need xtrabackup_checkpoints later on
|
||||||
rm -f ${DATA}/xtrabackup_binary ${DATA}/xtrabackup_galera_info ${DATA}/xtrabackup_logfile
|
rm -f "${DATA}/xtrabackup_binary" "${DATA}/xtrabackup_galera_info" "${DATA}/xtrabackup_logfile"
|
||||||
|
|
||||||
ADDR="${WSREP_SST_OPT_HOST}:${WSREP_SST_OPT_PORT}"
|
ADDR="${WSREP_SST_OPT_HOST}:${WSREP_SST_OPT_PORT}"
|
||||||
|
|
||||||
wait_for_listen ${WSREP_SST_OPT_PORT} ${ADDR} ${MODULE} &
|
wait_for_listen "${WSREP_SST_OPT_PORT}" "${ADDR}" "${MODULE}" &
|
||||||
|
|
||||||
trap sig_joiner_cleanup HUP PIPE INT TERM
|
trap sig_joiner_cleanup HUP PIPE INT TERM
|
||||||
trap cleanup_joiner EXIT
|
trap cleanup_joiner EXIT
|
||||||
@ -543,14 +557,14 @@ then
|
|||||||
|
|
||||||
if [[ $incremental -eq 1 ]];then
|
if [[ $incremental -eq 1 ]];then
|
||||||
BDATA=$DATA
|
BDATA=$DATA
|
||||||
DATA=$(mktemp -d)
|
DATA="$(mktemp -d)"
|
||||||
MAGIC_FILE="${DATA}/${INFO_FILE}"
|
MAGIC_FILE="${DATA}/${INFO_FILE}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
get_keys
|
get_keys
|
||||||
set +e
|
set +e
|
||||||
if [[ $encrypt -eq 1 && $sencrypted -eq 1 ]];then
|
if [[ $encrypt -eq 1 && $sencrypted -eq 1 ]];then
|
||||||
strmcmd=" $ecmd | $strmcmd"
|
strmcmd="$ecmd | $strmcmd"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
pushd ${DATA} 1>/dev/null
|
pushd ${DATA} 1>/dev/null
|
||||||
@ -584,7 +598,7 @@ then
|
|||||||
# this message should cause joiner to abort
|
# this message should cause joiner to abort
|
||||||
wsrep_log_error "xtrabackup process ended without creating '${MAGIC_FILE}'"
|
wsrep_log_error "xtrabackup process ended without creating '${MAGIC_FILE}'"
|
||||||
wsrep_log_info "Contents of datadir"
|
wsrep_log_info "Contents of datadir"
|
||||||
wsrep_log_info "$(ls -l ${DATA}/**/*)"
|
wsrep_log_info $(ls -l "${DATA}"/**/*)
|
||||||
exit 32
|
exit 32
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -600,9 +614,9 @@ then
|
|||||||
|
|
||||||
wsrep_log_info "Removing existing ib_logfile files"
|
wsrep_log_info "Removing existing ib_logfile files"
|
||||||
if [[ $incremental -ne 1 ]];then
|
if [[ $incremental -ne 1 ]];then
|
||||||
rm -f ${DATA}/ib_logfile*
|
rm -f "${DATA}/ib_logfile"*
|
||||||
else
|
else
|
||||||
rm -f ${BDATA}/ib_logfile*
|
rm -f "${BDATA}/ib_logfile"*
|
||||||
fi
|
fi
|
||||||
|
|
||||||
get_proc
|
get_proc
|
||||||
@ -619,19 +633,19 @@ then
|
|||||||
rebuildcmd="--rebuild-indexes --rebuild-threads=$nthreads"
|
rebuildcmd="--rebuild-indexes --rebuild-threads=$nthreads"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test -n "$(find ${DATA} -maxdepth 1 -type f -name '*.qp' -print -quit)";then
|
if test -n $(find "${DATA}" -maxdepth 1 -type f -name '*.qp' -print -quit); then
|
||||||
|
|
||||||
wsrep_log_info "Compressed qpress files found"
|
wsrep_log_info "Compressed qpress files found"
|
||||||
|
|
||||||
if [[ ! -x `which qpress` ]];then
|
if [ ! -x "$(command -v qpress)" ]; then
|
||||||
wsrep_log_error "qpress not found in path: $PATH"
|
wsrep_log_error "qpress not found in path: $PATH"
|
||||||
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
|
if pv --help | grep -qw -F '-F';then
|
||||||
pvopts="-f -s $count -l -N Decompression -F '%N => Rate:%r Elapsed:%t %e Progress: [%b/$count]'"
|
pvopts="-f -s $count -l -N Decompression -F '%N => Rate:%r Elapsed:%t %e Progress: [%b/$count]'"
|
||||||
else
|
else
|
||||||
pvopts="-f -s $count -l -N Decompression"
|
pvopts="-f -s $count -l -N Decompression"
|
||||||
@ -644,11 +658,11 @@ then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
wsrep_log_info "Removing existing ibdata1 file"
|
wsrep_log_info "Removing existing ibdata1 file"
|
||||||
rm -f ${DATA}/ibdata1
|
rm -f "${DATA}/ibdata1"
|
||||||
|
|
||||||
# Decompress the qpress files
|
# Decompress the qpress files
|
||||||
wsrep_log_info "Decompression with $nproc threads"
|
wsrep_log_info "Decompression with $nproc threads"
|
||||||
timeit "Decompression" "find ${DATA} -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd"
|
timeit "Decompression" "find '${DATA}' -type f -name '*.qp' -printf '%p\n%h\n' | $dcmd"
|
||||||
extcode=$?
|
extcode=$?
|
||||||
|
|
||||||
if [[ $extcode -eq 0 ]];then
|
if [[ $extcode -eq 0 ]];then
|
||||||
|
Loading…
x
Reference in New Issue
Block a user