summaryrefslogtreecommitdiff
path: root/sql/wsrep_sst.cc
diff options
context:
space:
mode:
authorJulius Goryavsky <julius.goryavsky@mariadb.com>2019-07-30 13:45:13 +0200
committerJulius Goryavsky <julius.goryavsky@mariadb.com>2019-08-19 23:45:35 +0200
commitff6d3075d5e66b3248b37379b44c6c6abf1ef0c3 (patch)
tree6cf948f821309a868dd26bc624cf09be602bcf3c /sql/wsrep_sst.cc
parent68e6c2d7688101e3941ae17ea4a36c79077ed474 (diff)
downloadmariadb-git-ff6d3075d5e66b3248b37379b44c6c6abf1ef0c3.tar.gz
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.
Diffstat (limited to 'sql/wsrep_sst.cc')
-rw-r--r--sql/wsrep_sst.cc86
1 files changed, 78 insertions, 8 deletions
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index cb8b1cab225..fe9f5650b4f 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -648,17 +648,76 @@ static int sst_append_data_dir(wsp::env& env, const char* data_dir)
return -env.error();
}
+static size_t 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):
+ */
+ size_t cmd_len= 4096;
+ bool extra= false;
+ /*
+ If mysqld was started with arguments, add them all:
+ */
+ if (orig_argc > 1)
+ {
+ for (int 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)
+ {
+ size_t n = strlen(WSREP_SST_OPT_MYSQLD);
+ *cmd_str++ = ' ';
+ memcpy(cmd_str, WSREP_SST_OPT_MYSQLD, n * sizeof(char));
+ cmd_str += n;
+ for (int 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;
+ size_t const cmd_len= estimate_cmd_len(&extra_args);
wsp::string cmd_str(cmd_len);
if (!cmd_str())
{
- WSREP_ERROR("sst_prepare_other(): could not allocate cmd buffer of %d bytes",
+ WSREP_ERROR("sst_prepare_other(): could not allocate cmd buffer of %zd bytes",
cmd_len);
return -ENOMEM;
}
@@ -709,6 +768,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())
{
@@ -972,13 +1034,14 @@ 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;
- wsp::string cmd_str(cmd_len);
+ bool extra_args;
+ size_t const cmd_len= estimate_cmd_len(&extra_args);
+ wsp::string cmd_str(cmd_len);
if (!cmd_str())
{
WSREP_ERROR("sst_donate_mysqldump(): "
- "could not allocate cmd buffer of %d bytes", cmd_len);
+ "could not allocate cmd buffer of %zd bytes", cmd_len);
return -ENOMEM;
}
@@ -1007,6 +1070,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);
@@ -1326,13 +1392,14 @@ static int sst_donate_other (const char* method,
bool bypass,
char** env) // carries auth info
{
- int const cmd_len= 4096;
- wsp::string cmd_str(cmd_len);
+ bool extra_args;
+ size_t const cmd_len= estimate_cmd_len(&extra_args);
+ wsp::string cmd_str(cmd_len);
if (!cmd_str())
{
WSREP_ERROR("sst_donate_other(): "
- "could not allocate cmd buffer of %d bytes", cmd_len);
+ "could not allocate cmd buffer of %zd bytes", cmd_len);
return -ENOMEM;
}
@@ -1373,6 +1440,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;