Skip to content
Permalink
Browse files

MW-366 Improved support for IPv6 networks - made mysqld and SST scrip…

…ts to recognize []-escaped IPv6 addresses - pulled in latest Percona and MariaDB updates to SST scripts - instruct netcat and socat in wsrep_sst_xtrabackup-v2 to listen on IPv6 socket via sockopt parameter in the [sst] section of my.cnf

In summary, wsrep_node_address and wsrep_sst_receive_address can now
be set to IPv6 addresses escaped by []. Rsync SST works out ouf the
box thanks to rsync daemon listening on both IPv4 and IPv6 sockets by
default. For xtrabackup SST onver IPv6 one needs to set sockopt in
the [sst] section of joiner's configuration file to ",pf=ip6" if
using socat as a streamer or to "-6" if using netcat.
  • Loading branch information...
Alexey Yurchenko authored and janlindstrom committed Mar 3, 2017
1 parent 5108ded commit 83664e21e4fb6755c8c0c90d3dee8819d36928c9
@@ -30,6 +30,22 @@ while [ $# -gt 0 ]; do
case "$1" in
'--address')
readonly WSREP_SST_OPT_ADDR="$2"
#
# Break address string into host:port/path parts
#
if echo $WSREP_SST_OPT_ADDR | grep -qe '^\[.*\]'
then
# IPv6 notation
readonly WSREP_SST_OPT_HOST=${WSREP_SST_OPT_ADDR/\]*/\]}
readonly WSREP_SST_OPT_HOST_UNESCAPED=$(echo $WSREP_SST_OPT_HOST | \
cut -d '[' -f 2 | cut -d ']' -f 1)
else
# "traditional" notation
readonly WSREP_SST_OPT_HOST=${WSREP_SST_OPT_ADDR%%[:/]*}
fi
readonly WSREP_SST_OPT_PORT=$(echo $WSREP_SST_OPT_ADDR | \
cut -d ']' -f 2 | cut -s -d ':' -f 2 | cut -d '/' -f 1)
readonly WSREP_SST_OPT_PATH=${WSREP_SST_OPT_ADDR#*/}
shift
;;
'--bypass')
@@ -169,6 +185,11 @@ wsrep_log_error()
wsrep_log "[ERROR] $*"
}

wsrep_log_warning()
{
wsrep_log "[WARNING] $*"
}

wsrep_log_info()
{
wsrep_log "[INFO] $*"
@@ -202,3 +223,39 @@ wsrep_check_programs()

return $ret
}

#
# user can specify xtrabackup 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 : name of the config file section, e.g. 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=""

# print the default settings for given group using my_print_default.
# normalize the variable names specified in cnf file (user can use _ or - for example log-bin or log_bin)
# then grep for needed variable
# finally get the variable value (if variables has been specified multiple time use the last value only)

# look in group+suffix
if [[ -n $WSREP_SST_OPT_CONF_SUFFIX ]]; then
reval=$($MY_PRINT_DEFAULTS -c $WSREP_SST_OPT_CONF "${group}${WSREP_SST_OPT_CONF_SUFFIX}" | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2- | tail -1)
fi

# look in group
if [[ -z $reval ]]; then

This comment has been minimized.

Copy link
@darkain

darkain Sep 25, 2017

Contributor

This is causing errors on default Debian 9 installs. Double-bracket IF statements are not fully portable to all platforms.

