diff options
author | Julius Goryavsky <julius.goryavsky@mariadb.com> | 2019-06-13 13:59:54 +0200 |
---|---|---|
committer | Julius Goryavsky <julius.goryavsky@mariadb.com> | 2019-06-13 13:59:54 +0200 |
commit | f9df3a341c42ae791c460851d4fc52b57841b24b (patch) | |
tree | c9b273c9e0ca9035312cd30765bf178561735a9f | |
parent | e68d3e45572caa41bd167b7934e2b382a31e6cb5 (diff) | |
download | mariadb-git-bb-10.5-MDEV-18863.tar.gz |
MDEV-18863: Galera SST scripts can't read [mysqldN] option groupsbb-10.5-MDEV-18863
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 from the server, if that option was set
for mysqld when the server was started.
However, the SST script 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 and therefore cannot transfer them to mariabackup.
To correct these shortcomings, we need to add a transfer to the
script of all the parameters of the original mysqld call, and in
the SST scripts themselves provide for the transfer 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 line of the original parameters,
as received by 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.
-rw-r--r-- | scripts/mysqld_multi.sh | 13 | ||||
-rwxr-xr-x | scripts/wsrep_sst_common.sh | 58 | ||||
-rw-r--r-- | scripts/wsrep_sst_mariabackup.sh | 36 | ||||
-rw-r--r-- | scripts/wsrep_sst_rsync.sh | 10 | ||||
-rw-r--r-- | sql/wsrep_mysqld.cc | 2 | ||||
-rw-r--r-- | sql/wsrep_sst.cc | 79 | ||||
-rw-r--r-- | sql/wsrep_sst.h | 1 |
7 files changed, 188 insertions, 11 deletions
diff --git a/scripts/mysqld_multi.sh b/scripts/mysqld_multi.sh index 7add8541d7a..a00fab433e8 100644 --- a/scripts/mysqld_multi.sh +++ b/scripts/mysqld_multi.sh @@ -308,7 +308,9 @@ sub report_mysqlds sub start_mysqlds() { - my (@groups, $com, $tmp, $i, @options, $j, $mysqld_found, $info_sent); + my (@groups, $com, $tmp, $i, @options, $j, $mysqld_found, $suffix_found, $info_sent); + + $suffix_found= 0; if (!$opt_no_log) { @@ -347,6 +349,10 @@ sub start_mysqlds() $options[$j]= quote_shell_word($options[$j]); $tmp.= " $options[$j]"; } + elseif ("--defaults-group-suffix=" eq substr($options[$j], 0, 24)) + { + $suffix_found= 1; + } else { $options[$j]= quote_shell_word($options[$j]); @@ -364,6 +370,11 @@ sub start_mysqlds() } $com.= $tmp; + if (!$suffix_found) + { + $com.= " --defaults-group-suffix=$i"; + } + if ($opt_wsrep_new_cluster) { $com.= " --wsrep-new-cluster"; } diff --git a/scripts/wsrep_sst_common.sh b/scripts/wsrep_sst_common.sh index 41c6f3370f8..b1b586868df 100755 --- a/scripts/wsrep_sst_common.sh +++ b/scripts/wsrep_sst_common.sh @@ -28,7 +28,12 @@ WSREP_SST_OPT_PSWD=${WSREP_SST_OPT_PSWD:-} WSREP_SST_OPT_DEFAULT="" WSREP_SST_OPT_EXTRA_DEFAULT="" WSREP_SST_OPT_SUFFIX_DEFAULT="" +WSREP_SST_OPT_SUFFIX_VALUE="" +WSREP_SST_OPT_MYSQLD="" INNODB_DATA_HOME_DIR_ARG="" +INNODB_LOG_GROUP_HOME_ARG="" +INNODB_UNDO_DIR_ARG="" +LOG_BIN_ARG="" while [ $# -gt 0 ]; do case "$1" in @@ -83,6 +88,18 @@ case "$1" in readonly INNODB_DATA_HOME_DIR_ARG="$2" shift ;; + '--innodb-log-group-home-dir') + readonly INNODB_LOG_GROUP_HOME_ARG="$2" + shift + ;; + '--innodb-undo-directory') + readonly INNODB_UNDO_DIR_ARG="$2" + shift + ;; + '--log-bin') + readonly LOG_BIN_ARG="$2" + shift + ;; '--defaults-file') readonly WSREP_SST_OPT_DEFAULT="$1=$2" shift @@ -93,6 +110,7 @@ case "$1" in ;; '--defaults-group-suffix') readonly WSREP_SST_OPT_SUFFIX_DEFAULT="$1=$2" + readonly WSREP_SST_OPT_SUFFIX_VALUE="$2" shift ;; '--host') @@ -143,6 +161,46 @@ case "$1" in readonly WSREP_SST_OPT_GTID_DOMAIN_ID="$2" shift ;; + '--mysqld-args') + original_cmd="" + shift + while [ $# -gt 0 ]; do + option=${1%%=*} + if [ "$option" != "--defaults-file" ]; then + value=${1#*=} + case "$option" in + '--innodb-data-home-dir') + if [ -z "$INNODB_DATA_HOME_DIR_ARG" ]; then + readonly INNODB_DATA_HOME_DIR_ARG="$value" + fi + ;; + '--innodb-log-group-home-dir') + if [ -z "$INNODB_LOG_GROUP_HOME_ARG" ]; then + readonly INNODB_LOG_GROUP_HOME_ARG="$value" + fi + ;; + '--innodb-undo-directory') + if [ -z "$INNODB_UNDO_DIR_ARG" ]; then + readonly INNODB_UNDO_DIR_ARG="$value" + fi + ;; + '--log-bin') + if [ -z "$LOG_BIN_ARG" ]; then + readonly LOG_BIN_ARG="$value" + fi + ;; + esac + if [ -z "$original_cmd" ]; then + original_cmd="$1" + else + original_cmd+=" $1" + fi + fi + shift + done + readonly WSREP_SST_OPT_MYSQLD="$original_cmd" + break + ;; *) # must be command # usage # exit 1 diff --git a/scripts/wsrep_sst_mariabackup.sh b/scripts/wsrep_sst_mariabackup.sh index 6c3206a03e1..13595937321 100644 --- a/scripts/wsrep_sst_mariabackup.sh +++ b/scripts/wsrep_sst_mariabackup.sh @@ -697,8 +697,7 @@ if [[ ${FORCE_FTWRL:-0} -eq 1 ]];then iopts+=" --no-backup-locks " fi - -INNOEXTRA="" +INNOEXTRA=$WSREP_SST_OPT_MYSQLD INNODB_DATA_HOME_DIR=${INNODB_DATA_HOME_DIR:-""} # Try to set INNODB_DATA_HOME_DIR from the command line: @@ -707,6 +706,9 @@ if [ ! -z "$INNODB_DATA_HOME_DIR_ARG" ]; then fi # if INNODB_DATA_HOME_DIR env. 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$WSREP_SST_OPT_SUFFIX_VALUE innodb-data-home-dir '') +fi +if [ -z "$INNODB_DATA_HOME_DIR" ]; then INNODB_DATA_HOME_DIR=$(parse_cnf --mysqld innodb-data-home-dir '') fi if [ ! -z "$INNODB_DATA_HOME_DIR" ]; then @@ -826,7 +828,7 @@ then exit 93 fi - if [[ -z $(parse_cnf --mysqld tmpdir "") && -z $(parse_cnf xtrabackup tmpdir "") ]];then + if [[ -z $(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE tmpdir "") && -z $(parse_cnf --mysqld tmpdir "") && -z $(parse_cnf xtrabackup tmpdir "") ]];then xtmpdir=$(mktemp -d) tmpopts=" --tmpdir=$xtmpdir " wsrep_log_info "Using $xtmpdir as xtrabackup temporary directory" @@ -949,8 +951,24 @@ then [[ -n $SST_PROGRESS_FILE ]] && touch $SST_PROGRESS_FILE ib_home_dir=$INNODB_DATA_HOME_DIR - ib_log_dir=$(parse_cnf --mysqld innodb-log-group-home-dir "") - ib_undo_dir=$(parse_cnf --mysqld innodb-undo-directory "") + + # Try to set ib_log_dir from the command line: + ib_log_dir=$INNODB_LOG_GROUP_HOME_ARG + if [ -z "$ib_log_dir" ]; then + ib_log_dir=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-log-group-home-dir "") + fi + if [ -z "$ib_log_dir" ]; then + ib_log_dir=$(parse_cnf --mysqld innodb-log-group-home-dir "") + fi + + # Try to set ib_undo_dir from the command line: + ib_undo_dir=$INNODB_UNDO_DIR_ARG + if [ -z "$ib_undo_dir" ]; then + ib_undo_dir=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-undo-directory "") + fi + if [ -z "$ib_undo_dir" ]; then + ib_undo_dir=$(parse_cnf --mysqld innodb-undo-directory "") + fi stagemsg="Joiner-Recv" @@ -1027,7 +1045,13 @@ then find $ib_home_dir $ib_log_dir $ib_undo_dir $DATA -mindepth 1 -prune -regex $cpat -o -exec rm -rfv {} 1>&2 \+ fi - tempdir=$(parse_cnf --mysqld log-bin "") + tempdir=$LOG_BIN_ARG + if [ -z "$tempdir" ]; then + tempdir=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE log-bin "") + fi + if [ -z "$tempdir" ]; then + tempdir=$(parse_cnf --mysqld log-bin "") + fi if [[ -n ${tempdir:-} ]];then binlog_dir=$(dirname $tempdir) binlog_file=$(basename $tempdir) diff --git a/scripts/wsrep_sst_rsync.sh b/scripts/wsrep_sst_rsync.sh index 0fb7509d387..82d15dba68e 100644 --- a/scripts/wsrep_sst_rsync.sh +++ b/scripts/wsrep_sst_rsync.sh @@ -151,8 +151,15 @@ then fi WSREP_LOG_DIR=${WSREP_LOG_DIR:-""} +# Try to set WSREP_LOG_DIR from the command line: +if [ ! -z "$WSREP_LOG_DIR" ]; then + WSREP_LOG_DIR=$INNODB_LOG_GROUP_HOME_ARG +fi # 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=$(parse_cnf mysqld$WSREP_SST_OPT_SUFFIX_VALUE innodb-log-group-home-dir '') +fi +if [ -z "$WSREP_LOG_DIR" ]; then WSREP_LOG_DIR=$(parse_cnf --mysqld innodb-log-group-home-dir '') fi @@ -171,6 +178,9 @@ if [ ! -z "$INNODB_DATA_HOME_DIR_ARG" ]; then fi # if INNODB_DATA_HOME_DIR env. 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$WSREP_SST_OPT_SUFFIX_VALUE innodb-data-home-dir '') +fi +if [ -z "$INNODB_DATA_HOME_DIR" ]; then INNODB_DATA_HOME_DIR=$(parse_cnf --mysqld innodb-data-home-dir '') fi diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index d96eb6a1a36..4d424d3fd35 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2694,9 +2694,9 @@ void* start_wsrep_THD(void *arg) 'Error in my_thread_global_end(): 2 threads didn't exit' at server shutdown */ + server_threads.erase(thd); } - server_threads.erase(thd); delete thd; my_thread_end(); return(NULL); diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc index 3181415dad1..1f149832e66 100644 --- a/sql/wsrep_sst.cc +++ b/sql/wsrep_sst.cc @@ -576,12 +576,74 @@ static int sst_append_data_dir(wsp::env& env, const char* data_dir) return -env.error(); } +static int estimate_cmd_len (bool* extra_args) +{ + /* + The length of the area reserved for the control parameters + of the SST script (excluding the copying of the original + mysqld arguments): + */ + int cmd_len= 4096; + bool extra= false; + /* + If mysqld was started with arguments, add them all: + */ + if (orig_argc > 1) + { + int i; + for (i = 1; i < orig_argc; i++) + { + cmd_len += strlen(orig_argv[i]); + } + extra = true; + cmd_len += strlen(WSREP_SST_OPT_MYSQLD); + /* + Add the separating spaces between arguments, + and one additional space before "--mysqld-args": + */ + cmd_len += orig_argc; + } + *extra_args= extra; + return cmd_len; +} + +static void copy_orig_argv (char* cmd_str) +{ + /* + If mysqld was started with arguments, copy them all: + */ + if (orig_argc > 1) + { + int i; + size_t n; + *cmd_str++ = ' '; + n = strlen(WSREP_SST_OPT_MYSQLD); + memcpy(cmd_str, WSREP_SST_OPT_MYSQLD, n * sizeof(char)); + cmd_str += n; + for (i = 1; i < orig_argc; i++) + { + char* arg= orig_argv[i]; + *cmd_str++ = ' '; + n = strlen(arg); + memcpy(cmd_str, arg, n * sizeof(char)); + cmd_str += n; + } + /* + Add a terminating null character (not counted in the length, + since we've overwritten the original null character which + was previously added by snprintf: + */ + *cmd_str = 0; + } +} + static ssize_t sst_prepare_other (const char* method, const char* sst_auth, const char* addr_in, const char** addr_out) { - int const cmd_len= 4096; + bool extra_args; + int const cmd_len= estimate_cmd_len(&extra_args); wsp::string cmd_str(cmd_len); if (!cmd_str()) @@ -637,6 +699,9 @@ static ssize_t sst_prepare_other (const char* method, return (ret < 0 ? ret : -EMSGSIZE); } + if (extra_args) + copy_orig_argv(cmd_str() + ret); + wsp::env env(NULL); if (env.error()) { @@ -890,7 +955,8 @@ static int sst_donate_mysqldump (const char* addr, } memcpy(host, address.get_address(), address.get_address_len()); int port= address.get_port(); - int const cmd_len= 4096; + bool extra_args; + int const cmd_len= estimate_cmd_len(&extra_args); wsp::string cmd_str(cmd_len); if (!cmd_str()) @@ -933,6 +999,9 @@ static int sst_donate_mysqldump (const char* addr, return (ret < 0 ? ret : -EMSGSIZE); } + if (extra_args) + copy_orig_argv(cmd_str() + ret); + WSREP_DEBUG("Running: '%s'", cmd_str()); ret= sst_run_shell (cmd_str(), env, 3); @@ -1283,7 +1352,8 @@ static int sst_donate_other (const char* method, bool bypass, char** env) // carries auth info { - int const cmd_len= 4096; + bool extra_args; + int const cmd_len= estimate_cmd_len(&extra_args); wsp::string cmd_str(cmd_len); if (!cmd_str()) @@ -1345,6 +1415,9 @@ static int sst_donate_other (const char* method, return (ret < 0 ? ret : -EMSGSIZE); } + if (extra_args) + copy_orig_argv(cmd_str() + ret); + if (!bypass && wsrep_sst_donor_rejects_queries) sst_reject_queries(FALSE); pthread_t tmp; diff --git a/sql/wsrep_sst.h b/sql/wsrep_sst.h index eb218647bc0..2389db4abe7 100644 --- a/sql/wsrep_sst.h +++ b/sql/wsrep_sst.h @@ -32,6 +32,7 @@ #define WSREP_SST_OPT_PARENT "--parent" #define WSREP_SST_OPT_BINLOG "--binlog" #define WSREP_SST_OPT_BINLOG_INDEX "--binlog-index" +#define WSREP_SST_OPT_MYSQLD "--mysqld-args" // mysqldump-specific options #define WSREP_SST_OPT_USER "--user" |