mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 11:01:52 +01:00
31201dcbaf
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).
413 lines
13 KiB
Bash
413 lines
13 KiB
Bash
# Copyright (C) 2012-2015 Codership Oy
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; version 2 of the License.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; see the file COPYING. If not, write to the
|
|
# Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston
|
|
# MA 02110-1335 USA.
|
|
|
|
# This is a common command line parser to be sourced by other SST scripts
|
|
|
|
set -u
|
|
|
|
WSREP_SST_OPT_BYPASS=0
|
|
WSREP_SST_OPT_BINLOG=""
|
|
WSREP_SST_OPT_BINLOG_INDEX=""
|
|
WSREP_SST_OPT_DATA=""
|
|
WSREP_SST_OPT_AUTH=${WSREP_SST_OPT_AUTH:-}
|
|
WSREP_SST_OPT_USER=${WSREP_SST_OPT_USER:-}
|
|
WSREP_SST_OPT_PSWD=${WSREP_SST_OPT_PSWD:-}
|
|
WSREP_SST_OPT_DEFAULT=""
|
|
WSREP_SST_OPT_EXTRA_DEFAULT=""
|
|
WSREP_SST_OPT_SUFFIX_DEFAULT=""
|
|
WSREP_SST_OPT_SUFFIX_VALUE=""
|
|
WSREP_SST_OPT_MYSQLD=""
|
|
INNODB_DATA_HOME_DIR_ARG=""
|
|
INNODB_LOG_GROUP_HOME_ARG=""
|
|
INNODB_UNDO_DIR_ARG=""
|
|
LOG_BIN_ARG=""
|
|
|
|
while [ $# -gt 0 ]; do
|
|
case "$1" in
|
|
'--address')
|
|
readonly WSREP_SST_OPT_ADDR="$2"
|
|
#
|
|
# Break address string into host:port/path parts
|
|
#
|
|
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%%/*}
|
|
# 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=""
|
|
fi
|
|
else
|
|
readonly WSREP_SST_OPT_LSN=""
|
|
readonly WSREP_SST_OPT_SST_VER=""
|
|
fi
|
|
shift
|
|
;;
|
|
'--bypass')
|
|
WSREP_SST_OPT_BYPASS=1
|
|
;;
|
|
'--datadir')
|
|
readonly WSREP_SST_OPT_DATA="$2"
|
|
shift
|
|
;;
|
|
'--innodb-data-home-dir')
|
|
readonly INNODB_DATA_HOME_DIR_ARG="$2"
|
|
shift
|
|
;;
|
|
'--innodb-log-group-home-dir')
|
|
readonly INNODB_LOG_GROUP_HOME_ARG="$2"
|
|
shift
|
|
;;
|
|
'--innodb-undo-directory')
|
|
readonly INNODB_UNDO_DIR_ARG="$2"
|
|
shift
|
|
;;
|
|
'--log-bin')
|
|
readonly LOG_BIN_ARG="$2"
|
|
shift
|
|
;;
|
|
'--defaults-file')
|
|
readonly WSREP_SST_OPT_DEFAULT="$1=$2"
|
|
shift
|
|
;;
|
|
'--defaults-extra-file')
|
|
readonly WSREP_SST_OPT_EXTRA_DEFAULT="$1=$2"
|
|
shift
|
|
;;
|
|
'--defaults-group-suffix')
|
|
readonly WSREP_SST_OPT_SUFFIX_DEFAULT="$1=$2"
|
|
readonly WSREP_SST_OPT_SUFFIX_VALUE="$2"
|
|
shift
|
|
;;
|
|
'--host')
|
|
readonly WSREP_SST_OPT_HOST="$2"
|
|
shift
|
|
;;
|
|
'--local-port')
|
|
readonly WSREP_SST_OPT_LPORT="$2"
|
|
shift
|
|
;;
|
|
'--parent')
|
|
readonly WSREP_SST_OPT_PARENT="$2"
|
|
shift
|
|
;;
|
|
'--password')
|
|
WSREP_SST_OPT_PSWD="$2"
|
|
shift
|
|
;;
|
|
'--port')
|
|
readonly WSREP_SST_OPT_PORT="$2"
|
|
shift
|
|
;;
|
|
'--role')
|
|
readonly WSREP_SST_OPT_ROLE="$2"
|
|
shift
|
|
;;
|
|
'--socket')
|
|
readonly WSREP_SST_OPT_SOCKET="$2"
|
|
shift
|
|
;;
|
|
'--user')
|
|
WSREP_SST_OPT_USER="$2"
|
|
shift
|
|
;;
|
|
'--gtid')
|
|
readonly WSREP_SST_OPT_GTID="$2"
|
|
shift
|
|
;;
|
|
'--binlog')
|
|
WSREP_SST_OPT_BINLOG="$2"
|
|
shift
|
|
;;
|
|
'--binlog-index')
|
|
WSREP_SST_OPT_BINLOG_INDEX="$2"
|
|
shift
|
|
;;
|
|
'--gtid-domain-id')
|
|
readonly WSREP_SST_OPT_GTID_DOMAIN_ID="$2"
|
|
shift
|
|
;;
|
|
'--mysqld-args')
|
|
original_cmd=""
|
|
shift
|
|
while [ $# -gt 0 ]; do
|
|
option=${1%%=*}
|
|
if [[ "$option" != "--defaults-file" && \
|
|
"$option" != "--defaults-extra-file" && \
|
|
"$option" != "--defaults-group-suffix" && \
|
|
"$option" != "--port" && \
|
|
"$option" != "--socket" ]]; then
|
|
value=${1#*=}
|
|
case "$option" in
|
|
'--innodb-data-home-dir')
|
|
if [ -z "$INNODB_DATA_HOME_DIR_ARG" ]; then
|
|
readonly INNODB_DATA_HOME_DIR_ARG="$value"
|
|
fi
|
|
;;
|
|
'--innodb-log-group-home-dir')
|
|
if [ -z "$INNODB_LOG_GROUP_HOME_ARG" ]; then
|
|
readonly INNODB_LOG_GROUP_HOME_ARG="$value"
|
|
fi
|
|
;;
|
|
'--innodb-undo-directory')
|
|
if [ -z "$INNODB_UNDO_DIR_ARG" ]; then
|
|
readonly INNODB_UNDO_DIR_ARG="$value"
|
|
fi
|
|
;;
|
|
'--log-bin')
|
|
if [ -z "$LOG_BIN_ARG" ]; then
|
|
readonly LOG_BIN_ARG="$value"
|
|
fi
|
|
;;
|
|
esac
|
|
if [ -z "$original_cmd" ]; then
|
|
original_cmd="$1"
|
|
else
|
|
original_cmd="$original_cmd $1"
|
|
fi
|
|
fi
|
|
shift
|
|
done
|
|
readonly WSREP_SST_OPT_MYSQLD="$original_cmd"
|
|
break
|
|
;;
|
|
*) # must be command
|
|
# usage
|
|
# exit 1
|
|
;;
|
|
esac
|
|
shift
|
|
done
|
|
readonly WSREP_SST_OPT_BYPASS
|
|
readonly WSREP_SST_OPT_BINLOG
|
|
readonly WSREP_SST_OPT_BINLOG_INDEX
|
|
|
|
if [ -n "${WSREP_SST_OPT_ADDR_PORT:-}" ]; then
|
|
if [ -n "${WSREP_SST_OPT_PORT:-}" ]; then
|
|
if [ "$WSREP_SST_OPT_PORT" != "$WSREP_SST_OPT_ADDR_PORT" ]; then
|
|
echo "WSREP_SST: [ERROR] port in --port=$WSREP_SST_OPT_PORT differs from port in --address=$WSREP_SST_OPT_ADDR" >&2
|
|
exit 2
|
|
fi
|
|
else
|
|
readonly WSREP_SST_OPT_PORT="$WSREP_SST_OPT_ADDR_PORT"
|
|
fi
|
|
fi
|
|
|
|
# try to use my_print_defaults, mysql and mysqldump that come with the sources
|
|
# (for MTR suite)
|
|
SCRIPTS_DIR="$(cd $(dirname "$0"); pwd -P)"
|
|
EXTRA_DIR="$SCRIPTS_DIR/../extra"
|
|
CLIENT_DIR="$SCRIPTS_DIR/../client"
|
|
|
|
if [ -x "$CLIENT_DIR/mysql" ]; then
|
|
MYSQL_CLIENT="$CLIENT_DIR/mysql"
|
|
else
|
|
MYSQL_CLIENT=$(which mysql)
|
|
fi
|
|
|
|
if [ -x "$CLIENT_DIR/mysqldump" ]; then
|
|
MYSQLDUMP="$CLIENT_DIR/mysqldump"
|
|
else
|
|
MYSQLDUMP=$(which mysqldump)
|
|
fi
|
|
|
|
if [ -x "$SCRIPTS_DIR/my_print_defaults" ]; then
|
|
MY_PRINT_DEFAULTS="$SCRIPTS_DIR/my_print_defaults"
|
|
elif [ -x "$EXTRA_DIR/my_print_defaults" ]; then
|
|
MY_PRINT_DEFAULTS="$EXTRA_DIR/my_print_defaults"
|
|
else
|
|
MY_PRINT_DEFAULTS=$(which my_print_defaults)
|
|
fi
|
|
|
|
wsrep_defaults="$WSREP_SST_OPT_DEFAULT"
|
|
if [ -n "$wsrep_defaults" ]; then
|
|
wsrep_defaults="$wsrep_defaults "
|
|
fi
|
|
wsrep_defaults="$wsrep_defaults$WSREP_SST_OPT_EXTRA_DEFAULT"
|
|
if [ -n "$wsrep_defaults" ]; then
|
|
wsrep_defaults="$wsrep_defaults "
|
|
fi
|
|
readonly WSREP_SST_OPT_CONF="$wsrep_defaults$WSREP_SST_OPT_SUFFIX_DEFAULT"
|
|
readonly MY_PRINT_DEFAULTS="$MY_PRINT_DEFAULTS $WSREP_SST_OPT_CONF"
|
|
|
|
wsrep_auth_not_set()
|
|
{
|
|
[ -z "$WSREP_SST_OPT_AUTH" -o "$WSREP_SST_OPT_AUTH" = "(null)" ]
|
|
}
|
|
|
|
# State Snapshot Transfer authentication password was displayed in the ps output. Bug fixed #1200727.
|
|
if $MY_PRINT_DEFAULTS sst | grep -q "wsrep_sst_auth"; then
|
|
if wsrep_auth_not_set; then
|
|
WSREP_SST_OPT_AUTH=$($MY_PRINT_DEFAULTS sst | grep -- "--wsrep_sst_auth" | cut -d= -f2)
|
|
fi
|
|
fi
|
|
readonly WSREP_SST_OPT_AUTH
|
|
|
|
# Splitting AUTH into potential user:password pair
|
|
if ! wsrep_auth_not_set
|
|
then
|
|
WSREP_SST_OPT_USER="${WSREP_SST_OPT_AUTH%%:*}"
|
|
WSREP_SST_OPT_PSWD="${WSREP_SST_OPT_AUTH##*:}"
|
|
fi
|
|
readonly WSREP_SST_OPT_USER
|
|
readonly WSREP_SST_OPT_PSWD
|
|
|
|
if [ -n "${WSREP_SST_OPT_DATA:-}" ]
|
|
then
|
|
SST_PROGRESS_FILE="$WSREP_SST_OPT_DATA/sst_in_progress"
|
|
else
|
|
SST_PROGRESS_FILE=""
|
|
fi
|
|
|
|
wsrep_log()
|
|
{
|
|
# echo everything to stderr so that it gets into common error log
|
|
# deliberately made to look different from the rest of the log
|
|
local readonly tst="$(date +%Y%m%d\ %H:%M:%S.%N | cut -b -21)"
|
|
echo "WSREP_SST: $* ($tst)" >&2
|
|
}
|
|
|
|
wsrep_log_error()
|
|
{
|
|
wsrep_log "[ERROR] $*"
|
|
}
|
|
|
|
wsrep_log_warning()
|
|
{
|
|
wsrep_log "[WARNING] $*"
|
|
}
|
|
|
|
wsrep_log_info()
|
|
{
|
|
wsrep_log "[INFO] $*"
|
|
}
|
|
|
|
wsrep_cleanup_progress_file()
|
|
{
|
|
[ -n "${SST_PROGRESS_FILE:-}" ] && rm -f "$SST_PROGRESS_FILE" 2>/dev/null || true
|
|
}
|
|
|
|
wsrep_check_program()
|
|
{
|
|
local prog=$1
|
|
|
|
if ! which $prog >/dev/null
|
|
then
|
|
echo "'$prog' not found in PATH"
|
|
return 2 # no such file or directory
|
|
fi
|
|
}
|
|
|
|
wsrep_check_programs()
|
|
{
|
|
local ret=0
|
|
|
|
while [ $# -gt 0 ]
|
|
do
|
|
wsrep_check_program $1 || ret=$?
|
|
shift
|
|
done
|
|
|
|
return $ret
|
|
}
|
|
|
|
#
|
|
# user can specify mariabackup specific settings that will be used during sst
|
|
# process like encryption, etc.....
|
|
# parse such configuration option. (group for xb settings is [sst] in my.cnf
|
|
#
|
|
# 1st param: group (config file section like sst) or my_print_defaults argument (like --mysqld)
|
|
# 2nd param: var : name of the variable in the section, e.g. server-id
|
|
# 3rd param: - : default value for the param
|
|
parse_cnf()
|
|
{
|
|
local group=$1
|
|
local var=$2
|
|
local reval=""
|
|
|
|
# normalize the variable names specified in cnf file (user can use _ or - for example log-bin or log_bin)
|
|
# then search for needed variable
|
|
# finally get the variable value (if variables has been specified multiple time use the last value only)
|
|
|
|
reval=$($MY_PRINT_DEFAULTS "${group}" | awk -v var="${var}" 'BEGIN { OFS=FS="=" } { gsub(/_/,"-",$1); if ( $1=="--"var) lastval=substr($0,length($1)+2) } END { print lastval}')
|
|
|
|
# use default if we haven't found a value
|
|
if [ -z "$reval" ]; then
|
|
[ -n "$3" ] && reval=$3
|
|
fi
|
|
echo $reval
|
|
}
|