summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2017-08-21 13:35:00 +0300
committerJan Lindström <jan.lindstrom@mariadb.com>2017-08-21 13:35:00 +0300
commitc23efc7d50530570e6c13207f3c76adcb9237346 (patch)
tree7c57ca7a1dc61590019abb5608c2b19327f8ed7c /scripts
parent06106c01481401b6d7ef4309391ca2f66242cc85 (diff)
parentf1af2114993f884b1a6dc34fb1d972ead08f1966 (diff)
downloadmariadb-git-c23efc7d50530570e6c13207f3c76adcb9237346.tar.gz
Merge remote-tracking branch 'origin/10.0-galera' into 10.1
Diffstat (limited to 'scripts')
-rw-r--r--scripts/wsrep_sst_common.sh57
-rw-r--r--scripts/wsrep_sst_mysqldump.sh6
-rw-r--r--scripts/wsrep_sst_rsync.sh32
-rw-r--r--scripts/wsrep_sst_xtrabackup-v2.sh396
4 files changed, 376 insertions, 115 deletions
diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh
index f173a861e85..723fd311f88 100644
--- a/scripts/wsrep_sst_common.sh
+++ b/scripts/wsrep_sst_common.sh
@@ -32,6 +32,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')
@@ -181,6 +197,11 @@ wsrep_log_error()
wsrep_log "[ERROR] $*"
}
+wsrep_log_warning()
+{
+ wsrep_log "[WARNING] $*"
+}
+
wsrep_log_info()
{
wsrep_log "[INFO] $*"
@@ -214,3 +235,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
+ 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
+}
diff --git a/scripts/wsrep_sst_mysqldump.sh b/scripts/wsrep_sst_mysqldump.sh
index 5f25c2c9d13..59d9a3c5c9c 100644
--- a/scripts/wsrep_sst_mysqldump.sh
+++ b/scripts/wsrep_sst_mysqldump.sh
@@ -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
@@ -116,8 +117,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.
diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh
index 10d6896accd..c6e8a7ef4e1 100644
--- a/scripts/wsrep_sst_rsync.sh
+++ b/scripts/wsrep_sst_rsync.sh
@@ -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,9 +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 --mysqld \
- | 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
@@ -222,8 +237,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"/{}/ \
@@ -284,9 +299,9 @@ then
RSYNC_CONF="$WSREP_SST_OPT_DATA/$MODULE.conf"
if [ -n "${MYSQL_TMP_DIR:-}" ] ; then
- SILENT="log file = $MYSQL_TMP_DIR/rsynd.log"
+ SILENT="log file = $MYSQL_TMP_DIR/rsyncd.log"
else
- SILENT=""
+ SILENT=""
fi
cat << EOF > "$RSYNC_CONF"
@@ -304,6 +319,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=$!
@@ -312,7 +328,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" && \
diff --git a/scripts/wsrep_sst_xtrabackup-v2.sh b/scripts/wsrep_sst_xtrabackup-v2.sh
index 565e62e4dbe..78a7d76da09 100644
--- a/scripts/wsrep_sst_xtrabackup-v2.sh
+++ b/scripts/wsrep_sst_xtrabackup-v2.sh
@@ -35,6 +35,7 @@ XTRABACKUP_PID=""
SST_PORT=""
REMOTEIP=""
REMOTEHOST=""
+tca=""
tcert=""
tpem=""
tkey=""
@@ -48,7 +49,6 @@ rlimit=""
# Initially
stagemsg="${WSREP_SST_OPT_ROLE}"
cpat=""
-speciald=1
ib_home_dir=""
ib_log_dir=""
ib_undo_dir=""
@@ -72,6 +72,11 @@ xtmpdir=""
scomp=""
sdecomp=""
+ssl_dhparams=""
+
+ssl_cert=""
+ssl_ca=""
+ssl_key=""
# Required for backup locks
# For backup locks it is 1 sent by joiner
@@ -151,6 +156,10 @@ get_keys()
if [[ -z $ekey ]];then
ecmd="xbcrypt --encrypt-algo=$ealgo --encrypt-key-file=$ekeyfile"
else
+ wsrep_log_warning "Using the 'encrypt-key' option causes the encryption key"
+ wsrep_log_warning "to be set via the command-line and is considered insecure."
+ wsrep_log_warning "It is recommended to use the 'encrypt-key-file' option instead."
+
ecmd="xbcrypt --encrypt-algo=$ealgo --encrypt-key=$ekey"
fi
@@ -161,6 +170,86 @@ get_keys()
stagemsg+="-XB-Encrypted"
}
+#
+# If the ssl_dhparams variable is already set, uses that as a source
+# of dh parameters for OpenSSL. Otherwise, looks for dhparams.pem in the
+# datadir, and creates it there if it can't find the file.
+# No input parameters
+#
+check_for_dhparams()
+{
+ if [[ -z "$ssl_dhparams" ]]; then
+ if ! [[ -r "$DATA/dhparams.pem" ]]; then
+ wsrep_check_programs openssl
+ wsrep_log_info "Could not find dhparams file, creating $DATA/dhparams.pem"
+
+ if ! openssl dhparam -out "$DATA/dhparams.pem" 2048 >/dev/null 2>&1
+ then
+ wsrep_log_error "******** FATAL ERROR ********************************* "
+ wsrep_log_error "* Could not create the dhparams.pem file with OpenSSL. "
+ wsrep_log_error "****************************************************** "
+ exit 22
+ fi
+ fi
+ ssl_dhparams="$DATA/dhparams.pem"
+ fi
+}
+
+#
+# verifies that the certificate matches the private key
+# doing this will save us having to wait for a timeout that would
+# otherwise occur.
+#
+# 1st param: path to the cert
+# 2nd param: path to the private key
+#
+verify_cert_matches_key()
+{
+ local cert_path=$1
+ local key_path=$2
+
+ wsrep_check_programs openssl diff
+
+ # generate the public key from the cert and the key
+ # they should match (otherwise we can't create an SSL connection)
+ if ! diff <(openssl x509 -in "$cert_path" -pubkey -noout) <(openssl rsa -in "$key_path" -pubout 2>/dev/null) >/dev/null 2>&1
+ then
+ wsrep_log_error "******** FATAL ERROR ************************* "
+ wsrep_log_error "* The certifcate and private key do not match. "
+ wsrep_log_error "* Please check your certificate and key files. "
+ wsrep_log_error "********************************************** "
+ exit 22
+ fi
+}
+
+# Checks to see if the file exists
+# If the file does not exist (or cannot be read), issues an error
+# and exits
+#
+# 1st param: file name to be checked (for read access)
+# 2nd param: 1st error message (header)
+# 3rd param: 2nd error message (footer, optional)
+#
+verify_file_exists()
+{
+ local file_path=$1
+ local error_message1=$2
+ local error_message2=$3
+
+ if ! [[ -r "$file_path" ]]; then
+ wsrep_log_error "******** FATAL ERROR ************************* "
+ wsrep_log_error "* $error_message1 "
+ wsrep_log_error "* Could not find/access : $file_path "
+
+ if ! [[ -z "$error_message2" ]]; then
+ wsrep_log_error "* $error_message2 "
+ fi
+
+ wsrep_log_error "********************************************** "
+ exit 22
+ fi
+}
+
get_transfer()
{
if [[ -z $SST_PORT ]];then
@@ -174,15 +263,25 @@ get_transfer()
wsrep_log_error "nc(netcat) not found in path: $PATH"
exit 2
fi
+
+ if [[ $encrypt -eq 2 || $encrypt -eq 3 || $encrypt -eq 4 ]]; then
+ wsrep_log_error "******** FATAL ERROR *********************** "
+ wsrep_log_error "* Using SSL encryption (encrypt= 2, 3, or 4) "
+ wsrep_log_error "* is not supported when using nc(netcat). "
+ wsrep_log_error "******************************************** "
+ exit 22
+ fi
+
wsrep_log_info "Using netcat as streamer"
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
- if nc -h 2>&1 | grep -q ncat;then
- tcmd="nc -l ${TSST_PORT}"
+ if nc -h 2>&1 | grep -q ncat; then
+ tcmd="nc $sockopt -l ${TSST_PORT}"
else
- tcmd="nc -dl ${TSST_PORT}"
+ tcmd="nc $sockopt -dl ${TSST_PORT}"
fi
else
- tcmd="nc ${REMOTEIP} ${TSST_PORT}"
+ # netcat doesn't understand [] around IPv6 address
+ tcmd="nc ${REMOTEIP//[\[\]]/} ${TSST_PORT}"
fi
else
tfmt='socat'
@@ -192,74 +291,112 @@ get_transfer()
exit 2
fi
- if [[ $encrypt -eq 2 || $encrypt -eq 3 ]] && ! socat -V | grep -q "WITH_OPENSSL 1";then
- wsrep_log_error "Encryption requested, but socat is not OpenSSL enabled (encrypt=$encrypt)"
- exit 2
- fi
+ donor_extra=""
+ joiner_extra=""
+ if [[ $encrypt -eq 2 || $encrypt -eq 3 || $encrypt -eq 4 ]]; then
+ if ! socat -V | grep -q WITH_OPENSSL; then
+ wsrep_log_error "******** FATAL ERROR ****************** "
+ wsrep_log_error "* socat is not openssl enabled. "
+ wsrep_log_error "* Unable to encrypt SST communications. "
+ wsrep_log_error "*************************************** "
+ exit 2
+ fi
- if [[ $encrypt -eq 2 ]];then
- wsrep_log_info "Using openssl based encryption with socat: with crt and pem"
- if [[ -z $tpem || -z $tcert ]];then
- wsrep_log_error "Both PEM and CRT files required"
- exit 22
+ # Determine the socat version
+ SOCAT_VERSION=`socat -V 2>&1 | grep -oe '[0-9]\.[0-9][\.0-9]*' | head -n1`
+ if [[ -z "$SOCAT_VERSION" ]]; then
+ wsrep_log_error "******** FATAL ERROR **************** "
+ wsrep_log_error "* Cannot determine the socat version. "
+ wsrep_log_error "************************************* "
+ exit 2
fi
+
+ # socat versions < 1.7.3 will have 512-bit dhparams (too small)
+ # so create 2048-bit dhparams and send that as a parameter
+ # socat version >= 1.7.3, checks to see if the peername matches the hostname
+ # set commonname="" to disable the peername checks
+ #
+ if ! check_for_version "$SOCAT_VERSION" "1.7.3"; then
+ if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]]; then
+ # dhparams check (will create ssl_dhparams if needed)
+ check_for_dhparams
+ joiner_extra=",dhparam=$ssl_dhparams"
+ fi
+ fi
+ if check_for_version "$SOCAT_VERSION" "1.7.3"; then
+ donor_extra=',commonname=""'
+ fi
+ fi
+
+ if [[ $encrypt -eq 2 ]]; then
+ wsrep_log_warning "**** WARNING **** encrypt=2 is deprecated and will be removed in a future release"
+ wsrep_log_info "Using openssl based encryption with socat: with crt and ca"
+
+ verify_file_exists "$tcert" "Both certificate and CA files are required." \
+ "Please check the 'tcert' option. "
+ verify_file_exists "$tca" "Both certificate and CA files are required." \
+ "Please check the 'tca' option. "
+
stagemsg+="-OpenSSL-Encrypted-2"
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
- wsrep_log_info "Decrypting with cert=${tpem}, cafile=${tcert}"
- tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tpem},cafile=${tcert}${sockopt} stdio"
+ wsrep_log_info "Decrypting with CERT: $tcert, CA: $tca"
+ tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tcert},cafile=${tca}${joiner_extra}${sockopt} stdio"
else
- wsrep_log_info "Encrypting with cert=${tpem}, cafile=${tcert}"
- tcmd="socat -u stdio openssl-connect:${REMOTEHOST}:${TSST_PORT},cert=${tpem},cafile=${tcert}${sockopt}"
+ wsrep_log_info "Encrypting with CERT: $tcert, CA: $tca"
+ tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${tcert},cafile=${tca}${donor_extra}${sockopt}"
fi
elif [[ $encrypt -eq 3 ]];then
+ wsrep_log_warning "**** WARNING **** encrypt=3 is deprecated and will be removed in a future release"
wsrep_log_info "Using openssl based encryption with socat: with key and crt"
- if [[ -z $tpem || -z $tkey ]];then
- wsrep_log_error "Both certificate and key files required"
- exit 22
- fi
+
+ verify_file_exists "$tcert" "Both certificate and key files are required." \
+ "Please check the 'tcert' option. "
+ verify_file_exists "$tkey" "Both certificate and key files are required." \
+ "Please check the 'tkey' option. "
+
stagemsg+="-OpenSSL-Encrypted-3"
if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
- if [[ -z $tcert ]];then
- wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, verify=0"
+ wsrep_log_info "Decrypting with CERT: $tcert, KEY: $tkey"
+ tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tcert},key=${tkey},verify=0${joiner_extra}${sockopt} stdio"
tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tpem},key=${tkey},verify=0${sockopt} stdio"
else
- wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}"
- tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${tpem},key=${tkey},cafile=${tcert}${sockopt} stdio"
- fi
+ wsrep_log_info "Encrypting with CERT: $tcert, KEY: $tkey"
+ tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${tcert},key=${tkey},verify=0${sockopt}"
+ fi
+ elif [[ $encrypt -eq 4 ]]; then
+ wsrep_log_info "Using openssl based encryption with socat: with key, crt, and ca"
+
+ verify_file_exists "$ssl_ca" "CA, certificate, and key files are required." \
+ "Please check the 'ssl-ca' option. "
+ verify_file_exists "$ssl_cert" "CA, certificate, and key files are required." \
+ "Please check the 'ssl-cert' option. "
+ verify_file_exists "$ssl_key" "CA, certificate, and key files are required." \
+ "Please check the 'ssl-key' option. "
+
+ # Check to see that the key matches the cert
+ verify_cert_matches_key $ssl_cert $ssl_key
+
+ stagemsg+="-OpenSSL-Encrypted-4"
+ if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]]; then
+ wsrep_log_info "Decrypting with CERT: $ssl_cert, KEY: $ssl_key, CA: $ssl_ca"
+ tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert=${ssl_cert},key=${ssl_key},cafile=${ssl_ca},verify=1${joiner_extra}${sockopt} stdio"
else
- if [[ -z $tcert ]];then
- wsrep_log_info "Encrypting with cert=${tpem}, key=${tkey}, verify=0"
- tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${tpem},key=${tkey},verify=0${sockopt}"
- else
- wsrep_log_info "Encrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}"
- tcmd="socat -u stdio openssl-connect:${REMOTEHOST}:${TSST_PORT},cert=${tpem},key=${tkey},cafile=${tcert}${sockopt}"
- fi
+ wsrep_log_info "Encrypting with CERT: $ssl_cert, KEY: $ssl_key, CA: $ssl_ca"
+ tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert=${ssl_cert},key=${ssl_key},cafile=${ssl_ca},verify=1${donor_extra}${sockopt}"
fi
- else
- if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then
+ else
+ if [[ $encrypt -eq 1 ]]; then
+ wsrep_log_warning "**** WARNING **** encrypt=1 is deprecated and will be removed in a future release"
+ fi
+
+ if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]]; then
tcmd="socat -u TCP-LISTEN:${TSST_PORT},reuseaddr${sockopt} stdio"
else
tcmd="socat -u stdio TCP:${REMOTEIP}:${TSST_PORT}${sockopt}"
fi
fi
fi
-
-}
-
-parse_cnf()
-{
- local group=$1
- local var=$2
- # 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)
- reval=$($MY_PRINT_DEFAULTS $group | awk -F= '{if ($1 ~ /_/) { gsub(/_/,"-",$1); print $1"="$2 } else { print $0 }}' | grep -- "--$var=" | cut -d= -f2- | tail -1)
- if [[ -z $reval ]];then
- [[ -n $3 ]] && reval=$3
- fi
- echo $reval
}
get_footprint()
@@ -309,15 +446,15 @@ read_cnf()
{
sfmt=$(parse_cnf sst streamfmt "xbstream")
tfmt=$(parse_cnf sst transferfmt "socat")
- tcert=$(parse_cnf sst tca "")
- tpem=$(parse_cnf sst tcert "")
+ tca=$(parse_cnf sst tca "")
+ tcert=$(parse_cnf sst tcert "")
tkey=$(parse_cnf sst tkey "")
encrypt=$(parse_cnf sst encrypt 0)
sockopt=$(parse_cnf sst sockopt "")
progress=$(parse_cnf sst progress "")
rebuild=$(parse_cnf sst rebuild 0)
ttime=$(parse_cnf sst time 0)
- cpat=$(parse_cnf sst cpat '.*galera\.cache$\|.*sst_in_progress$\|.*\.sst$\|.*gvwstate\.dat$\|.*grastate\.dat$\|.*\.err$\|.*\.log$\|.*RPM_UPGRADE_MARKER$\|.*RPM_UPGRADE_HISTORY$')
+ cpat=$(parse_cnf sst cpat '.*\.pem$\|.*init\.ok$\|.*galera\.cache$\|.*sst_in_progress$\|.*\.sst$\|.*gvwstate\.dat$\|.*grastate\.dat$\|.*\.err$\|.*\.log$\|.*RPM_UPGRADE_MARKER$\|.*RPM_UPGRADE_HISTORY$')
ealgo=$(parse_cnf xtrabackup encrypt "")
ekey=$(parse_cnf xtrabackup encrypt-key "")
ekeyfile=$(parse_cnf xtrabackup encrypt-key-file "")
@@ -331,9 +468,23 @@ read_cnf()
ekey=$(parse_cnf sst encrypt-key "")
ekeyfile=$(parse_cnf sst encrypt-key-file "")
fi
+
+ # Pull the parameters needed for encrypt=4
+ ssl_ca=$(parse_cnf sst ssl-ca "")
+ if [[ -z "$ssl_ca" ]]; then
+ ssl_ca=$(parse_cnf mysqld ssl-ca "")
+ fi
+ ssl_cert=$(parse_cnf sst ssl-cert "")
+ if [[ -z "$ssl_cert" ]]; then
+ ssl_cert=$(parse_cnf mysqld ssl-cert "")
+ fi
+ ssl_key=$(parse_cnf sst ssl-key "")
+ if [[ -z "$ssl_key" ]]; then
+ ssl_key=$(parse_cnf mysqld ssl-key "")
+ fi
+
rlimit=$(parse_cnf sst rlimit "")
uextra=$(parse_cnf sst use-extra 0)
- speciald=$(parse_cnf sst sst-special-dirs 1)
iopts=$(parse_cnf sst inno-backup-opts "")
iapts=$(parse_cnf sst inno-apply-opts "")
impts=$(parse_cnf sst inno-move-opts "")
@@ -342,13 +493,8 @@ read_cnf()
ssystag=$(parse_cnf mysqld_safe syslog-tag "${SST_SYSLOG_TAG:-}")
ssystag+="-"
- if [[ $speciald -eq 0 ]];then
- wsrep_log_error "sst-special-dirs equal to 0 is not supported, falling back to 1"
- speciald=1
- fi
-
if [[ $ssyslog -ne -1 ]];then
- if $MY_PRINT_DEFAULTS mysqld_safe | tr '_' '-' | grep -q -- "--syslog";then
+ if $MY_PRINT_DEFAULTS -c $WSREP_SST_OPT_CONF mysqld_safe | tr '_' '-' | grep -q -- "--syslog";then
ssyslog=1
fi
fi
@@ -494,32 +640,30 @@ kill_xtrabackup()
setup_ports()
{
if [[ "$WSREP_SST_OPT_ROLE" == "donor" ]];then
- SST_PORT=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $2 }')
- REMOTEIP=$(echo $WSREP_SST_OPT_ADDR | awk -F ':' '{ print $1 }')
- REMOTEHOST=$(getent hosts $REMOTEIP | awk '{ print $2 }')
- if [[ -z $REMOTEHOST ]];then
- REMOTEHOST=$REMOTEIP
- fi
- lsn=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $4 }')
- sst_ver=$(echo $WSREP_SST_OPT_ADDR | awk -F '[:/]' '{ print $5 }')
+ SST_PORT=$WSREP_SST_OPT_PORT
+ REMOTEIP=$WSREP_SST_OPT_HOST
+ lsn=$(echo $WSREP_SST_OPT_PATH | awk -F '[/]' '{ print $2 }')
+ sst_ver=$(echo $WSREP_SST_OPT_PATH | awk -F '[/]' '{ print $3 }')
else
- SST_PORT=$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $2 }')
+ SST_PORT=$WSREP_SST_OPT_PORT
fi
}
-# waits ~10 seconds for nc to open the port and then reports ready
+# waits ~1 minute for nc/socat to open the port and then reports ready
# (regardless of timeout)
wait_for_listen()
{
- local PORT=$1
- local ADDR=$2
+ local HOST=$1
+ local PORT=$2
local MODULE=$3
- for i in {1..50}
+
+ for i in {1..300}
do
ss -p state listening "( sport = :$PORT )" | grep -qE 'socat|nc' && break
sleep 0.2
done
- echo "ready ${ADDR}/${MODULE}//$sst_ver"
+
+ echo "ready ${HOST}:${PORT}/${MODULE}//$sst_ver"
}
check_extra()
@@ -527,7 +671,7 @@ check_extra()
local use_socket=1
if [[ $uextra -eq 1 ]];then
if $MY_PRINT_DEFAULTS --mysqld | tr '_' '-' | grep -- "--thread-handling=" | grep -q 'pool-of-threads';then
- local eport=$($MY_PRINT_DEFAULTS --mysqld | tr '_' '-' | grep -- "--extra-port=" | cut -d= -f2)
+ local eport=$($MY_PRINT_DEFAULTS -c $WSREP_SST_OPT_CONF mysqld | tr '_' '-' | grep -- "--extra-port=" | cut -d= -f2)
if [[ -n $eport ]];then
# Xtrabackup works only locally.
# Hence, setting host to 127.0.0.1 unconditionally.
@@ -622,11 +766,64 @@ send_donor()
}
+# Returns the version string in a standardized format
+# Input "1.2.3" => echoes "010203"
+# Wrongly formatted values => echoes "000000"
+normalize_version()
+{
+ local major=0
+ local minor=0
+ local patch=0
+
+ # Only parses purely numeric version numbers, 1.2.3
+ # Everything after the first three values are ignored
+ if [[ $1 =~ ^([0-9]+)\.([0-9]+)\.?([0-9]*)([\.0-9])*$ ]]; then
+ major=${BASH_REMATCH[1]}
+ minor=${BASH_REMATCH[2]}
+ patch=${BASH_REMATCH[3]}
+ fi
+
+ printf %02d%02d%02d $major $minor $patch
+}
+
+# Compares two version strings
+# The first parameter is the version to be checked
+# The second parameter is the minimum version required
+# Returns 1 (failure) if $1 >= $2, 0 (success) otherwise
+check_for_version()
+{
+ local local_version_str="$( normalize_version $1 )"
+ local required_version_str="$( normalize_version $2 )"
+
+ if [[ "$local_version_str" < "$required_version_str" ]]; then
+ return 1
+ else
+ return 0
+ fi
+}
+
+
if [[ ! -x `which $INNOBACKUPEX_BIN` ]];then
wsrep_log_error "innobackupex not in path: $PATH"
exit 2
fi
+# check the version, we require XB-2.4 to ensure that we can pass the
+# datadir via the command-line option
+XB_REQUIRED_VERSION="2.3.5"
+
+XB_VERSION=`$INNOBACKUPEX_BIN --version 2>&1 | grep -oe '[0-9]\.[0-9][\.0-9]*' | head -n1`
+if [[ -z $XB_VERSION ]]; then
+ wsrep_log_error "FATAL: Cannot determine the $INNOBACKUPEX_BIN version. Needs xtrabackup-$XB_REQUIRED_VERSION or higher to perform SST"
+ exit 2
+fi
+
+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"
+ exit 2
+fi
+
+
rm -f "${MAGIC_FILE}"
if [[ ! ${WSREP_SST_OPT_ROLE} == 'joiner' && ! ${WSREP_SST_OPT_ROLE} == 'donor' ]];then
@@ -670,13 +867,13 @@ if [[ $ssyslog -eq 1 ]];then
}
INNOAPPLY="${INNOBACKUPEX_BIN} $disver $iapts --apply-log \$rebuildcmd \${DATA} 2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-apply "
- INNOMOVE="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} $disver $impts --move-back --force-non-empty-directories \${DATA} 2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move "
+ INNOMOVE="${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} $disver $impts --datadir=${DATA} --move-back --force-non-empty-directories \${DATA} 2>&1 | logger -p daemon.err -t ${ssystag}innobackupex-move "
INNOBACKUP="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt \$itmpdir 2> >(logger -p daemon.err -t ${ssystag}innobackupex-backup)"
fi
else
INNOAPPLY="${INNOBACKUPEX_BIN} $disver $iapts --apply-log \$rebuildcmd \${DATA} &>\${DATA}/innobackup.prepare.log"
- INNOMOVE="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} $disver $impts --move-back --force-non-empty-directories \${DATA} &>\${DATA}/innobackup.move.log"
+ INNOMOVE="${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} --defaults-group=mysqld${WSREP_SST_OPT_CONF_SUFFIX} $disver $impts --datadir=${DATA} --move-back --force-non-empty-directories \${DATA} &>\${DATA}/innobackup.move.log"
INNOBACKUP="${INNOBACKUPEX_BIN} ${WSREP_SST_OPT_CONF} $disver $iopts \$tmpopts \$INNOEXTRA --galera-info --stream=\$sfmt \$itmpdir 2>\${DATA}/innobackup.backup.log"
fi
@@ -718,15 +915,6 @@ then
fi
get_keys
- if [[ $encrypt -eq 1 ]];then
- if [[ -n $ekey ]];then
- INNOEXTRA+=" --encrypt=$ealgo --encrypt-key=$ekey "
- else
- INNOEXTRA+=" --encrypt=$ealgo --encrypt-key-file=$ekeyfile "
- fi
- fi
-
-
check_extra
wsrep_log_info "Streaming GTID file before SST"
@@ -739,17 +927,17 @@ then
if [[ $encrypt -eq 1 ]];then
if [[ -n $scomp ]];then
- tcmd=" $ecmd | $scomp | $tcmd "
+ tcmd=" \$ecmd | $scomp | $tcmd "
else
- tcmd=" $ecmd | $tcmd "
+ tcmd=" \$ecmd | $tcmd "
fi
elif [[ -n $scomp ]];then
tcmd=" $scomp | $tcmd "
fi
-
send_donor $DATA "${stagemsg}-gtid"
+ # Restore the transport commmand to its original state
tcmd="$ttcmd"
if [[ -n $progress ]];then
get_footprint
@@ -764,10 +952,16 @@ then
wsrep_log_info "Streaming the backup to joiner at ${REMOTEIP} ${SST_PORT:-4444}"
- if [[ -n $scomp ]];then
+ # Add compression to the head of the stream (if specified)
+ if [[ -n $scomp ]]; then
tcmd="$scomp | $tcmd"
fi
+ # Add encryption to the head of the stream (if specified)
+ if [[ $encrypt -eq 1 ]]; then
+ tcmd=" \$ecmd | $tcmd "
+ fi
+
set +e
timeit "${stagemsg}-SST" "$INNOBACKUP | $tcmd; RC=( "\${PIPESTATUS[@]}" )"
set -e
@@ -797,9 +991,9 @@ then
get_keys
if [[ $encrypt -eq 1 ]];then
if [[ -n $scomp ]];then
- tcmd=" $ecmd | $scomp | $tcmd "
+ tcmd=" \$ecmd | $scomp | $tcmd "
else
- tcmd=" $ecmd | $tcmd "
+ tcmd=" \$ecmd | $tcmd "
fi
elif [[ -n $scomp ]];then
tcmd=" $scomp | $tcmd "
@@ -824,7 +1018,6 @@ then
stagemsg="Joiner-Recv"
-
sencrypted=1
nthreads=1
@@ -835,14 +1028,7 @@ then
# May need xtrabackup_checkpoints later on
rm -f ${DATA}/xtrabackup_binary ${DATA}/xtrabackup_galera_info ${DATA}/xtrabackup_logfile
- ADDR=${WSREP_SST_OPT_ADDR}
- if [ -z "${SST_PORT}" ]
- then
- SST_PORT=4444
- ADDR="$(echo ${WSREP_SST_OPT_ADDR} | awk -F ':' '{ print $1 }'):${SST_PORT}"
- fi
-
- wait_for_listen ${SST_PORT} ${ADDR} ${MODULE} &
+ wait_for_listen ${WSREP_SST_OPT_HOST} ${WSREP_SST_OPT_PORT:-4444} ${MODULE} &
trap sig_joiner_cleanup HUP PIPE INT TERM
trap cleanup_joiner EXIT
@@ -855,9 +1041,9 @@ then
get_keys
if [[ $encrypt -eq 1 && $sencrypted -eq 1 ]];then
if [[ -n $sdecomp ]];then
- strmcmd=" $sdecomp | $ecmd | $strmcmd"
+ strmcmd=" $sdecomp | \$ecmd | $strmcmd"
else
- strmcmd=" $ecmd | $strmcmd"
+ strmcmd=" \$ecmd | $strmcmd"
fi
elif [[ -n $sdecomp ]];then
strmcmd=" $sdecomp | $strmcmd"