2019-08-20 08:50:35 +02:00
|
|
|
#!/bin/bash -ue
|
2014-08-06 14:39:15 +02:00
|
|
|
|
|
|
|
# Copyright (C) 2010-2014 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
|
2019-05-11 21:19:05 +02:00
|
|
|
# MA 02110-1335 USA.
|
2014-08-06 14:39:15 +02:00
|
|
|
|
|
|
|
# This is a reference script for rsync-based state snapshot tansfer
|
|
|
|
|
2015-11-16 18:35:06 +01:00
|
|
|
RSYNC_PID= # rsync pid file
|
|
|
|
RSYNC_CONF= # rsync configuration file
|
|
|
|
RSYNC_REAL_PID= # rsync process id
|
|
|
|
|
2014-08-06 14:39:15 +02:00
|
|
|
OS=$(uname)
|
2016-07-24 22:01:14 +02:00
|
|
|
[ "$OS" = "Darwin" ] && export -n LD_LIBRARY_PATH
|
2014-08-06 14:39:15 +02:00
|
|
|
|
|
|
|
# Setting the path for lsof on CentOS
|
|
|
|
export PATH="/usr/sbin:/sbin:$PATH"
|
|
|
|
|
|
|
|
. $(dirname $0)/wsrep_sst_common
|
|
|
|
|
|
|
|
wsrep_check_programs rsync
|
|
|
|
|
|
|
|
cleanup_joiner()
|
|
|
|
{
|
2015-11-16 18:35:06 +01:00
|
|
|
wsrep_log_info "Joiner cleanup. rsync PID: $RSYNC_REAL_PID"
|
|
|
|
[ "0" != "$RSYNC_REAL_PID" ] && \
|
|
|
|
kill $RSYNC_REAL_PID && \
|
|
|
|
sleep 0.5 && \
|
|
|
|
kill -9 $RSYNC_REAL_PID >/dev/null 2>&1 || \
|
|
|
|
:
|
2014-08-06 14:39:15 +02:00
|
|
|
rm -rf "$RSYNC_CONF"
|
2018-02-12 22:08:57 +01:00
|
|
|
rm -f "$STUNNEL_CONF"
|
|
|
|
rm -f "$STUNNEL_PID"
|
2014-08-06 14:39:15 +02:00
|
|
|
rm -rf "$MAGIC_FILE"
|
|
|
|
rm -rf "$RSYNC_PID"
|
|
|
|
wsrep_log_info "Joiner cleanup done."
|
|
|
|
if [ "${WSREP_SST_OPT_ROLE}" = "joiner" ];then
|
|
|
|
wsrep_cleanup_progress_file
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2015-11-16 18:35:06 +01:00
|
|
|
# Check whether rsync process is still running.
|
2014-08-06 14:39:15 +02:00
|
|
|
check_pid()
|
|
|
|
{
|
|
|
|
local pid_file=$1
|
|
|
|
[ -r "$pid_file" ] && ps -p $(cat $pid_file) >/dev/null 2>&1
|
|
|
|
}
|
|
|
|
|
|
|
|
check_pid_and_port()
|
|
|
|
{
|
|
|
|
local pid_file=$1
|
|
|
|
local rsync_pid=$2
|
2016-10-03 12:30:12 +02:00
|
|
|
local rsync_addr=$3
|
|
|
|
local rsync_port=$4
|
2014-08-06 14:39:15 +02:00
|
|
|
|
2016-07-24 22:13:02 +02:00
|
|
|
case $OS in
|
|
|
|
FreeBSD)
|
2016-11-08 14:35:57 +01:00
|
|
|
local port_info="$(sockstat -46lp ${rsync_port} 2>/dev/null | \
|
|
|
|
grep ":${rsync_port}")"
|
|
|
|
local is_rsync="$(echo $port_info | \
|
2018-02-12 22:08:57 +01:00
|
|
|
grep -E '[[:space:]]+(rsync|stunnel)[[:space:]]+'"$rsync_pid" 2>/dev/null)"
|
2016-07-24 22:13:02 +02:00
|
|
|
;;
|
2016-11-08 14:35:57 +01:00
|
|
|
*)
|
2016-07-24 22:13:02 +02:00
|
|
|
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
|
2014-08-06 14:39:15 +02:00
|
|
|
|
2016-11-08 14:35:57 +01:00
|
|
|
local port_info="$(lsof -i :$rsync_port -Pn 2>/dev/null | \
|
|
|
|
grep "(LISTEN)")"
|
|
|
|
local is_rsync="$(echo $port_info | \
|
2018-02-12 22:08:57 +01:00
|
|
|
grep -E '^(rsync|stunnel)[[:space:]]+'"$rsync_pid" 2>/dev/null)"
|
2016-07-24 22:13:02 +02:00
|
|
|
;;
|
|
|
|
esac
|
2014-08-06 14:39:15 +02:00
|
|
|
|
2016-11-08 14:35:57 +01:00
|
|
|
local is_listening_all="$(echo $port_info | \
|
|
|
|
grep "*:$rsync_port" 2>/dev/null)"
|
|
|
|
local is_listening_addr="$(echo $port_info | \
|
2019-02-01 17:45:15 +01:00
|
|
|
grep -F "$rsync_addr:$rsync_port" 2>/dev/null)"
|
2016-11-08 14:35:57 +01:00
|
|
|
|
2016-10-03 12:30:12 +02:00
|
|
|
if [ ! -z "$is_listening_all" -o ! -z "$is_listening_addr" ]; then
|
|
|
|
if [ -z "$is_rsync" ]; then
|
|
|
|
wsrep_log_error "rsync daemon port '$rsync_port' has been taken"
|
|
|
|
exit 16 # EBUSY
|
|
|
|
fi
|
2014-08-06 14:39:15 +02:00
|
|
|
fi
|
|
|
|
check_pid $pid_file && \
|
|
|
|
[ -n "$port_info" ] && [ -n "$is_rsync" ] && \
|
|
|
|
[ $(cat $pid_file) -eq $rsync_pid ]
|
|
|
|
}
|
|
|
|
|
2016-10-03 12:30:12 +02:00
|
|
|
is_local_ip()
|
|
|
|
{
|
|
|
|
local address="$1"
|
|
|
|
local get_addr_bin=`which ifconfig`
|
|
|
|
if [ -z "$get_addr_bin" ]
|
|
|
|
then
|
|
|
|
get_addr_bin=`which ip`
|
|
|
|
get_addr_bin="$get_addr_bin address show"
|
|
|
|
# Add an slash at the end, so we don't get false positive : 172.18.0.4 matches 172.18.0.41
|
|
|
|
# ip output format is "X.X.X.X/mask"
|
|
|
|
address="${address}/"
|
|
|
|
else
|
|
|
|
# Add an space at the end, so we don't get false positive : 172.18.0.4 matches 172.18.0.41
|
|
|
|
# ifconfig output format is "X.X.X.X "
|
|
|
|
address="$address "
|
|
|
|
fi
|
|
|
|
|
2019-02-01 17:45:15 +01:00
|
|
|
$get_addr_bin | grep -F "$address" > /dev/null
|
2016-10-03 12:30:12 +02:00
|
|
|
}
|
|
|
|
|
2018-02-12 22:08:57 +01:00
|
|
|
STUNNEL_CONF="$WSREP_SST_OPT_DATA/stunnel.conf"
|
|
|
|
rm -f "$STUNNEL_CONF"
|
|
|
|
|
|
|
|
STUNNEL_PID="$WSREP_SST_OPT_DATA/stunnel.pid"
|
|
|
|
rm -f "$STUNNEL_PID"
|
|
|
|
|
2014-08-06 14:39:15 +02:00
|
|
|
MAGIC_FILE="$WSREP_SST_OPT_DATA/rsync_sst_complete"
|
|
|
|
rm -rf "$MAGIC_FILE"
|
|
|
|
|
|
|
|
BINLOG_TAR_FILE="$WSREP_SST_OPT_DATA/wsrep_sst_binlog.tar"
|
|
|
|
BINLOG_N_FILES=1
|
|
|
|
rm -f "$BINLOG_TAR_FILE" || :
|
|
|
|
|
|
|
|
if ! [ -z $WSREP_SST_OPT_BINLOG ]
|
|
|
|
then
|
|
|
|
BINLOG_DIRNAME=$(dirname $WSREP_SST_OPT_BINLOG)
|
|
|
|
BINLOG_FILENAME=$(basename $WSREP_SST_OPT_BINLOG)
|
2018-06-26 11:56:19 +02:00
|
|
|
BINLOG_INDEX_DIRNAME=$(dirname $WSREP_SST_OPT_BINLOG)
|
|
|
|
BINLOG_INDEX_FILENAME=$(basename $WSREP_SST_OPT_BINLOG)
|
|
|
|
fi
|
|
|
|
|
|
|
|
if ! [ -z $WSREP_SST_OPT_BINLOG_INDEX ]
|
|
|
|
then
|
|
|
|
BINLOG_INDEX_DIRNAME=$(dirname $WSREP_SST_OPT_BINLOG_INDEX)
|
|
|
|
BINLOG_INDEX_FILENAME=$(basename $WSREP_SST_OPT_BINLOG_INDEX)
|
2014-08-06 14:39:15 +02:00
|
|
|
fi
|
|
|
|
|
|
|
|
WSREP_LOG_DIR=${WSREP_LOG_DIR:-""}
|
MDEV-18863: Galera SST scripts can't read [mysqldN] option groups
Some users and some scripts (for example, mysqld_multi.sh) use special
option groups with names like [mysqld1], [mysqld2], ..., [mysqldN].
But SST scripts can't currently fully support these option groups.
The only option group-related value it gets from the server is
--defaults-group-suffix, if that option was set for mysqld when
the server was started.
However, the SST scripts does not get told by the server to read
these option groups, so this means that the SST script will fail
to read options like innodb-data-home-dir when it is in a option
group like [mysqld1]...[mysqldN].
Moreover, SST scripts ignore many parameters that can be passed
to them explicitly and cannot transfer them further, for example,
to the input of mariabackup utility. Ideally, we want to transfer
all the parameters of the original mysqld call to utilities such
as mariabackup, however the SST script does not receive these
parameters from the server and therefore cannot transfer them to
mariabackup.
To correct these shortcomings, we need to transfer to the scripts
all of the parameters of the original mysqld call, and in the SST
scripts themselves provide for the transfer all of these parameters
to utilities such as mariabackup. To prevent these parameters from
mixing with the script's own parameters, they should be transferred
to SST script after the special option "--mysqld-args", followed by
the string argument with the original parameters, as it received by
the mysqld call at the time of launch (further all these parameters
will be passed to mariabackup, for example).
In addition, the SST scripts themselves must be refined so that
they can read the parameters from the user-selected group, not just
from the global mysqld configuration group. And also so that they
can receive the parameters (which important for their work) as
command-line arguments.
2019-07-30 13:45:13 +02:00
|
|
|
# Try to set WSREP_LOG_DIR from the command line:
|
2020-08-04 14:25:58 +02:00
|
|
|
if [ ! -z "$INNODB_LOG_GROUP_HOME_ARG" ]; then
|
MDEV-18863: Galera SST scripts can't read [mysqldN] option groups
Some users and some scripts (for example, mysqld_multi.sh) use special
option groups with names like [mysqld1], [mysqld2], ..., [mysqldN].
But SST scripts can't currently fully support these option groups.
The only option group-related value it gets from the server is
--defaults-group-suffix, if that option was set for mysqld when
the server was started.
However, the SST scripts does not get told by the server to read
these option groups, so this means that the SST script will fail
to read options like innodb-data-home-dir when it is in a option
group like [mysqld1]...[mysqldN].
Moreover, SST scripts ignore many parameters that can be passed
to them explicitly and cannot transfer them further, for example,
to the input of mariabackup utility. Ideally, we want to transfer
all the parameters of the original mysqld call to utilities such
as mariabackup, however the SST script does not receive these
parameters from the server and therefore cannot transfer them to
mariabackup.
To correct these shortcomings, we need to transfer to the scripts
all of the parameters of the original mysqld call, and in the SST
scripts themselves provide for the transfer all of these parameters
to utilities such as mariabackup. To prevent these parameters from
mixing with the script's own parameters, they should be transferred
to SST script after the special option "--mysqld-args", followed by
the string argument with the original parameters, as it received by
the mysqld call at the time of launch (further all these parameters
will be passed to mariabackup, for example).
In addition, the SST scripts themselves must be refined so that
they can read the parameters from the user-selected group, not just
from the global mysqld configuration group. And also so that they
can receive the parameters (which important for their work) as
command-line arguments.
2019-07-30 13:45:13 +02:00
|
|
|
WSREP_LOG_DIR=$INNODB_LOG_GROUP_HOME_ARG
|
|
|
|
fi
|
2020-08-04 14:25:58 +02:00
|
|
|
# if no command line arg and WSREP_LOG_DIR is not set,
|
|
|
|
# try to get it from my.cnf:
|
MDEV-18863: Galera SST scripts can't read [mysqldN] option groups
Some users and some scripts (for example, mysqld_multi.sh) use special
option groups with names like [mysqld1], [mysqld2], ..., [mysqldN].
But SST scripts can't currently fully support these option groups.
The only option group-related value it gets from the server is
--defaults-group-suffix, if that option was set for mysqld when
the server was started.
However, the SST scripts does not get told by the server to read
these option groups, so this means that the SST script will fail
to read options like innodb-data-home-dir when it is in a option
group like [mysqld1]...[mysqldN].
Moreover, SST scripts ignore many parameters that can be passed
to them explicitly and cannot transfer them further, for example,
to the input of mariabackup utility. Ideally, we want to transfer
all the parameters of the original mysqld call to utilities such
as mariabackup, however the SST script does not receive these
parameters from the server and therefore cannot transfer them to
mariabackup.
To correct these shortcomings, we need to transfer to the scripts
all of the parameters of the original mysqld call, and in the SST
scripts themselves provide for the transfer all of these parameters
to utilities such as mariabackup. To prevent these parameters from
mixing with the script's own parameters, they should be transferred
to SST script after the special option "--mysqld-args", followed by
the string argument with the original parameters, as it received by
the mysqld call at the time of launch (further all these parameters
will be passed to mariabackup, for example).
In addition, the SST scripts themselves must be refined so that
they can read the parameters from the user-selected group, not just
from the global mysqld configuration group. And also so that they
can receive the parameters (which important for their work) as
command-line arguments.
2019-07-30 13:45:13 +02:00
|
|
|
if [ -z "$WSREP_LOG_DIR" ]; then
|
|
|
|
WSREP_LOG_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-log-group-home-dir '')
|
|
|
|
fi
|
2014-08-06 14:39:15 +02:00
|
|
|
if [ -z "$WSREP_LOG_DIR" ]; then
|
2014-09-26 15:54:42 +02:00
|
|
|
WSREP_LOG_DIR=$(parse_cnf --mysqld innodb-log-group-home-dir '')
|
2014-08-06 14:39:15 +02:00
|
|
|
fi
|
|
|
|
|
|
|
|
if [ -n "$WSREP_LOG_DIR" ]; then
|
|
|
|
# handle both relative and absolute paths
|
|
|
|
WSREP_LOG_DIR=$(cd $WSREP_SST_OPT_DATA; mkdir -p "$WSREP_LOG_DIR"; cd $WSREP_LOG_DIR; pwd -P)
|
|
|
|
else
|
|
|
|
# default to datadir
|
|
|
|
WSREP_LOG_DIR=$(cd $WSREP_SST_OPT_DATA; pwd -P)
|
|
|
|
fi
|
|
|
|
|
2018-07-26 15:42:06 +02:00
|
|
|
INNODB_DATA_HOME_DIR=${INNODB_DATA_HOME_DIR:-""}
|
2018-08-27 16:10:20 +02:00
|
|
|
# Try to set INNODB_DATA_HOME_DIR from the command line:
|
|
|
|
if [ ! -z "$INNODB_DATA_HOME_DIR_ARG" ]; then
|
|
|
|
INNODB_DATA_HOME_DIR=$INNODB_DATA_HOME_DIR_ARG
|
|
|
|
fi
|
2020-08-04 14:25:58 +02:00
|
|
|
# if no command line arg and INNODB_DATA_HOME_DIR environment variable
|
|
|
|
# is not set, try to get it from my.cnf:
|
MDEV-18863: Galera SST scripts can't read [mysqldN] option groups
Some users and some scripts (for example, mysqld_multi.sh) use special
option groups with names like [mysqld1], [mysqld2], ..., [mysqldN].
But SST scripts can't currently fully support these option groups.
The only option group-related value it gets from the server is
--defaults-group-suffix, if that option was set for mysqld when
the server was started.
However, the SST scripts does not get told by the server to read
these option groups, so this means that the SST script will fail
to read options like innodb-data-home-dir when it is in a option
group like [mysqld1]...[mysqldN].
Moreover, SST scripts ignore many parameters that can be passed
to them explicitly and cannot transfer them further, for example,
to the input of mariabackup utility. Ideally, we want to transfer
all the parameters of the original mysqld call to utilities such
as mariabackup, however the SST script does not receive these
parameters from the server and therefore cannot transfer them to
mariabackup.
To correct these shortcomings, we need to transfer to the scripts
all of the parameters of the original mysqld call, and in the SST
scripts themselves provide for the transfer all of these parameters
to utilities such as mariabackup. To prevent these parameters from
mixing with the script's own parameters, they should be transferred
to SST script after the special option "--mysqld-args", followed by
the string argument with the original parameters, as it received by
the mysqld call at the time of launch (further all these parameters
will be passed to mariabackup, for example).
In addition, the SST scripts themselves must be refined so that
they can read the parameters from the user-selected group, not just
from the global mysqld configuration group. And also so that they
can receive the parameters (which important for their work) as
command-line arguments.
2019-07-30 13:45:13 +02:00
|
|
|
if [ -z "$INNODB_DATA_HOME_DIR" ]; then
|
|
|
|
INNODB_DATA_HOME_DIR=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-data-home-dir '')
|
|
|
|
fi
|
2018-08-09 04:24:12 +02:00
|
|
|
if [ -z "$INNODB_DATA_HOME_DIR" ]; then
|
2019-03-05 04:01:02 +01:00
|
|
|
INNODB_DATA_HOME_DIR=$(parse_cnf --mysqld innodb-data-home-dir '')
|
2018-08-27 16:10:20 +02:00
|
|
|
fi
|
2018-08-09 04:24:12 +02:00
|
|
|
|
|
|
|
if [ -n "$INNODB_DATA_HOME_DIR" ]; then
|
|
|
|
# handle both relative and absolute paths
|
|
|
|
INNODB_DATA_HOME_DIR=$(cd $WSREP_SST_OPT_DATA; mkdir -p "$INNODB_DATA_HOME_DIR"; cd $INNODB_DATA_HOME_DIR; pwd -P)
|
|
|
|
else
|
|
|
|
# default to datadir
|
|
|
|
INNODB_DATA_HOME_DIR=$(cd $WSREP_SST_OPT_DATA; pwd -P)
|
2018-07-26 15:42:06 +02:00
|
|
|
fi
|
|
|
|
|
2014-08-06 14:39:15 +02:00
|
|
|
# Old filter - include everything except selected
|
|
|
|
# FILTER=(--exclude '*.err' --exclude '*.pid' --exclude '*.sock' \
|
|
|
|
# --exclude '*.conf' --exclude core --exclude 'galera.*' \
|
|
|
|
# --exclude grastate.txt --exclude '*.pem' \
|
|
|
|
# --exclude '*.[0-9][0-9][0-9][0-9][0-9][0-9]' --exclude '*.index')
|
|
|
|
|
|
|
|
# New filter - exclude everything except dirs (schemas) and innodb files
|
2018-09-14 08:47:22 +02:00
|
|
|
FILTER="-f '- /lost+found'
|
2020-02-11 19:27:59 +01:00
|
|
|
-f '- /.zfs'
|
2018-07-16 09:41:37 +02:00
|
|
|
-f '- /.fseventsd'
|
|
|
|
-f '- /.Trashes'
|
|
|
|
-f '+ /wsrep_sst_binlog.tar'
|
2018-09-07 15:25:27 +02:00
|
|
|
-f '- $INNODB_DATA_HOME_DIR/ib_lru_dump'
|
|
|
|
-f '- $INNODB_DATA_HOME_DIR/ibdata*'
|
2018-07-16 09:42:53 +02:00
|
|
|
-f '+ /undo*'
|
2018-07-16 09:41:37 +02:00
|
|
|
-f '+ /*/'
|
2018-09-14 08:47:22 +02:00
|
|
|
-f '- /*'"
|
2014-08-06 14:39:15 +02:00
|
|
|
|
2018-02-12 22:08:57 +01:00
|
|
|
SSTKEY=$(parse_cnf sst tkey "")
|
|
|
|
SSTCERT=$(parse_cnf sst tcert "")
|
|
|
|
STUNNEL=""
|
|
|
|
if [ -f "$SSTKEY" ] && [ -f "$SSTCERT" ] && wsrep_check_programs stunnel
|
|
|
|
then
|
|
|
|
STUNNEL="stunnel ${STUNNEL_CONF}"
|
|
|
|
fi
|
|
|
|
|
2014-08-06 14:39:15 +02:00
|
|
|
if [ "$WSREP_SST_OPT_ROLE" = "donor" ]
|
|
|
|
then
|
|
|
|
|
2018-02-12 22:08:57 +01:00
|
|
|
cat << EOF > "$STUNNEL_CONF"
|
|
|
|
CApath = ${SSTCERT%/*}
|
|
|
|
foreground = yes
|
|
|
|
pid = $STUNNEL_PID
|
|
|
|
debug = warning
|
|
|
|
client = yes
|
|
|
|
connect = ${WSREP_SST_OPT_ADDR%/*}
|
|
|
|
TIMEOUTclose = 0
|
|
|
|
verifyPeer = yes
|
|
|
|
EOF
|
|
|
|
|
2014-08-06 14:39:15 +02:00
|
|
|
if [ $WSREP_SST_OPT_BYPASS -eq 0 ]
|
|
|
|
then
|
|
|
|
|
|
|
|
FLUSHED="$WSREP_SST_OPT_DATA/tables_flushed"
|
2016-02-26 16:49:19 +01:00
|
|
|
ERROR="$WSREP_SST_OPT_DATA/sst_error"
|
|
|
|
|
2014-08-06 14:39:15 +02:00
|
|
|
rm -rf "$FLUSHED"
|
2016-02-26 16:49:19 +01:00
|
|
|
rm -rf "$ERROR"
|
2014-08-06 14:39:15 +02:00
|
|
|
|
|
|
|
# Use deltaxfer only for WAN
|
|
|
|
inv=$(basename $0)
|
|
|
|
[ "$inv" = "wsrep_sst_rsync_wan" ] && WHOLE_FILE_OPT="" \
|
|
|
|
|| WHOLE_FILE_OPT="--whole-file"
|
|
|
|
|
|
|
|
echo "flush tables"
|
|
|
|
|
2015-02-28 04:33:41 +01:00
|
|
|
# Wait for :
|
2016-02-26 16:49:19 +01:00
|
|
|
# (a) Tables to be flushed, AND
|
|
|
|
# (b) Cluster state ID & wsrep_gtid_domain_id to be written to the file, OR
|
|
|
|
# (c) ERROR file, in case flush tables operation failed.
|
|
|
|
|
2014-08-06 14:39:15 +02:00
|
|
|
while [ ! -r "$FLUSHED" ] && ! grep -q ':' "$FLUSHED" >/dev/null 2>&1
|
|
|
|
do
|
2016-02-26 16:49:19 +01:00
|
|
|
# Check whether ERROR file exists.
|
|
|
|
if [ -f "$ERROR" ]
|
|
|
|
then
|
|
|
|
# Flush tables operation failed.
|
|
|
|
rm -rf "$ERROR"
|
|
|
|
exit 255
|
|
|
|
fi
|
|
|
|
|
2014-08-06 14:39:15 +02:00
|
|
|
sleep 0.2
|
|
|
|
done
|
|
|
|
|
|
|
|
STATE="$(cat $FLUSHED)"
|
|
|
|
rm -rf "$FLUSHED"
|
|
|
|
|
|
|
|
sync
|
|
|
|
|
|
|
|
if ! [ -z $WSREP_SST_OPT_BINLOG ]
|
|
|
|
then
|
|
|
|
# Prepare binlog files
|
2016-11-08 14:35:57 +01:00
|
|
|
OLD_PWD="$(pwd)"
|
|
|
|
cd $BINLOG_DIRNAME
|
|
|
|
|
2018-06-26 11:56:19 +02:00
|
|
|
if ! [ -z $WSREP_SST_OPT_BINLOG_INDEX ]
|
|
|
|
binlog_files_full=$(tail -n $BINLOG_N_FILES ${BINLOG_FILENAME}.index)
|
|
|
|
then
|
|
|
|
cd $BINLOG_INDEX_DIRNAME
|
|
|
|
binlog_files_full=$(tail -n $BINLOG_N_FILES ${BINLOG_INDEX_FILENAME}.index)
|
|
|
|
fi
|
|
|
|
|
|
|
|
cd $BINLOG_DIRNAME
|
2014-08-06 14:39:15 +02:00
|
|
|
binlog_files=""
|
|
|
|
for ii in $binlog_files_full
|
|
|
|
do
|
|
|
|
binlog_files="$binlog_files $(basename $ii)"
|
|
|
|
done
|
2018-06-26 11:56:19 +02:00
|
|
|
|
2014-08-06 14:39:15 +02:00
|
|
|
if ! [ -z "$binlog_files" ]
|
|
|
|
then
|
|
|
|
wsrep_log_info "Preparing binlog files for transfer:"
|
|
|
|
tar -cvf $BINLOG_TAR_FILE $binlog_files >&2
|
|
|
|
fi
|
2016-11-08 14:35:57 +01:00
|
|
|
cd "$OLD_PWD"
|
2014-08-06 14:39:15 +02:00
|
|
|
fi
|
|
|
|
|
|
|
|
# first, the normal directories, so that we can detect incompatible protocol
|
|
|
|
RC=0
|
2018-02-12 22:08:57 +01:00
|
|
|
eval rsync ${STUNNEL:+--rsh="$STUNNEL"} \
|
|
|
|
--owner --group --perms --links --specials \
|
2014-08-06 14:39:15 +02:00
|
|
|
--ignore-times --inplace --dirs --delete --quiet \
|
2016-11-08 14:35:57 +01:00
|
|
|
$WHOLE_FILE_OPT ${FILTER} "$WSREP_SST_OPT_DATA/" \
|
2014-08-06 14:39:15 +02:00
|
|
|
rsync://$WSREP_SST_OPT_ADDR >&2 || RC=$?
|
|
|
|
|
|
|
|
if [ "$RC" -ne 0 ]; then
|
|
|
|
wsrep_log_error "rsync returned code $RC:"
|
|
|
|
|
|
|
|
case $RC in
|
|
|
|
12) RC=71 # EPROTO
|
|
|
|
wsrep_log_error \
|
|
|
|
"rsync server on the other end has incompatible protocol. " \
|
|
|
|
"Make sure you have the same version of rsync on all nodes."
|
|
|
|
;;
|
|
|
|
22) RC=12 # ENOMEM
|
|
|
|
;;
|
|
|
|
*) RC=255 # unknown error
|
|
|
|
;;
|
|
|
|
esac
|
|
|
|
exit $RC
|
|
|
|
fi
|
|
|
|
|
2018-08-09 04:24:12 +02:00
|
|
|
# Transfer InnoDB data files
|
|
|
|
rsync ${STUNNEL:+--rsh="$STUNNEL"} \
|
|
|
|
--owner --group --perms --links --specials \
|
|
|
|
--ignore-times --inplace --dirs --delete --quiet \
|
|
|
|
$WHOLE_FILE_OPT -f '+ /ibdata*' -f '+ /ib_lru_dump' \
|
|
|
|
-f '- **' "$INNODB_DATA_HOME_DIR/" \
|
|
|
|
rsync://$WSREP_SST_OPT_ADDR-data_dir >&2 || RC=$?
|
|
|
|
|
|
|
|
if [ $RC -ne 0 ]; then
|
|
|
|
wsrep_log_error "rsync innodb_data_home_dir returned code $RC:"
|
|
|
|
exit 255 # unknown error
|
|
|
|
fi
|
|
|
|
|
2014-08-06 14:39:15 +02:00
|
|
|
# second, we transfer InnoDB log files
|
2018-02-12 22:08:57 +01:00
|
|
|
rsync ${STUNNEL:+--rsh="$STUNNEL"} \
|
|
|
|
--owner --group --perms --links --specials \
|
2014-08-06 14:39:15 +02:00
|
|
|
--ignore-times --inplace --dirs --delete --quiet \
|
|
|
|
$WHOLE_FILE_OPT -f '+ /ib_logfile[0-9]*' -f '- **' "$WSREP_LOG_DIR/" \
|
|
|
|
rsync://$WSREP_SST_OPT_ADDR-log_dir >&2 || RC=$?
|
|
|
|
|
|
|
|
if [ $RC -ne 0 ]; then
|
|
|
|
wsrep_log_error "rsync innodb_log_group_home_dir returned code $RC:"
|
|
|
|
exit 255 # unknown error
|
|
|
|
fi
|
|
|
|
|
|
|
|
# then, we parallelize the transfer of database directories, use . so that pathconcatenation works
|
2016-11-08 14:35:57 +01:00
|
|
|
OLD_PWD="$(pwd)"
|
|
|
|
cd $WSREP_SST_OPT_DATA
|
2014-08-06 14:39:15 +02:00
|
|
|
|
|
|
|
count=1
|
2016-07-24 22:01:14 +02:00
|
|
|
[ "$OS" = "Linux" ] && count=$(grep -c processor /proc/cpuinfo)
|
|
|
|
[ "$OS" = "Darwin" -o "$OS" = "FreeBSD" ] && count=$(sysctl -n hw.ncpu)
|
2014-08-06 14:39:15 +02:00
|
|
|
|
2020-02-11 19:27:59 +01:00
|
|
|
find . -maxdepth 1 -mindepth 1 -type d -not -name "lost+found" -not -name ".zfs" \
|
2017-03-03 21:28:27 +01:00
|
|
|
-print0 | xargs -I{} -0 -P $count \
|
2018-02-12 22:08:57 +01:00
|
|
|
rsync ${STUNNEL:+--rsh="$STUNNEL"} \
|
|
|
|
--owner --group --perms --links --specials \
|
2014-08-06 14:39:15 +02:00
|
|
|
--ignore-times --inplace --recursive --delete --quiet \
|
|
|
|
$WHOLE_FILE_OPT --exclude '*/ib_logfile*' "$WSREP_SST_OPT_DATA"/{}/ \
|
|
|
|
rsync://$WSREP_SST_OPT_ADDR/{} >&2 || RC=$?
|
|
|
|
|
2016-11-08 14:35:57 +01:00
|
|
|
cd "$OLD_PWD"
|
2014-08-06 14:39:15 +02:00
|
|
|
|
|
|
|
if [ $RC -ne 0 ]; then
|
|
|
|
wsrep_log_error "find/rsync returned code $RC:"
|
|
|
|
exit 255 # unknown error
|
|
|
|
fi
|
|
|
|
|
|
|
|
else # BYPASS
|
|
|
|
wsrep_log_info "Bypassing state dump."
|
2015-02-28 04:33:41 +01:00
|
|
|
|
|
|
|
# Store donor's wsrep GTID (state ID) and wsrep_gtid_domain_id
|
|
|
|
# (separated by a space).
|
|
|
|
STATE="$WSREP_SST_OPT_GTID $WSREP_SST_OPT_GTID_DOMAIN_ID"
|
2014-08-06 14:39:15 +02:00
|
|
|
fi
|
|
|
|
|
|
|
|
echo "continue" # now server can resume updating data
|
|
|
|
|
|
|
|
echo "$STATE" > "$MAGIC_FILE"
|
2018-02-12 22:08:57 +01:00
|
|
|
rsync ${STUNNEL:+--rsh="$STUNNEL"} \
|
|
|
|
--archive --quiet --checksum "$MAGIC_FILE" rsync://$WSREP_SST_OPT_ADDR
|
2014-08-06 14:39:15 +02:00
|
|
|
|
|
|
|
echo "done $STATE"
|
|
|
|
|
|
|
|
elif [ "$WSREP_SST_OPT_ROLE" = "joiner" ]
|
|
|
|
then
|
|
|
|
wsrep_check_programs lsof
|
|
|
|
|
|
|
|
touch $SST_PROGRESS_FILE
|
|
|
|
MYSQLD_PID=$WSREP_SST_OPT_PARENT
|
|
|
|
|
|
|
|
MODULE="rsync_sst"
|
|
|
|
|
|
|
|
RSYNC_PID="$WSREP_SST_OPT_DATA/$MODULE.pid"
|
2020-11-18 16:47:39 +01:00
|
|
|
# give some time for lingering rsync from previous SST to complete
|
|
|
|
check_round=0
|
|
|
|
while check_pid $RSYNC_PID && [ $check_round -lt 10 ]
|
|
|
|
do
|
|
|
|
wsrep_log_info "lingering rsync daemon found at startup, waiting for it to exit"
|
|
|
|
check_round=$(( check_round + 1 ))
|
|
|
|
sleep 1
|
|
|
|
done
|
2014-08-06 14:39:15 +02:00
|
|
|
|
|
|
|
if check_pid $RSYNC_PID
|
|
|
|
then
|
|
|
|
wsrep_log_error "rsync daemon already running."
|
|
|
|
exit 114 # EALREADY
|
|
|
|
fi
|
|
|
|
rm -rf "$RSYNC_PID"
|
|
|
|
|
|
|
|
ADDR=$WSREP_SST_OPT_ADDR
|
2019-02-02 10:40:02 +01:00
|
|
|
if [ "${ADDR#\[}" != "$ADDR" ]; then
|
2019-01-26 01:11:45 +01:00
|
|
|
RSYNC_PORT=$(echo $ADDR | awk -F '\\]:' '{ print $2 }')
|
|
|
|
RSYNC_ADDR=$(echo $ADDR | awk -F '\\]:' '{ print $1 }')"]"
|
|
|
|
else
|
|
|
|
RSYNC_PORT=$(echo $ADDR | awk -F ':' '{ print $2 }')
|
|
|
|
RSYNC_ADDR=$(echo $ADDR | awk -F ':' '{ print $1 }')
|
|
|
|
fi
|
2014-08-06 14:39:15 +02:00
|
|
|
if [ -z "$RSYNC_PORT" ]
|
|
|
|
then
|
|
|
|
RSYNC_PORT=4444
|
2019-01-26 01:11:45 +01:00
|
|
|
ADDR="$RSYNC_ADDR:$RSYNC_PORT"
|
2014-08-06 14:39:15 +02:00
|
|
|
fi
|
|
|
|
|
|
|
|
trap "exit 32" HUP PIPE
|
|
|
|
trap "exit 3" INT TERM ABRT
|
|
|
|
trap cleanup_joiner EXIT
|
|
|
|
|
|
|
|
RSYNC_CONF="$WSREP_SST_OPT_DATA/$MODULE.conf"
|
|
|
|
|
2014-10-04 19:53:33 +02:00
|
|
|
if [ -n "${MYSQL_TMP_DIR:-}" ] ; then
|
2017-03-03 21:28:27 +01:00
|
|
|
SILENT="log file = $MYSQL_TMP_DIR/rsyncd.log"
|
2014-10-02 18:54:01 +02:00
|
|
|
else
|
2017-03-03 21:28:27 +01:00
|
|
|
SILENT=""
|
2014-10-02 18:54:01 +02:00
|
|
|
fi
|
|
|
|
|
2014-08-06 14:39:15 +02:00
|
|
|
cat << EOF > "$RSYNC_CONF"
|
|
|
|
pid file = $RSYNC_PID
|
|
|
|
use chroot = no
|
|
|
|
read only = no
|
|
|
|
timeout = 300
|
2014-10-02 18:54:01 +02:00
|
|
|
$SILENT
|
2014-08-06 14:39:15 +02:00
|
|
|
[$MODULE]
|
|
|
|
path = $WSREP_SST_OPT_DATA
|
2020-02-11 19:27:59 +01:00
|
|
|
exclude = .zfs
|
2014-08-06 14:39:15 +02:00
|
|
|
[$MODULE-log_dir]
|
|
|
|
path = $WSREP_LOG_DIR
|
2018-08-09 04:24:12 +02:00
|
|
|
[$MODULE-data_dir]
|
|
|
|
path = $INNODB_DATA_HOME_DIR
|
2014-08-06 14:39:15 +02:00
|
|
|
EOF
|
|
|
|
|
|
|
|
# rm -rf "$DATA"/ib_logfile* # we don't want old logs around
|
|
|
|
|
2017-03-03 21:28:27 +01:00
|
|
|
readonly RSYNC_PORT=${WSREP_SST_OPT_PORT:-4444}
|
2018-08-21 15:52:59 +02:00
|
|
|
# If the IP is local listen only in it
|
|
|
|
if is_local_ip "$RSYNC_ADDR"
|
2016-10-03 12:30:12 +02:00
|
|
|
then
|
2018-02-12 22:08:57 +01:00
|
|
|
RSYNC_EXTRA_ARGS="--address $RSYNC_ADDR"
|
|
|
|
STUNNEL_ACCEPT="$RSYNC_ADDR:$RSYNC_PORT"
|
2016-10-03 12:30:12 +02:00
|
|
|
else
|
2018-02-12 22:08:57 +01:00
|
|
|
# Not local, possibly a NAT, listen on all interfaces
|
|
|
|
RSYNC_EXTRA_ARGS=""
|
|
|
|
STUNNEL_ACCEPT="$RSYNC_PORT"
|
2018-08-21 15:52:59 +02:00
|
|
|
# Overwrite address with all
|
|
|
|
RSYNC_ADDR="*"
|
2016-10-03 12:30:12 +02:00
|
|
|
fi
|
2018-02-12 22:08:57 +01:00
|
|
|
|
|
|
|
if [ -z "$STUNNEL" ]
|
|
|
|
then
|
|
|
|
rsync --daemon --no-detach --port "$RSYNC_PORT" --config "$RSYNC_CONF" ${RSYNC_EXTRA_ARGS} &
|
|
|
|
RSYNC_REAL_PID=$!
|
|
|
|
else
|
|
|
|
cat << EOF > "$STUNNEL_CONF"
|
|
|
|
key = $SSTKEY
|
|
|
|
cert = $SSTCERT
|
|
|
|
foreground = yes
|
|
|
|
pid = $STUNNEL_PID
|
|
|
|
debug = warning
|
|
|
|
client = no
|
|
|
|
[rsync]
|
|
|
|
accept = $STUNNEL_ACCEPT
|
|
|
|
exec = $(which rsync)
|
|
|
|
execargs = rsync --server --daemon --config=$RSYNC_CONF .
|
|
|
|
EOF
|
|
|
|
stunnel "$STUNNEL_CONF" &
|
|
|
|
RSYNC_REAL_PID=$!
|
|
|
|
RSYNC_PID=$STUNNEL_PID
|
|
|
|
fi
|
2014-08-06 14:39:15 +02:00
|
|
|
|
2017-09-03 09:33:27 +02:00
|
|
|
until check_pid_and_port "$RSYNC_PID" "$RSYNC_REAL_PID" "$RSYNC_ADDR" "$RSYNC_PORT"
|
2014-08-06 14:39:15 +02:00
|
|
|
do
|
|
|
|
sleep 0.2
|
|
|
|
done
|
|
|
|
|
2017-03-03 21:28:27 +01:00
|
|
|
echo "ready $WSREP_SST_OPT_HOST:$RSYNC_PORT/$MODULE"
|
2014-08-06 14:39:15 +02:00
|
|
|
|
|
|
|
# wait for SST to complete by monitoring magic file
|
|
|
|
while [ ! -r "$MAGIC_FILE" ] && check_pid "$RSYNC_PID" && \
|
|
|
|
ps -p $MYSQLD_PID >/dev/null
|
|
|
|
do
|
|
|
|
sleep 1
|
|
|
|
done
|
|
|
|
|
|
|
|
if ! ps -p $MYSQLD_PID >/dev/null
|
|
|
|
then
|
|
|
|
wsrep_log_error \
|
|
|
|
"Parent mysqld process (PID:$MYSQLD_PID) terminated unexpectedly."
|
2018-06-20 13:16:34 +02:00
|
|
|
kill -- -"${MYSQLD_PID}"
|
|
|
|
sleep 1
|
2014-08-06 14:39:15 +02:00
|
|
|
exit 32
|
|
|
|
fi
|
|
|
|
|
|
|
|
if ! [ -z $WSREP_SST_OPT_BINLOG ]
|
|
|
|
then
|
|
|
|
|
2016-11-08 14:35:57 +01:00
|
|
|
OLD_PWD="$(pwd)"
|
|
|
|
cd $BINLOG_DIRNAME
|
|
|
|
|
2014-08-06 14:39:15 +02:00
|
|
|
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 >&2
|
|
|
|
for ii in $(ls -1 ${BINLOG_FILENAME}.*)
|
|
|
|
do
|
2018-06-26 11:56:19 +02:00
|
|
|
if ! [ -z $WSREP_SST_OPT_BINLOG_INDEX ]
|
|
|
|
echo ${BINLOG_DIRNAME}/${ii} >> ${BINLOG_FILENAME}.index
|
|
|
|
then
|
|
|
|
echo ${BINLOG_DIRNAME}/${ii} >> ${BINLOG_INDEX_DIRNAME}/${BINLOG_INDEX_FILENAME}.index
|
|
|
|
fi
|
2014-08-06 14:39:15 +02:00
|
|
|
done
|
|
|
|
fi
|
2016-11-08 14:35:57 +01:00
|
|
|
cd "$OLD_PWD"
|
|
|
|
|
2014-08-06 14:39:15 +02:00
|
|
|
fi
|
|
|
|
if [ -r "$MAGIC_FILE" ]
|
|
|
|
then
|
2015-02-28 04:33:41 +01:00
|
|
|
# UUID:seqno & wsrep_gtid_domain_id is received here.
|
|
|
|
cat "$MAGIC_FILE" # Output : UUID:seqno wsrep_gtid_domain_id
|
2014-08-06 14:39:15 +02:00
|
|
|
else
|
|
|
|
# this message should cause joiner to abort
|
|
|
|
echo "rsync process ended without creating '$MAGIC_FILE'"
|
|
|
|
fi
|
|
|
|
wsrep_cleanup_progress_file
|
|
|
|
# cleanup_joiner
|
|
|
|
else
|
|
|
|
wsrep_log_error "Unrecognized role: '$WSREP_SST_OPT_ROLE'"
|
|
|
|
exit 22 # EINVAL
|
|
|
|
fi
|
|
|
|
|
|
|
|
rm -f $BINLOG_TAR_FILE || :
|
|
|
|
|
|
|
|
exit 0
|