diff options
author | Julius Goryavsky <julius.goryavsky@mariadb.com> | 2021-04-28 17:01:15 +0200 |
---|---|---|
committer | Julius Goryavsky <julius.goryavsky@mariadb.com> | 2021-04-28 17:01:15 +0200 |
commit | 130a152c3120b6534da30b19f8b40fa57bbd17f2 (patch) | |
tree | 1dee1fd6286d9120e642c6a753e10f89ee1e7df9 | |
parent | 5f5d08564d63e4f3088d68d85233ece59fb29d5f (diff) | |
download | mariadb-git-130a152c3120b6534da30b19f8b40fa57bbd17f2.tar.gz |
New improvements + changes from 10.6
-rw-r--r-- | scripts/wsrep_sst_common.sh | 139 | ||||
-rw-r--r-- | scripts/wsrep_sst_mariabackup.sh | 211 | ||||
-rw-r--r-- | scripts/wsrep_sst_mysqldump.sh | 2 | ||||
-rw-r--r-- | scripts/wsrep_sst_rsync.sh | 47 | ||||
-rw-r--r-- | scripts/wsrep_sst_xtrabackup-v2.sh | 26 | ||||
-rw-r--r-- | scripts/wsrep_sst_xtrabackup.sh | 1 |
6 files changed, 302 insertions, 124 deletions
diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index 9e9e3aa6075..1f5f11e13a2 100644 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -1,4 +1,5 @@ # Copyright (C) 2012-2015 Codership Oy +# Copyright (C) 2017-2021 MariaDB # # 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 @@ -26,6 +27,7 @@ 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_REMOTE_AUTH="${WSREP_SST_OPT_REMOTE_AUTH:-}" WSREP_SST_OPT_DEFAULT="" WSREP_SST_OPT_EXTRA_DEFAULT="" WSREP_SST_OPT_SUFFIX_DEFAULT="" @@ -278,11 +280,7 @@ case "$1" in if [ -z "$WSREP_SST_OPT_BINLOG" ]; then MYSQLD_OPT_LOG_BIN="$value" fi - # If this option has no parameter, then it does not - # need to be removed from the mysqld arguments list: - if [ -n "$value" ]; then - skip_mysqld_arg=1 - fi + skip_mysqld_arg=1 ;; '--log-bin-index') if [ -z "$WSREP_SST_OPT_BINLOG_INDEX" ]; then @@ -352,7 +350,22 @@ if [ -n "${MYSQLD_OPT_DATADIR:-}" -a \ fi if [ -n "${MYSQLD_OPT_LOG_BASENAME:-}" -a \ -z "$WSREP_SST_OPT_LOG_BASENAME" ]; then - readonly WSREP_SST_OPT_LOG_BASENAME="$MYSQLD_OPT_DATADIR" + readonly WSREP_SST_OPT_LOG_BASENAME="$MYSQLD_OPT_LOG_BASENAME" +fi + +# If the --log-bin option is present without a value, then +# setting WSREP_SST_OPT_BINLOG by using other arguments: +if [ -z "$WSREP_SST_OPT_BINLOG" -a -n "${MYSQLD_OPT_LOG_BIN+x}" ]; then + if [ -n "$WSREP_SST_OPT_LOG_BASENAME" ]; then + # If the WSREP_SST_OPT_BINLOG variable is not set, but + # --log-basename is present among the arguments to mysqld, + # then set WSREP_SST_OPT_BINLOG equal to the base name with + # the "-bin" suffix: + readonly WSREP_SST_OPT_BINLOG="$WSREP_SST_OPT_LOG_BASENAME-bin" + else + # Take the default name: + readonly WSREP_SST_OPT_BINLOG='mysql-bin' + fi fi # Reconstructing the command line arguments that control the innodb @@ -373,7 +386,8 @@ if [ -n "$WSREP_SST_OPT_BINLOG" ]; then fi fi -get_binlog() { +get_binlog() +{ # if no command line argument and WSREP_SST_OPT_BINLOG is not set, # try to get it from my.cnf: if [ -z "$WSREP_SST_OPT_BINLOG" ]; then @@ -390,7 +404,12 @@ get_binlog() { WSREP_SST_OPT_LOG_BASENAME=$(parse_cnf '--mysqld' 'log-basename') fi if [ -z "$WSREP_SST_OPT_BINLOG" ]; then - if [ -n "${MYSQLD_OPT_LOG_BIN+x}" ]; then + # If the --log-bin option is specified without a parameter, + # then we need to build the name of the index file according + # to the rules described in the server documentation: + if [ -n "${MYSQLD_OPT_LOG_BIN+x}" -o \ + $(in_config '--mysqld' 'log-bin') -eq 1 ] + then if [ -n "$WSREP_SST_OPT_LOG_BASENAME" ]; then # If the WSREP_SST_OPT_BINLOG variable is not set, but # --log-basename is present among the arguments to mysqld, @@ -400,7 +419,7 @@ get_binlog() { else # If the --log-bin option is present without a value, then # we take the default name: - readonly WSREP_SST_OPT_BINLOG='mysqld-bin' + readonly WSREP_SST_OPT_BINLOG='mysql-bin' fi fi fi @@ -415,27 +434,12 @@ get_binlog() { else # If the --log-bin option is present without a value, then # we take the default name: - readonly WSREP_SST_OPT_BINLOG_INDEX='mysqld-bin.index' + readonly WSREP_SST_OPT_BINLOG_INDEX='mysql-bin.index' fi fi fi } -# Setting WSREP_SST_OPT_BINLOG by using other arguments: -if [ -z "$WSREP_SST_OPT_BINLOG" ]; then - if [ -n "$WSREP_SST_OPT_LOG_BASENAME" ]; then - # If the WSREP_SST_OPT_BINLOG variable is not set, but - # --log-basename is present among the arguments to mysqld, - # then set WSREP_SST_OPT_BINLOG equal to the base name with - # the "-bin" suffix: - readonly WSREP_SST_OPT_BINLOG="$WSREP_SST_OPT_LOG_BASENAME-bin" - elif [ -n "${MYSQLD_OPT_LOG_BIN+x}" ]; then - # If the --log-bin option is present without a value, then - # we take the default name: - readonly WSREP_SST_OPT_BINLOG='mysql-bin' - fi -fi - # Let's transfer the port from the address to the WSREP_SST_OPT_PORT # variable, or vice versa, substitute the missing port value into the # address: @@ -512,13 +516,14 @@ readonly WSREP_SST_OPT_CONF="$wsrep_defaults$WSREP_SST_OPT_SUFFIX_DEFAULT" readonly MY_PRINT_DEFAULTS="$MY_PRINT_DEFAULTS $WSREP_SST_OPT_CONF" # -# 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 +# User can specify mariabackup specific settings that will be used during sst +# process like encryption, etc. Parse such configuration option. +# +# 1st parameter: group (config file section like sst) or +# my_print_defaults argument (like --mysqld) +# 2nd parameter: var : name of the variable in the section, e.g. server-id +# 3rd parameter: default value for the parameter # -# 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" @@ -532,12 +537,12 @@ parse_cnf() if [ "$group" = '--mysqld' -o \ "$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="="} {gsub(/_/,"-",$1); if ($1=="--'"$var"'") lastval=substr($0,length($1)+2)} END {print lastval}') + 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 - reval=$($MY_PRINT_DEFAULTS "$group" | awk 'BEGIN {OFS=FS="="} {gsub(/_/,"-",$1); if ($1=="--'"$var"'") lastval=substr($0,length($1)+2)} END {print lastval}') + 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}') fi # use default if we haven't found a value @@ -547,6 +552,29 @@ parse_cnf() echo $reval } +# +# This function simply checks for the presence of the parameter +# in the config file, but does not return its value. It returns "1" +# (true) even if the parameter is present in the configuration file +# without a value: +# +in_config() +{ + local group="$1" + local var="$2" + local found=0 + if [ "$group" = '--mysqld' -o \ + "$group" = 'mysqld' ]; then + if [ -n "$WSREP_SST_OPT_SUFFIX_VALUE" ]; then + 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}') + fi + fi + 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}') + fi + echo $found +} + wsrep_auth_not_set() { [ -z "$WSREP_SST_OPT_AUTH" -o "$WSREP_SST_OPT_AUTH" = '(null)' ] @@ -562,11 +590,23 @@ readonly WSREP_SST_OPT_AUTH if ! wsrep_auth_not_set then WSREP_SST_OPT_USER="${WSREP_SST_OPT_AUTH%%:*}" - WSREP_SST_OPT_PSWD="${WSREP_SST_OPT_AUTH##*:}" + WSREP_SST_OPT_PSWD="${WSREP_SST_OPT_AUTH#*:}" fi readonly WSREP_SST_OPT_USER readonly WSREP_SST_OPT_PSWD +readonly WSREP_SST_OPT_REMOTE_AUTH + +if [ -n "$WSREP_SST_OPT_REMOTE_AUTH" ] +then + # Split auth string at the last ':' + readonly WSREP_SST_OPT_REMOTE_USER="${WSREP_SST_OPT_REMOTE_AUTH%%:*}" + readonly WSREP_SST_OPT_REMOTE_PSWD="${WSREP_SST_OPT_REMOTE_AUTH#*:}" +else + readonly WSREP_SST_OPT_REMOTE_USER= + readonly WSREP_SST_OPT_REMOTE_PSWD= +fi + if [ -n "$WSREP_SST_OPT_DATA" ] then SST_PROGRESS_FILE="$WSREP_SST_OPT_DATA/sst_in_progress" @@ -633,3 +673,34 @@ wsrep_check_datadir() exit 2 fi } + +get_openssl() +{ + # If the OPENSSL_BINARY variable is already defined, just return: + if [ -n "${OPENSSL_BINARY+x}" ]; then + return + fi + # Let's look for openssl: + OPENSSL_BINARY="$(command -v openssl)" + if [ -z "$OPENSSL_BINARY" ]; then + OPENSSL_BINARY='/usr/bin/openssl' + if [ ! -x "$OPENSSL_BINARY" ]; then + OPENSSL_BINARY="" + fi + fi + readonly OPENSSL_BINARY +} + +# Generate a string equivalent to 16 random bytes +wsrep_gen_secret() +{ + get_openssl + if [ -n "$OPENSSL_BINARY" ] + then + echo $("$OPENSSL_BINARY" rand -hex 16) + else + printf "%04x%04x%04x%04x%04x%04x%04x%04x" \ + $RANDOM $RANDOM $RANDOM $RANDOM \ + $RANDOM $RANDOM $RANDOM $RANDOM + fi +} diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index 6d837c01d4d..432fa4f465b 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -1,6 +1,6 @@ #!/bin/bash -ue # Copyright (C) 2013 Percona Inc -# Copyright (C) 2017-2020 MariaDB +# Copyright (C) 2017-2021 MariaDB # # 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 @@ -38,6 +38,7 @@ REMOTEIP="" tcert="" tpem="" tkey="" +tmode="DISABLED" sockopt="" progress="" ttime=0 @@ -71,6 +72,8 @@ xtmpdir="" scomp="" sdecomp="" +readonly SECRET_TAG="secret" + # Required for backup locks # For backup locks it is 1 sent by joiner # 5.6.21 PXC and later can't donate to an older joiner @@ -175,27 +178,27 @@ get_transfer() { TSST_PORT="$SST_PORT" - if [[ $tfmt == 'nc' ]];then + if [ $tfmt = 'nc' ]; then wsrep_check_programs nc wsrep_log_info "Using netcat as streamer" - if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then - if nc -h 2>&1 | grep -q ncat;then + if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then + if nc -h 2>&1 | grep -q ncat; then # Ncat - tcmd="nc -l ${TSST_PORT}" - elif nc -h 2>&1 | grep -qw -- '-d\>';then + tcmd="nc -l $TSST_PORT" + elif nc -h 2>&1 | grep -qw -- '-d\>'; then # Debian netcat - if [ $WSREP_SST_OPT_HOST_IPv6 -eq 1 ];then + 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}" + tcmd="nc -dl -6 $TSST_PORT" else - tcmd="nc -dl ${TSST_PORT}" + tcmd="nc -dl $TSST_PORT" fi else # traditional netcat - tcmd="nc -l -p ${TSST_PORT}" + tcmd="nc -l -p $TSST_PORT" fi else # Check to see if netcat supports the '-N' flag. @@ -207,23 +210,23 @@ get_transfer() # return an error if the flag is used. # tcmd_extra="" - if nc -h 2>&1 | grep -qw -- -N;then - tcmd_extra+="-N" + 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 + 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 + tcmd="nc $tcmd_extra $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT" + elif nc -h 2>&1 | grep -qw -- '-d\>'; then # Debian netcat wsrep_log_info "Using Debian netcat as streamer" - tcmd="nc ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}" + tcmd="nc $tcmd_extra $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT" else # traditional netcat wsrep_log_info "Using traditional netcat as streamer" - tcmd="nc -q0 ${tcmd_extra} ${WSREP_SST_OPT_HOST_UNESCAPED} ${TSST_PORT}" + tcmd="nc -q0 $tcmd_extra $WSREP_SST_OPT_HOST_UNESCAPED $TSST_PORT" fi fi else @@ -236,49 +239,55 @@ get_transfer() exit 2 fi - if [[ $encrypt -eq 2 ]];then + if [ $encrypt -eq 2 ]; then wsrep_log_info "Using openssl based encryption with socat: with crt and pem" - if [[ -z "$tpem" || -z "$tcert" ]];then + if [ -z "$tpem" -o -z "$tcert" ]; then wsrep_log_error "Both PEM and CRT files required" exit 22 fi stagemsg+="-OpenSSL-Encrypted-2" - if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then + 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" + tcmd="socat -u openssl-listen:$TSST_PORT,reuseaddr,cert='$tpem',cafile='$tcert'$sockopt stdio" else wsrep_log_info "Encrypting with cert=${tpem}, cafile=${tcert}" - tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert='${tpem}',cafile='${tcert}'${sockopt}" + tcmd="socat -u stdio openssl-connect:$REMOTEIP:$TSST_PORT,cert='$tpem',cafile='$tcert'$sockopt" fi - elif [[ $encrypt -eq 3 ]];then + elif [ $encrypt -eq 3 ]; then wsrep_log_info "Using openssl based encryption with socat: with key and crt" - if [[ -z "$tpem" || -z "$tkey" ]];then + if [ -z "$tpem" -o -z "$tkey" ]; then wsrep_log_error "Both certificate and key files required" exit 22 fi stagemsg+="-OpenSSL-Encrypted-3" - if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then - if [[ -z "$tcert" ]];then + if [ -z "$tcert" ]; then + # no verification + if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then wsrep_log_info "Decrypting with cert=${tpem}, key=${tkey}, verify=0" - tcmd="socat -u openssl-listen:${TSST_PORT},reuseaddr,cert='${tpem}',key='${tkey}',verify=0${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" + 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" fi 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}" + # CA verification + if [ "$WSREP_SST_OPT_ROLE" = 'joiner' ]; then + 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" else + CN_option="" + if [ -n "$WSREP_SST_OPT_REMOTE_USER" ]; then + CN_option=",commonname='$WSREP_SST_OPT_REMOTE_USER'" + fi wsrep_log_info "Encrypting with cert=${tpem}, key=${tkey}, cafile=${tcert}" - tcmd="socat -u stdio openssl-connect:${REMOTEIP}:${TSST_PORT},cert='${tpem}',key='${tkey}',cafile='${tcert}'${sockopt}" + tcmd="socat -u stdio openssl-connect:$REMOTEIP:$TSST_PORT,cert='$tpem',key='$tkey',cafile='$tcert'$CN_option$sockopt" fi fi else - if [[ "$WSREP_SST_OPT_ROLE" == "joiner" ]];then - tcmd="socat -u TCP-LISTEN:${TSST_PORT},reuseaddr${sockopt} stdio" + 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}" + tcmd="socat -u stdio TCP:$REMOTEIP:$TSST_PORT$sockopt" fi fi fi @@ -326,19 +335,54 @@ adjust_progress() fi } +check_server_ssl_config() +{ + local section="$1" + tcert=$(parse_cnf "$section" 'ssl-ca') + tpem=$(parse_cnf "$section" 'ssl-cert') + tkey=$(parse_cnf "$section" 'ssl-key') +} + read_cnf() { sfmt=$(parse_cnf sst streamfmt "xbstream") tfmt=$(parse_cnf sst transferfmt "socat") - encrypt=$(parse_cnf sst encrypt 0) - if [ $encrypt -ge 2 ]; then - tcert=$(parse_cnf sst tca "") - tpem=$(parse_cnf sst tcert "") - if [ $encrypt -ge 3 ]; then - tkey=$(parse_cnf sst tkey "") + encrypt=$(parse_cnf 'sst' 'encrypt' 0) + tmode=$(parse_cnf 'sst' 'ssl-mode' 'DISABLED' | tr [:lower:] [:upper:]) + + if [ $encrypt -eq 0 -o $encrypt -ge 2 ] + then + if [ "$tmode" != 'DISABLED' -o $encrypt -ge 2 ] + then + tcert=$(parse_cnf 'sst' 'tca') + tpem=$(parse_cnf 'sst' 'tcert') + tkey=$(parse_cnf 'sst' 'tkey') + fi + if [ "$tmode" != 'DISABLED' ] + then # backward-incompatible behavior + if [ -z "$tpem" -a -z "$tkey" -a -z "$tcert" ] + then # no old-style SSL config in [sst] + check_server_ssl_config 'sst' + if [ -z "$tpem" -a -z "$tkey" -a -z "$tcert" ] + then # no new-stype SSL config in [sst], try server-wide SSL config + check_server_ssl_config '--mysqld' + fi + fi + if [ 0 -eq $encrypt -a -n "$tpem" -a -n "$tkey" ] + then + encrypt=3 # enable cert/key SSL encyption + + # avoid CA verification if not set explicitly: + # nodes may happen to have different CA if self-generated + # zeroing up tcert does the trick + local mode=$(parse_cnf 'sst' 'ssl-mode') + [[ $mode = *VERIFY* ]] || tcert="" + fi fi - elif [ $encrypt -ne -1 ]; then + fi + + if [ $encrypt -eq 1 ]; then # Refer to http://www.percona.com/doc/percona-xtradb-cluster/manual/xtrabackup_sst.html ealgo=$(parse_cnf xtrabackup encrypt "") if [ -z "$ealgo" ]; then @@ -351,6 +395,9 @@ read_cnf() fi fi + wsrep_log_info "SSL configuration: CA='"$tcert"', CERT='"$tpem"'," \ + "KEY='"$tkey"', MODE='"$tmode"', encrypt="$encrypt + sockopt=$(parse_cnf sst sockopt "") progress=$(parse_cnf sst progress "") ttime=$(parse_cnf sst time 0) @@ -555,9 +602,9 @@ check_extra() { local use_socket=1 if [ $uextra -eq 1 ]; then - local thread_handling=$(parse_cnf --mysqld thread-handling "") - if [ $thread_handling -eq "pool-of-threads" ];then - local eport=$(parse_cnf --mysqld extra-port "") + local thread_handling=$(parse_cnf '--mysqld' 'thread-handling') + if [ "$thread_handling" = 'pool-of-threads' ]; then + local eport=$(parse_cnf '--mysqld' 'extra-port') if [ -n "$eport" ]; then # Xtrabackup works only locally. # Hence, setting host to 127.0.0.1 unconditionally. @@ -608,7 +655,7 @@ recv_joiner() popd 1>/dev/null if [[ ${RC[0]} -eq 124 ]];then - wsrep_log_error "Possible timeout in receiving first data from " + wsrep_log_error "Possible timeout in receiving first data from " \ "donor in gtid stage: exit codes: ${RC[@]}" exit 32 fi @@ -621,12 +668,27 @@ recv_joiner() fi done - if [[ $checkf -eq 1 && ! -r "${MAGIC_FILE}" ]];then - # this message should cause joiner to abort - wsrep_log_error "xtrabackup process ended without creating '${MAGIC_FILE}'" - wsrep_log_info "Contents of datadir" - wsrep_log_info "$(ls -l ${dir}/*)" - exit 32 + if [ $checkf -eq 1 ]; then + if [ ! -r "$MAGIC_FILE" ]; then + # this message should cause joiner to abort + wsrep_log_error "receiving process ended without creating " \ + "'${MAGIC_FILE}'" + wsrep_log_info "Contents of datadir" + wsrep_log_info "$(ls -l ${dir}/*)" + exit 32 + fi + + # check donor supplied secret + SECRET=$(grep "$SECRET_TAG " "$MAGIC_FILE" 2>/dev/null | cut -d ' ' -f 2) + if [ "$SECRET" != "$MY_SECRET" ]; then + wsrep_log_error "Donor does not know my secret!" + wsrep_log_info "Donor:'$SECRET', my:'$MY_SECRET'" + exit 32 + fi + + # remove secret from magic file + grep -v "$SECRET_TAG " "$MAGIC_FILE" > "$MAGIC_FILE.new" + mv "$MAGIC_FILE.new" "$MAGIC_FILE" fi } @@ -643,7 +705,7 @@ send_donor() for ecode in "${RC[@]}";do if [[ $ecode -ne 0 ]];then - wsrep_log_error "Error while getting data from donor node: " \ + wsrep_log_error "Error while sending data to joiner node: " \ "exit codes: ${RC[@]}" exit 32 fi @@ -689,10 +751,10 @@ if [ ${FORCE_FTWRL:-0} -eq 1 ]; then iopts+=' --no-backup-locks' fi -# if no command line arg and INNODB_DATA_HOME_DIR environment variable +# if no command line argument and INNODB_DATA_HOME_DIR environment variable # is not set, try to get it from my.cnf: if [ -z "$INNODB_DATA_HOME_DIR" ]; then - INNODB_DATA_HOME_DIR=$(parse_cnf --mysqld innodb-data-home-dir) + INNODB_DATA_HOME_DIR=$(parse_cnf '--mysqld' 'innodb-data-home-dir') fi if [ -n "$INNODB_DATA_HOME_DIR" ]; then @@ -845,6 +907,11 @@ then # (separated by a space). echo "$WSREP_SST_OPT_GTID $WSREP_SST_OPT_GTID_DOMAIN_ID" > "$MAGIC_FILE" + if [ -n "$WSREP_SST_OPT_REMOTE_PSWD" ]; then + # Let joiner know that we know its secret + echo "$SECRET_TAG $WSREP_SST_OPT_REMOTE_PSWD" >> "$MAGIC_FILE" + fi + ttcmd="$tcmd" if [ -n "$scomp" ]; then @@ -932,14 +999,14 @@ then # if no command line argument and INNODB_LOG_GROUP_HOME is not set, # try to get it from my.cnf: if [ -z "$INNODB_LOG_GROUP_HOME" ]; then - INNODB_LOG_GROUP_HOME=$(parse_cnf --mysqld innodb-log-group-home-dir) + INNODB_LOG_GROUP_HOME=$(parse_cnf '--mysqld' 'innodb-log-group-home-dir') fi ib_log_dir="$INNODB_LOG_GROUP_HOME" - # if no command line arg then try to get it from my.cnf: + # if no command line argument then try to get it from my.cnf: if [ -z "$INNODB_UNDO_DIR" ]; then - INNODB_UNDO_DIR=$(parse_cnf --mysqld innodb-undo-directory) + INNODB_UNDO_DIR=$(parse_cnf '--mysqld' 'innodb-undo-directory') fi ib_undo_dir="$INNODB_UNDO_DIR" @@ -958,6 +1025,28 @@ then ADDR="$WSREP_SST_OPT_ADDR" + if [[ "$tmode" = *"VERIFY"* ]] + then # backward-incompatible behavior + CN="" + if [ -n "$tpem" ] + then + # find out my Common Name + get_openssl + if [ -z "$OPENSSL_BINARY" ]; then + wsrep_log_error 'openssl not found but it is required for authentication' + exit 42 + fi + CN=$("$OPENSSL_BINARY" x509 -noout -subject -in "$tpem" | \ + tr "," "\n" | grep "CN =" | cut -d= -f2 | sed s/^\ // | \ + sed s/\ %//) + fi + MY_SECRET=$(wsrep_gen_secret) + # Add authentication data to address + ADDR="$CN:$MY_SECRET@$ADDR" + else + MY_SECRET="" # for check down in recv_joiner() + fi # tmode == *VERIFY* + wait_for_listen "$SST_PORT" "$ADDR" "$MODULE" & trap sig_joiner_cleanup HUP PIPE INT TERM @@ -1020,7 +1109,7 @@ then binlog_dir=$(dirname "$WSREP_SST_OPT_BINLOG") wsrep_log_info "Cleaning the binlog directory $binlog_dir as well" rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || true - rm -fv "$WSREP_SST_OPT_BINLOG_INDEX" 1>&2 \+ || true + rm -fv "${WSREP_SST_OPT_BINLOG_INDEX%.index}.index" 1>&2 \+ || true fi TDATA="$DATA" @@ -1095,7 +1184,7 @@ then pushd "$BINLOG_DIRNAME" &>/dev/null for bfile in $(ls -1 "$BINLOG_FILENAME".[0-9]*); do - echo "$BINLOG_DIRNAME/$bfile" >> "$WSREP_SST_OPT_BINLOG_INDEX" + echo "$BINLOG_DIRNAME/$bfile" >> "${WSREP_SST_OPT_BINLOG_INDEX%.index}.index" done popd &> /dev/null diff --git a/scripts/wsrep_sst_mysqldump.sh b/scripts/wsrep_sst_mysqldump.sh index ba59db66a73..548e03cf7b7 100644 --- a/scripts/wsrep_sst_mysqldump.sh +++ b/scripts/wsrep_sst_mysqldump.sh @@ -1,5 +1,6 @@ #!/bin/bash -ue # Copyright (C) 2009-2015 Codership Oy +# Copyright (C) 2017-2021 MariaDB # # 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 @@ -25,6 +26,7 @@ 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 diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index d42d73cb35c..c03f1174848 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -1,6 +1,7 @@ #!/bin/bash -ue # Copyright (C) 2010-2014 Codership Oy +# Copyright (C) 2017-2021 MariaDB # # 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 @@ -141,15 +142,10 @@ if [ -n "$WSREP_SST_OPT_BINLOG" ]; then BINLOG_FILENAME=$(basename "$WSREP_SST_OPT_BINLOG") fi -if [ -n "$WSREP_SST_OPT_BINLOG_INDEX" ]; then - BINLOG_INDEX_DIRNAME=$(dirname "$WSREP_SST_OPT_BINLOG_INDEX") - BINLOG_INDEX_FILENAME=$(basename "$WSREP_SST_OPT_BINLOG_INDEX") -fi - # if no command line argument and INNODB_LOG_GROUP_HOME is not set, # try to get it from my.cnf: if [ -z "$INNODB_LOG_GROUP_HOME" ]; then - INNODB_LOG_GROUP_HOME=$(parse_cnf --mysqld innodb-log-group-home-dir) + INNODB_LOG_GROUP_HOME=$(parse_cnf '--mysqld' 'innodb-log-group-home-dir') fi WSREP_LOG_DIR="$INNODB_LOG_GROUP_HOME" @@ -162,10 +158,10 @@ else WSREP_LOG_DIR=$(cd "$WSREP_SST_OPT_DATA"; pwd -P) fi -# if no command line arg and INNODB_DATA_HOME_DIR environment variable +# if no command line argument and INNODB_DATA_HOME_DIR environment variable # is not set, try to get it from my.cnf: if [ -z "$INNODB_DATA_HOME_DIR" ]; then - INNODB_DATA_HOME_DIR=$(parse_cnf --mysqld innodb-data-home-dir) + INNODB_DATA_HOME_DIR=$(parse_cnf '--mysqld' 'innodb-data-home-dir') fi if [ -n "$INNODB_DATA_HOME_DIR" ]; then @@ -176,6 +172,19 @@ else INNODB_DATA_HOME_DIR=$(cd "$WSREP_SST_OPT_DATA"; pwd -P) fi +# if no command line argument then try to get it from my.cnf: +if [ -z "$INNODB_UNDO_DIR" ]; then + INNODB_UNDO_DIR=$(parse_cnf '--mysqld' 'innodb-undo-directory') +fi + +if [ -n "$INNODB_UNDO_DIR" ]; then + # handle both relative and absolute paths + INNODB_UNDO_DIR=$(cd "$WSREP_SST_OPT_DATA"; mkdir -p "$INNODB_UNDO_DIR"; cd "$INNODB_UNDO_DIR"; pwd -P) +else + # default to datadir + INNODB_UNDO_DIR=$(cd "$WSREP_SST_OPT_DATA"; pwd -P) +fi + # Old filter - include everything except selected # FILTER=(--exclude '*.err' --exclude '*.pid' --exclude '*.sock' \ # --exclude '*.conf' --exclude core --exclude 'galera.*' \ @@ -190,7 +199,7 @@ FILTER="-f '- /lost+found' -f '+ /wsrep_sst_binlog.tar' -f '- $INNODB_DATA_HOME_DIR/ib_lru_dump' -f '- $INNODB_DATA_HOME_DIR/ibdata*' - -f '+ /undo*' + -f '+ $INNODB_UNDO_DIR/undo*' -f '+ /*/' -f '- /*'" @@ -259,9 +268,9 @@ EOF then # Prepare binlog files OLD_PWD="$(pwd)" + cd "$BINLOG_DIRNAME" - cd "$BINLOG_INDEX_DIRNAME" - binlog_files_full=$(tail -n $BINLOG_N_FILES "$BINLOG_INDEX_FILENAME") + binlog_files_full=$(tail -n $BINLOG_N_FILES "${WSREP_SST_OPT_BINLOG_INDEX%.index}.index") binlog_files="" for ii in $binlog_files_full @@ -270,12 +279,12 @@ EOF binlog_files="$binlog_files $binlog_file" done - cd "$BINLOG_DIRNAME" if [ -n "$binlog_files" ] then wsrep_log_info "Preparing binlog files for transfer:" tar -cvf "$BINLOG_TAR_FILE" $binlog_files >&2 fi + cd "$OLD_PWD" fi @@ -321,7 +330,7 @@ EOF rsync ${STUNNEL:+--rsh="$STUNNEL"} \ --owner --group --perms --links --specials \ --ignore-times --inplace --dirs --delete --quiet \ - $WHOLE_FILE_OPT -f '+ /ib_logfile[0-9]*' -f '- **' "$WSREP_LOG_DIR/" \ + $WHOLE_FILE_OPT -f '+ /ib_logfile[0-9]*' -f '+ /aria_log.*' -f '+ /aria_log_control' -f '- **' "$WSREP_LOG_DIR/" \ rsync://$WSREP_SST_OPT_ADDR-log_dir >&2 || RC=$? if [ $RC -ne 0 ]; then @@ -342,7 +351,7 @@ EOF rsync ${STUNNEL:+--rsh="$STUNNEL"} \ --owner --group --perms --links --specials \ --ignore-times --inplace --recursive --delete --quiet \ - $WHOLE_FILE_OPT --exclude '*/ib_logfile*' "$WSREP_SST_OPT_DATA"/{}/ \ + $WHOLE_FILE_OPT --exclude '*/ib_logfile*' --exclude "*/aria_log.*" --exclude "*/aria_log_control" "$WSREP_SST_OPT_DATA"/{}/ \ rsync://$WSREP_SST_OPT_ADDR/{} >&2 || RC=$? cd "$OLD_PWD" @@ -492,13 +501,17 @@ EOF OLD_PWD="$(pwd)" cd "$BINLOG_DIRNAME" + binlog_index="${WSREP_SST_OPT_BINLOG_INDEX%.index}.index" + + # Clean up old binlog files first + rm -f "$BINLOG_FILENAME".* + [ -f "$binlog_index" ] && rm "$binlog_index" + if [ -f "$BINLOG_TAR_FILE" ]; then - # Clean up old binlog files first - rm -f "$BINLOG_FILENAME".* wsrep_log_info "Extracting binlog files:" tar -xvf "$BINLOG_TAR_FILE" >> _binlog_tmp_files_$! while read bin_file; do - echo "$BINLOG_DIRNAME/$bin_file" >> "$BINLOG_INDEX_DIRNAME/$BINLOG_INDEX_FILENAME" + echo "$BINLOG_DIRNAME/$bin_file" >> "$binlog_index" done < _binlog_tmp_files_$! rm -f _binlog_tmp_files_$! fi diff --git a/scripts/wsrep_sst_xtrabackup-v2.sh b/scripts/wsrep_sst_xtrabackup-v2.sh index 1a1b7590458..7b583f6ab9b 100644 --- a/scripts/wsrep_sst_xtrabackup-v2.sh +++ b/scripts/wsrep_sst_xtrabackup-v2.sh @@ -1,5 +1,6 @@ #!/bin/bash -ue # Copyright (C) 2013 Percona Inc +# Copyright (C) 2017-2021 MariaDB # # 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 @@ -681,10 +682,11 @@ wait_for_listen() check_extra() { local use_socket=1 - if [[ $uextra -eq 1 ]];then - if [ $(parse_cnf --mysqld thread-handling) = 'pool-of-threads'];then - local eport=$(parse_cnf --mysqld extra-port) - if [[ -n "$eport" ]];then + if [ $uextra -eq 1 ]; then + local thread_handling=$(parse_cnf '--mysqld' 'thread-handling') + if [ "$thread_handling" = 'pool-of-threads' ]; then + local eport=$(parse_cnf '--mysqld' 'extra-port') + if [ -n "$eport" ]; then # Xtrabackup works only locally. # Hence, setting host to 127.0.0.1 unconditionally. wsrep_log_info "SST through extra_port $eport" @@ -769,7 +771,7 @@ send_donor() for ecode in "${RC[@]}";do if [[ $ecode -ne 0 ]];then - wsrep_log_error "Error while getting data from donor node: " \ + wsrep_log_error "Error while sending data to joiner node: " \ "exit codes: ${RC[@]}" exit 32 fi @@ -904,10 +906,10 @@ fi get_stream get_transfer -# if no command line arg and INNODB_DATA_HOME_DIR environment variable +# if no command line argument and INNODB_DATA_HOME_DIR environment variable # is not set, try to get it from my.cnf: if [ -z "$INNODB_DATA_HOME_DIR" ]; then - INNODB_DATA_HOME_DIR=$(parse_cnf --mysqld innodb-data-home-dir) + INNODB_DATA_HOME_DIR=$(parse_cnf '--mysqld' 'innodb-data-home-dir') fi if [ -n "$INNODB_DATA_HOME_DIR" ]; then @@ -1062,14 +1064,14 @@ then # if no command line argument and INNODB_LOG_GROUP_HOME is not set, # try to get it from my.cnf: if [ -z "$INNODB_LOG_GROUP_HOME" ]; then - INNODB_LOG_GROUP_HOME=$(parse_cnf --mysqld innodb-log-group-home-dir) + INNODB_LOG_GROUP_HOME=$(parse_cnf '--mysqld' 'innodb-log-group-home-dir') fi ib_log_dir="$INNODB_LOG_GROUP_HOME" - # if no command line arg then try to get it from my.cnf: + # if no command line argument then try to get it from my.cnf: if [ -z "$INNODB_UNDO_DIR" ]; then - INNODB_UNDO_DIR=$(parse_cnf --mysqld innodb-undo-directory) + INNODB_UNDO_DIR=$(parse_cnf '--mysqld' 'innodb-undo-directory') fi ib_undo_dir="$INNODB_UNDO_DIR" @@ -1142,7 +1144,7 @@ then binlog_dir=$(dirname "$WSREP_SST_OPT_BINLOG") wsrep_log_info "Cleaning the binlog directory $binlog_dir as well" rm -fv "$WSREP_SST_OPT_BINLOG".[0-9]* 1>&2 \+ || true - rm -fv "$WSREP_SST_OPT_BINLOG_INDEX" 1>&2 \+ || true + rm -fv "${WSREP_SST_OPT_BINLOG_INDEX%.index}.index" 1>&2 \+ || true fi TDATA="${DATA}" @@ -1222,7 +1224,7 @@ then pushd "$BINLOG_DIRNAME" &>/dev/null for bfile in $(ls -1 "$BINLOG_FILENAME".[0-9]*); do - echo "$BINLOG_DIRNAME/$bfile" >> "$WSREP_SST_OPT_BINLOG_INDEX" + echo "$BINLOG_DIRNAME/$bfile" >> "${WSREP_SST_OPT_BINLOG_INDEX%.index}.index" done popd &> /dev/null diff --git a/scripts/wsrep_sst_xtrabackup.sh b/scripts/wsrep_sst_xtrabackup.sh index c06794e0994..c39696176b1 100644 --- a/scripts/wsrep_sst_xtrabackup.sh +++ b/scripts/wsrep_sst_xtrabackup.sh @@ -1,5 +1,6 @@ #!/bin/bash -ue # Copyright (C) 2013 Percona Inc +# Copyright (C) 2017-2021 MariaDB # # 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 |