summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulius Goryavsky <julius.goryavsky@mariadb.com>2020-10-13 13:33:47 +0200
committerJulius Goryavsky <julius.goryavsky@mariadb.com>2020-10-15 13:49:22 +0200
commit31201dcbaf0f35a4fccb83855c1e1157f9532b31 (patch)
treed6be2e4ce6734d986bd4b5aef1ef4f6fea9433d9
parent24c5af6758091dd4d9513e385ac76618c64ba0d2 (diff)
downloadmariadb-git-31201dcbaf0f35a4fccb83855c1e1157f9532b31.tar.gz
MDEV-21770: `galera_3nodes.galera_ipv6_mariabackup` fails
This patch fixes several flaws in the SST scripts that cause failures while running tests that use version 6 IP addresses for cluster nodes. First, if the netcat utility is used for streaming (but not socat), then in accordance with its command line syntax, we need to remove the square brackets around the IPv6 address. However, for socat, the address must contain square brackets, as before. Secondly, if an IPv6 address is used, then from the joiner side for a number of systems (such as Debian) we need to explicitly specify the "-6" option, otherwise a listening socket with an IPv6 address may not be created. This patch also contains code improvements in the wsrep_sst_common. Changed the code that pars the connection address - fixed the shortcomings that sometimes led to incorrect parsing of parameters when using shells other than the latest versions of bash. Also, this patch removes the duplicate code that is intended for parsing the connection address and which was located in the wsrep_sst_mariabackup file, since all the necessary actions have already been done in wsrep_sst_common and there they are done in such a way that any shell is supported, not just bash. The fix does not require separate tests, since all the necessary tests are already present in the galera_3nodes suite. On the contrary, after this fix, tests using IPv6 addresses can be removed from the disabled list (this will be done in a separate commit related to MDEV-23659).
-rw-r--r--mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.cnf5
-rw-r--r--scripts/wsrep_sst_common.sh46
-rw-r--r--scripts/wsrep_sst_mariabackup.sh63
3 files changed, 83 insertions, 31 deletions
diff --git a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.cnf b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.cnf
index 3861b17557d..8432b1c368c 100644
--- a/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.cnf
+++ b/mysql-test/suite/galera_3nodes/t/galera_ipv6_mariabackup.cnf
@@ -10,6 +10,7 @@ wsrep-cluster-address=gcomm://
wsrep_provider_options='base_host=[::1];base_port=@mysqld.1.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.1.#galera_port;ist.recv_addr=[::1]:@mysqld.1.#ist_port'
wsrep_sst_receive_address='[::1]:@mysqld.1.#sst_port'
wsrep_node_incoming_address='[::1]:@mysqld.1.port'
+wsrep_node_name=node_1
bind-address=::
[mysqld.2]
@@ -17,6 +18,8 @@ wsrep_cluster_address='gcomm://[::1]:@mysqld.1.#galera_port'
wsrep_provider_options='base_host=[::1];base_port=@mysqld.2.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.2.#galera_port;ist.recv_addr=[::1]:@mysqld.2.#ist_port'
wsrep_sst_receive_address='[::1]:@mysqld.2.#sst_port'
wsrep_node_incoming_address='[::1]:@mysqld.2.port'
+wsrep_node_name=node_2
+wsrep_sst_donor=node_1
bind-address=::
[mysqld.3]
@@ -24,6 +27,8 @@ wsrep_cluster_address='gcomm://[::1]:@mysqld.1.#galera_port'
wsrep_provider_options='base_host=[::1];base_port=@mysqld.3.#galera_port;gmcast.listen_addr=tcp://[::]:@mysqld.3.#galera_port;ist.recv_addr=[::1]:@mysqld.3.#ist_port'
wsrep_sst_receive_address='[::1]:@mysqld.3.#sst_port'
wsrep_node_incoming_address='[::1]:@mysqld.3.port'
+wsrep_node_name=node_3
+wsrep_sst_donor=node_1
bind-address=::
[SST]
diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
index ee7817a1550..f5adf0b0fd8 100644
--- a/scripts/wsrep_sst_common.sh
+++ b/scripts/wsrep_sst_common.sh
@@ -45,28 +45,68 @@ case "$1" in
case "${WSREP_SST_OPT_ADDR}" in
\[*)
# IPv6
+ # Remove the starting and ending square brackets, if present:
addr_no_bracket=${WSREP_SST_OPT_ADDR#\[}
readonly WSREP_SST_OPT_HOST_UNESCAPED=${addr_no_bracket%%\]*}
+ # Square brackets are needed in most cases:
readonly WSREP_SST_OPT_HOST="[${WSREP_SST_OPT_HOST_UNESCAPED}]"
+ # Some utilities and subsequent code require an address
+ # without square brackets:
readonly WSREP_SST_OPT_HOST_ESCAPED="\\[${WSREP_SST_OPT_HOST_UNESCAPED}\\]"
+ readonly WSREP_SST_OPT_HOST_IPv6=1
;;
*)
readonly WSREP_SST_OPT_HOST=${WSREP_SST_OPT_ADDR%%[:/]*}
readonly WSREP_SST_OPT_HOST_UNESCAPED=$WSREP_SST_OPT_HOST
readonly WSREP_SST_OPT_HOST_ESCAPED=$WSREP_SST_OPT_HOST
+ readonly WSREP_SST_OPT_HOST_IPv6=0
;;
esac
+ # Let's remove the leading part that contains the host address:
remain=${WSREP_SST_OPT_ADDR#${WSREP_SST_OPT_HOST_ESCAPED}}
+ # Let's remove the ":" character that separates the port number
+ # from the hostname:
remain=${remain#:}
+ # Extract the port number from the address - all characters
+ # up to "/" (if present):
readonly WSREP_SST_OPT_ADDR_PORT=${remain%%/*}
- remain=${remain#*/}
- readonly WSREP_SST_OPT_MODULE=${remain%%/*}
- readonly WSREP_SST_OPT_PATH=${WSREP_SST_OPT_ADDR#*/}
+ # If the "/" character is present, then the path is not empty:
+ if [ "${remain#*/}" != "${remain}" ]; then
+ # This operation removes everything up to the "/" character,
+ # effectively removing the port number from the string:
+ readonly WSREP_SST_OPT_PATH=${remain#*/}
+ else
+ readonly WSREP_SST_OPT_PATH=""
+ fi
+ # The rest of the string is the same as the path (for now):
+ remain=${WSREP_SST_OPT_PATH}
+ # If there is one more "/" in the string, then everything before
+ # it will be the module name, otherwise the module name is empty:
+ if [ "${remain%%/*}" != "${remain}" ]; then
+ # This operation removes the tail after the very first
+ # occurrence of the "/" character (inclusively):
+ readonly WSREP_SST_OPT_MODULE=${remain%%/*}
+ else
+ readonly WSREP_SST_OPT_MODULE=""
+ fi
+ # Remove the module name part from the string, which ends with "/":
remain=${WSREP_SST_OPT_PATH#*/}
+ # If the rest of the string does not match the original, then there
+ # was something else besides the module name:
if [ "$remain" != "${WSREP_SST_OPT_PATH}" ]; then
+ # Extract the part that matches the LSN by removing all
+ # characters starting from the very first "/":
readonly WSREP_SST_OPT_LSN=${remain%%/*}
+ # Exctract everything after the first occurrence of
+ # the "/" character in the string:
remain=${remain#*/}
+ # If the remainder does not match the original string,
+ # then there is something else (the version number in
+ # our case):
if [ "$remain" != "${WSREP_SST_OPT_LSN}" ]; then
+ # Let's extract the version number by removing the tail
+ # after the very first occurence of the "/" character
+ # (inclusively):
readonly WSREP_SST_OPT_SST_VER=${remain%%/*}
else
readonly WSREP_SST_OPT_SST_VER=""
diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh
index ef2a3b66de8..85138c3c0be 100644
--- a/scripts/wsrep_sst_mariabackup.sh
+++ b/scripts/wsrep_sst_mariabackup.sh
@@ -189,27 +189,48 @@ get_transfer()
if nc -h 2>&1 | grep -q ncat;then
# Ncat
tcmd="nc -l ${TSST_PORT}"
- elif nc -h 2>&1 | grep -q -- '-d\>';then
+ elif nc -h 2>&1 | grep -qw -- '-d\>';then
# Debian netcat
- tcmd="nc -dl ${TSST_PORT}"
+ if [ $WSREP_SST_OPT_HOST_IPv6 -eq 1 ];then
+ # When host is not explicitly specified (when only the port
+ # is specified) netcat can only bind to an IPv4 address if
+ # the "-6" option is not explicitly specified:
+ tcmd="nc -dl -6 ${TSST_PORT}"
+ else
+ tcmd="nc -dl ${TSST_PORT}"
+ fi
else
# traditional netcat
tcmd="nc -l -p ${TSST_PORT}"
fi
else
+ # Check to see if netcat supports the '-N' flag.
+ # -N Shutdown the network socket after EOF on stdin
+ # If it supports the '-N' flag, then we need to use the '-N'
+ # flag, otherwise the transfer will stay open after the file
+ # transfer and cause the command to timeout.
+ # Older versions of netcat did not need this flag and will
+ # return an error if the flag is used.
+ #
+ tcmd_extra=""
+ if nc -h 2>&1 | grep -qw -- -N; then
+ tcmd_extra+="-N"
+ wsrep_log_info "Using nc -N"
+ fi
+
+ # netcat doesn't understand [] around IPv6 address
if nc -h 2>&1 | grep -q ncat;then
# Ncat
- tcmd="nc ${REMOTEIP} ${TSST_PORT}"
- elif nc -h 2>&1 | grep -q -- '-d\>';then
+ wsrep_log_info "Using Ncat as streamer"
+ tcmd="nc ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}"
+ elif nc -h 2>&1 | grep -qw -- '-d\>';then
# Debian netcat
- if nc -h 2>&1 | grep -q -- '-N\>';then
- tcmd="nc -N ${REMOTEIP} ${TSST_PORT}"
- else
- tcmd="nc ${REMOTEIP} ${TSST_PORT}"
- fi
+ wsrep_log_info "Using Debian netcat as streamer"
+ tcmd="nc ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}"
else
# traditional netcat
- tcmd="nc -q0 ${REMOTEIP} ${TSST_PORT}"
+ wsrep_log_info "Using traditional netcat as streamer"
+ tcmd="nc -q0 ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}"
fi
fi
else
@@ -527,25 +548,11 @@ kill_xtrabackup()
setup_ports()
{
+ SST_PORT=${WSREP_SST_OPT_ADDR_PORT}
if [[ "$WSREP_SST_OPT_ROLE" == "donor" ]];then
- if [ "${WSREP_SST_OPT_ADDR#\[}" != "$WSREP_SST_OPT_ADDR" ]; then
- remain=$(echo $WSREP_SST_OPT_ADDR | awk -F '\\][:/]' '{ print $2 }')
- REMOTEIP=$(echo $WSREP_SST_OPT_ADDR | awk -F '\\]:' '{ print $1 }')"]"
- SST_PORT=$(echo $remain | awk -F '[:/]' '{ print $1 }')
- lsn=$(echo $remain | awk -F '[:/]' '{ print $3 }')
- sst_ver=$(echo $remain | awk -F '[:/]' '{ print $4 }')
- else
- SST_PORT=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $2 }')
- REMOTEIP=$(echo $WSREP_SST_OPT_ADDR | awk -F ':' '{ print $1 }')
- lsn=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $4 }')
- sst_ver=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $5 }')
- fi
- else
- if [ "${WSREP_SST_OPT_ADDR#\[}" != "$WSREP_SST_OPT_ADDR" ]; then
- SST_PORT=$(echo ${WSREP_SST_OPT_ADDR} | awk -F '\\]:' '{ print $2 }')
- else
- SST_PORT=$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $2 }')
- fi
+ REMOTEIP=${WSREP_SST_OPT_HOST}
+ lsn=${WSREP_SST_OPT_LSN}
+ sst_ver=${WSREP_SST_OPT_SST_VER}
fi
}