/usr/local/mysql/bin/wsrep_sst_rsync: 258: /usr/local/mysql/bin/wsrep_sst_rsync: [[: not found /usr/local/mysql/bin/wsrep_sst_rsync: 263: /usr/local/mysql/bin/wsrep_sst_rsync: [[: not found /usr/local/mysql/bin/wsrep_sst_rsync: 268: /usr/local/mysql/bin/wsrep_sst_rsync: [[: not found

NOTE: Line numbers are for MariaDB 10.2.9, but this would apply all the way back to this 10.0 patch.

This comment has been minimized.

Copy link
@vuvova

vuvova Sep 26, 2017

Member

Thanks. I've reported it as https://jira.mariadb.org/browse/MDEV-13909

Next time feel free to report a bug at jira.mariadb.org yourself 😄

reval=$($MY_PRINT_DEFAULTS -c $WSREP_SST_OPT_CONF $group | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2- | tail -1)
fi

# use default if we haven't found a value
if [[ -z $reval ]]; then
[[ -n $3 ]] && reval=$3
fi
echo $reval
}
@@ -30,6 +30,7 @@ local_ip()
{
[ "$1" = "127.0.0.1" ] && 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
@@ -105,8 +106,9 @@ GTID_BINLOG_STATE=$(echo "SHOW GLOBAL VARIABLES LIKE 'gtid_binlog_state'" |\
$MYSQL_CLIENT $AUTH -S$WSREP_SST_OPT_SOCKET --disable-reconnect --connect_timeout=10 |\
tail -1 | awk -F ' ' '{ print $2 }')

MYSQL="$MYSQL_CLIENT $AUTH -h$WSREP_SST_OPT_HOST -P$WSREP_SST_OPT_PORT "\
"--disable-reconnect --connect_timeout=10"
MYSQL="$MYSQL_CLIENT --defaults-extra-file=$WSREP_SST_OPT_CONF "\
"$AUTH -h${WSREP_SST_OPT_HOST_UNESCAPED:-$WSREP_SST_OPT_HOST} "\
"-P$WSREP_SST_OPT_PORT --disable-reconnect --connect_timeout=10"

# Check if binary logging is enabled on the joiner node.
# Note: SELECT cannot be used at this point.
@@ -67,6 +67,11 @@ check_pid_and_port()
exit 2 # ENOENT
fi

if ! which lsof > /dev/null; then
wsrep_log_error "lsof tool not found in PATH! Make sure you have it installed."
exit 2 # ENOENT
fi

local port_info=$(lsof -i :$rsync_port -Pn 2>/dev/null | \
grep "(LISTEN)")
local is_rsync=$(echo $port_info | \
@@ -97,10 +102,19 @@ fi
WSREP_LOG_DIR=${WSREP_LOG_DIR:-""}
# if WSREP_LOG_DIR env. variable is not set, try to get it from my.cnf
if [ -z "$WSREP_LOG_DIR" ]; then
WSREP_LOG_DIR=$($MY_PRINT_DEFAULTS --defaults-file \
"$WSREP_SST_OPT_CONF" mysqld server mysqld-10.0 mariadb mariadb-10.0 \
| grep -- '--innodb[-_]log[-_]group[-_]home[-_]dir=' \
| cut -b 29- )
WSREP_LOG_DIR=$(parse_cnf mariadb-10.0 innodb_log_group_home_dir "")
fi
if [ -z "$WSREP_LOG_DIR" ]; then
WSREP_LOG_DIR=$(parse_cnf mysqld innodb_log_group_home_dir "")
fi
if [ -z "$WSREP_LOG_DIR" ]; then
WSREP_LOG_DIR=$(parse_cnf server innodb_log_group_home_dir "")
fi
if [ -z "$WSREP_LOG_DIR" ]; then
WSREP_LOG_DIR=$(parse_cnf mariadb innodb_log_group_home_dir "")
fi
if [ -z "$WSREP_LOG_DIR" ]; then
WSREP_LOG_DIR=$(parse_cnf mysqld-10.0 innodb_log_group_home_dir "")
fi

if [ -n "$WSREP_LOG_DIR" ]; then
@@ -208,8 +222,8 @@ then
[ "$OS" == "Linux" ] && count=$(grep -c processor /proc/cpuinfo)
[ "$OS" == "Darwin" -o "$OS" == "FreeBSD" ] && count=$(sysctl -n hw.ncpu)

find . -maxdepth 1 -mindepth 1 -type d -not -name "lost+found" -print0 | \
xargs -I{} -0 -P $count \
find . -maxdepth 1 -mindepth 1 -type d -not -name "lost+found" \
-print0 | xargs -I{} -0 -P $count \
rsync --owner --group --perms --links --specials \
--ignore-times --inplace --recursive --delete --quiet \
$WHOLE_FILE_OPT --exclude '*/ib_logfile*' "$WSREP_SST_OPT_DATA"/{}/ \
@@ -252,25 +266,24 @@ then
fi
rm -rf "$RSYNC_PID"

ADDR=$WSREP_SST_OPT_ADDR
RSYNC_PORT=$(echo $ADDR | awk -F ':' '{ print $2 }')
if [ -z "$RSYNC_PORT" ]
then
RSYNC_PORT=4444
ADDR="$(echo $ADDR | awk -F ':' '{ print $1 }'):$RSYNC_PORT"
fi

trap "exit 32" HUP PIPE
trap "exit 3" INT TERM ABRT
trap cleanup_joiner EXIT

RSYNC_CONF="$WSREP_SST_OPT_DATA/$MODULE.conf"

if [ -n "${MYSQL_TMP_DIR:-}" ] ; then
SILENT="log file = $MYSQL_TMP_DIR/rsyncd.log"
else
SILENT=""
fi

cat << EOF > "$RSYNC_CONF"
pid file = $RSYNC_PID
use chroot = no
read only = no
timeout = 300
$SILENT
[$MODULE]
path = $WSREP_SST_OPT_DATA
[$MODULE-log_dir]
@@ -280,6 +293,7 @@ EOF
# rm -rf "$DATA"/ib_logfile* # we don't want old logs around

# listen at all interfaces (for firewalled setups)
readonly RSYNC_PORT=${WSREP_SST_OPT_PORT:-4444}
rsync --daemon --no-detach --port $RSYNC_PORT --config "$RSYNC_CONF" &
RSYNC_REAL_PID=$!

@@ -288,7 +302,7 @@ EOF
sleep 0.2
done

echo "ready $ADDR/$MODULE"
echo "ready $WSREP_SST_OPT_HOST:$RSYNC_PORT/$MODULE"

# wait for SST to complete by monitoring magic file
while [ ! -r "$MAGIC_FILE" ] && check_pid "$RSYNC_PID" && \

0 comments on commit 83664e2

Please sign in to comment.
You can’t perform that action at this time.