summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/mysqld.cc12
-rw-r--r--sql/wsrep_check_opts.cc405
-rw-r--r--sql/wsrep_mysqld.h4
3 files changed, 69 insertions, 352 deletions
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 2c57c164446..4119e0e5554 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -4142,15 +4142,6 @@ static int init_common_variables()
SQLCOM_END + 8);
#endif
-#ifdef WITH_WSREP
- /*
- This is a protection against mutually incompatible option values.
- Note WSREP_ON == global_system_variables.wsrep_on
- */
- if (WSREP_ON && wsrep_check_opts (remaining_argc, remaining_argv))
- global_system_variables.wsrep_on= 0;
-#endif /* WITH_WSREP */
-
if (get_options(&remaining_argc, &remaining_argv))
return 1;
set_server_version();
@@ -4990,6 +4981,9 @@ a file name for --log-bin-index option", opt_binlog_index_name);
}
plugins_are_initialized= TRUE; /* Don't separate from init function */
+ if (wsrep_check_opts())
+ unireg_abort(1);
+
/* we do want to exit if there are any other unknown options */
if (remaining_argc > 1)
{
diff --git a/sql/wsrep_check_opts.cc b/sql/wsrep_check_opts.cc
index 5ec18c79978..a4c12e7deb2 100644
--- a/sql/wsrep_check_opts.cc
+++ b/sql/wsrep_check_opts.cc
@@ -1,4 +1,5 @@
/* Copyright 2011 Codership Oy <http://www.codership.com>
+ Copyright 2014 SkySQL Ab.
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
@@ -13,367 +14,89 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-//#include <mysqld.h>
-#include <sql_class.h>
-//#include <sql_plugin.h>
-//#include <set_var.h>
+#include "mysqld.h"
+#include "sys_vars_shared.h"
+#include "wsrep.h"
+#include "wsrep_sst.h"
+//#include <sql_class.h>
+//#include "wsrep_mysqld.h"
-#include "wsrep_mysqld.h"
+extern char *my_bind_addr_str;
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <ctype.h>
-
-/* This file is about checking for correctness of mysql configuration options */
-
-struct opt
-{
- const char* const name;
- const char* value;
-};
-
-/* A list of options to check.
- * At first we assume default values and then see if they are changed on CLI or
- * in my.cnf */
-static struct opt opts[] =
-{
- { "wsrep_slave_threads", "1" }, // mysqld.cc
- { "bind_address", "0.0.0.0" }, // mysqld.cc
- { "wsrep_sst_method", "rsync" }, // mysqld.cc
- { "wsrep_sst_receive_address","AUTO"}, // mysqld.cc
- { "binlog_format", "ROW" }, // mysqld.cc
- { "wsrep_provider", "none" }, // mysqld.cc
- { "query_cache_type", "0" }, // mysqld.cc
- { "query_cache_size", "0" }, // mysqld.cc
- { "locked_in_memory", "0" }, // mysqld.cc
- { "wsrep_cluster_address", "0" }, // mysqld.cc
- { "locks_unsafe_for_binlog", "0" }, // ha_innodb.cc
- { "autoinc_lock_mode", "1" }, // ha_innodb.cc
- { 0, 0 }
-};
-
-enum
-{
- WSREP_SLAVE_THREADS,
- BIND_ADDRESS,
- WSREP_SST_METHOD,
- WSREP_SST_RECEIVE_ADDRESS,
- BINLOG_FORMAT,
- WSREP_PROVIDER,
- QUERY_CACHE_TYPE,
- QUERY_CACHE_SIZE,
- LOCKED_IN_MEMORY,
- WSREP_CLUSTER_ADDRESS,
- LOCKS_UNSAFE_FOR_BINLOG,
- AUTOINC_LOCK_MODE
-};
-
-
-/* A class to make a copy of argv[] vector */
-struct argv_copy
-{
- int const argc_;
- char** argv_;
-
- argv_copy (int const argc, const char* const argv[]) :
- argc_ (argc),
- argv_ (reinterpret_cast<char**>(calloc(argc_, sizeof(char*))))
- {
- if (argv_)
- {
- for (int i = 0; i < argc_; ++i)
- {
- argv_[i] = strdup(argv[i]);
-
- if (!argv_[i])
- {
- argv_free (); // free whatever bee allocated
- return;
- }
- }
- }
- }
-
- ~argv_copy () { argv_free (); }
-
-private:
- argv_copy (const argv_copy&);
- argv_copy& operator= (const argv_copy&);
-
- void argv_free()
- {
- if (argv_)
- {
- for (int i = 0; (i < argc_) && argv_[i] ; ++i) free (argv_[i]);
- free (argv_);
- argv_ = 0;
- }
- }
-};
-
-/* a short corresponding to '--' byte sequence */
-static short const long_opt_prefix ('-' + ('-' << 8));
-
-/* Normalizes long options to have '_' instead of '-' */
-static int
-normalize_opts (argv_copy& a)
+int wsrep_check_opts()
{
- if (a.argv_)
+ if (wsrep_slave_threads > 1)
+ {
+ sys_var *autoinc_lock_mode=
+ intern_find_sys_var(STRING_WITH_LEN("innodb_autoinc_lock_mode"));
+ bool is_null;
+ if (autoinc_lock_mode &&
+ autoinc_lock_mode->val_int(&is_null, 0, OPT_GLOBAL, 0) != 2)
{
- for (int i = 0; i < a.argc_; ++i)
- {
- char* ptr = a.argv_[i];
- if (long_opt_prefix == *(short*)ptr) // long option
- {
- ptr += 2;
- const char* end = strchr(ptr, '=');
-
- if (!end) end = ptr + strlen(ptr);
-
- for (; ptr != end; ++ptr) if ('-' == *ptr) *ptr = '_';
- }
- }
-
- return 0;
+ WSREP_ERROR("Parallel applying (wsrep_slave_threads > 1) requires"
+ " innodb_autoinc_lock_mode = 2.");
+ return 1;
}
- return EINVAL;
-}
-
-/* Find required options in the argument list and change their values */
-static int
-find_opts (argv_copy& a, struct opt* const opts)
-{
- for (int i = 0; i < a.argc_; ++i)
- {
- char* ptr = a.argv_[i] + 2; // we're interested only in long options
-
- struct opt* opt = opts;
- for (; 0 != opt->name; ++opt)
- {
- if (!strstr(ptr, opt->name)) continue; // try next option
-
- /* 1. try to find value after the '=' */
- opt->value = strchr(ptr, '=') + 1;
-
- /* 2. if no '=', try next element in the argument vector */
- if (reinterpret_cast<void*>(1) == opt->value)
- {
- /* also check that the next element is not an option itself */
- if (i + 1 < a.argc_ && *(a.argv_[i + 1]) != '-')
- {
- ++i;
- opt->value = a.argv_[i];
- }
- else opt->value = ""; // no value supplied (like boolean opt)
- }
-
- break; // option found, break inner loop
- }
- }
-
- return 0;
-}
-
-/* Parses string for an integer. Returns 0 on success. */
-int get_long_long (const struct opt& opt, long long* const val, int const base)
-{
- const char* const str = opt.value;
-
- if ('\0' != *str)
- {
- char* endptr;
-
- *val = strtoll (str, &endptr, base);
-
- if ('k' == *endptr || 'K' == *endptr)
- {
- *val *= 1024L;
- endptr++;
- }
- else if ('m' == *endptr || 'M' == *endptr)
- {
- *val *= 1024L * 1024L;
- endptr++;
- }
- else if ('g' == *endptr || 'G' == *endptr)
- {
- *val *= 1024L * 1024L * 1024L;
- endptr++;
- }
-
- if ('\0' == *endptr) return 0; // the whole string was a valid integer
- }
-
- WSREP_ERROR ("Bad value for *%s: '%s'. Should be integer.",
- opt.name, opt.value);
-
- return EINVAL;
-}
-
-/* This is flimzy coz hell knows how mysql interprets boolean strings...
- * and, no, I'm not going to become versed in how mysql handles options -
- * I'd rather sing.
-
- Aha, http://dev.mysql.com/doc/refman/5.1/en/dynamic-system-variables.html:
- Variables that have a type of “boolean” can be set to 0, 1, ON or OFF. (If you
- set them on the command line or in an option file, use the numeric values.)
-
- So it is '0' for FALSE, '1' or empty string for TRUE
-
- */
-int get_bool (const struct opt& opt, bool* const val)
-{
- const char* str = opt.value;
-
- while (isspace(*str)) ++str; // skip initial whitespaces
-
- ssize_t str_len = strlen(str);
- switch (str_len)
- {
- case 0:
- *val = true;
- return 0;
- case 1:
- if ('0' == *str || '1' == *str)
- {
- *val = ('1' == *str);
- return 0;
- }
- }
-
- WSREP_ERROR ("Bad value for *%s: '%s'. Should be '0', '1' or empty string.",
- opt.name, opt.value);
-
- return EINVAL;
-}
-
-static int
-check_opts (int const argc, const char* const argv[], struct opt opts[])
-{
- /* First, make a copy of argv to be able to manipulate it */
- argv_copy a(argc, argv);
-
- if (!a.argv_)
- {
- WSREP_ERROR ("Could not copy argv vector: not enough memory.");
- return ENOMEM;
- }
-
- int err = normalize_opts (a);
- if (err)
- {
- WSREP_ERROR ("Failed to normalize options.");
- return err;
- }
-
- err = find_opts (a, opts);
- if (err)
- {
- WSREP_ERROR ("Failed to parse options.");
- return err;
- }
-
- /* At this point we have updated default values in our option list to
- what has been specified on the command line / my.cnf */
-
- long long slave_threads;
- err = get_long_long (opts[WSREP_SLAVE_THREADS], &slave_threads, 10);
- if (err) return err;
-
- int rcode = 0;
-
- if (slave_threads > 1)
- /* Need to check AUTOINC_LOCK_MODE and LOCKS_UNSAFE_FOR_BINLOG */
- {
- long long autoinc_lock_mode;
- err = get_long_long (opts[AUTOINC_LOCK_MODE], &autoinc_lock_mode, 10);
- if (err) return err;
-
- bool locks_unsafe_for_binlog;
- err = get_bool (opts[LOCKS_UNSAFE_FOR_BINLOG],&locks_unsafe_for_binlog);
- if (err) return err;
-
- if (autoinc_lock_mode != 2)
- {
- WSREP_ERROR ("Parallel applying (wsrep_slave_threads > 1) requires"
- " innodb_autoinc_lock_mode = 2.");
- rcode = EINVAL;
- }
- }
-
- bool locked_in_memory;
- err = get_bool (opts[LOCKED_IN_MEMORY], &locked_in_memory);
- if (err) { WSREP_ERROR("get_bool error: %s", strerror(err)); return err; }
if (locked_in_memory)
{
- WSREP_ERROR ("Memory locking is not supported (locked_in_memory=%s)",
- locked_in_memory ? "ON" : "OFF");
- rcode = EINVAL;
+ WSREP_ERROR("Memory locking is not supported (locked_in_memory=ON)");
+ return 1;
}
- if (!strcasecmp(opts[WSREP_SST_METHOD].value,"mysqldump"))
+ if (!strcasecmp(wsrep_sst_method, "mysqldump"))
{
- if (!strcasecmp(opts[BIND_ADDRESS].value, "127.0.0.1") ||
- !strcasecmp(opts[BIND_ADDRESS].value, "localhost"))
- {
- WSREP_ERROR ("wsrep_sst_method is set to 'mysqldump' yet "
- "mysqld bind_address is set to '%s', which makes it "
- "impossible to receive state transfer from another "
- "node, since mysqld won't accept such connections. "
- "If you wish to use mysqldump state transfer method, "
- "set bind_address to allow mysql client connections "
- "from other cluster members (e.g. 0.0.0.0).",
- opts[BIND_ADDRESS].value);
- rcode = EINVAL;
- }
+ if (!strcasecmp(my_bind_addr_str, "127.0.0.1") ||
+ !strcasecmp(my_bind_addr_str, "localhost"))
+ {
+ WSREP_ERROR("wsrep_sst_method is set to 'mysqldump' yet "
+ "mysqld bind_address is set to '%s', which makes it "
+ "impossible to receive state transfer from another "
+ "node, since mysqld won't accept such connections. "
+ "If you wish to use mysqldump state transfer method, "
+ "set bind_address to allow mysql client connections "
+ "from other cluster members (e.g. 0.0.0.0).",
+ my_bind_addr_str);
+ return 1;
+ }
}
else
{
- // non-mysqldump SST requires wsrep_cluster_address on startup
- if (strlen(opts[WSREP_CLUSTER_ADDRESS].value) == 0)
- {
- WSREP_ERROR ("%s SST method requires wsrep_cluster_address to be "
- "configured on startup.",opts[WSREP_SST_METHOD].value);
- rcode = EINVAL;
- }
+ // non-mysqldump SST requires wsrep_cluster_address on startup
+ if (!wsrep_cluster_address || !wsrep_cluster_address[0])
+ {
+ WSREP_ERROR ("%s SST method requires wsrep_cluster_address to be "
+ "configured on startup.", wsrep_sst_method);
+ return 1;
+ }
}
- if (strcasecmp(opts[WSREP_SST_RECEIVE_ADDRESS].value, "AUTO"))
+ if (strcasecmp(wsrep_sst_receive_address, "AUTO"))
{
- if (!strncasecmp(opts[WSREP_SST_RECEIVE_ADDRESS].value,
- "127.0.0.1", strlen("127.0.0.1")) ||
- !strncasecmp(opts[WSREP_SST_RECEIVE_ADDRESS].value,
- "localhost", strlen("localhost")))
- {
- WSREP_WARN ("wsrep_sst_receive_address is set to '%s' which "
- "makes it impossible for another host to reach this "
- "one. Please set it to the address which this node "
- "can be connected at by other cluster members.",
- opts[WSREP_SST_RECEIVE_ADDRESS].value);
-// rcode = EINVAL;
- }
+ if (!strncasecmp(wsrep_sst_receive_address, STRING_WITH_LEN("127.0.0.1")) ||
+ !strncasecmp(wsrep_sst_receive_address, STRING_WITH_LEN("localhost")))
+ {
+ WSREP_WARN("wsrep_sst_receive_address is set to '%s' which "
+ "makes it impossible for another host to reach this "
+ "one. Please set it to the address which this node "
+ "can be connected at by other cluster members.",
+ wsrep_sst_receive_address);
+ }
}
- if (strcasecmp(opts[WSREP_PROVIDER].value, "none"))
+ if (strcasecmp(wsrep_provider, "NONE"))
{
- if (strcasecmp(opts[BINLOG_FORMAT].value, "ROW"))
- {
- WSREP_ERROR ("Only binlog_format = 'ROW' is currently supported. "
- "Configured value: '%s'. Please adjust your "
- "configuration.", opts[BINLOG_FORMAT].value);
-
- rcode = EINVAL;
- }
+ if (global_system_variables.binlog_format != BINLOG_FORMAT_ROW)
+ {
+ WSREP_ERROR("Only binlog_format = 'ROW' is currently supported. "
+ "Configured value: '%s'. Please adjust your "
+ "configuration.",
+ binlog_format_names[global_system_variables.binlog_format]);
+
+ return 1;
+ }
}
-
- return rcode;
-}
-
-int
-wsrep_check_opts (int const argc, char* const* const argv)
-{
- return check_opts (argc, argv, opts);
+ }
+ return 0;
}
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index ce12c13b5a8..d9ac32d1f6c 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -152,8 +152,8 @@ extern void wsrep_kill_mysql(THD *thd);
/* new defines */
extern void wsrep_stop_replication(THD *thd);
extern bool wsrep_start_replication();
-extern bool wsrep_sync_wait (THD* thd, uint mask = WSREP_SYNC_WAIT_BEFORE_READ);
-extern int wsrep_check_opts (int argc, char* const* argv);
+extern bool wsrep_sync_wait(THD* thd, uint mask = WSREP_SYNC_WAIT_BEFORE_READ);
+extern int wsrep_check_opts();
extern void wsrep_prepend_PATH (const char* path);
/* some inline functions are defined in wsrep_mysqld_inl.h */