summaryrefslogtreecommitdiff
path: root/sql/sys_vars.cc
diff options
context:
space:
mode:
authorJulius Goryavsky <sysprg@gmail.com>2019-02-15 10:58:59 +0100
committerJan Lindström <jan.lindstrom@mariadb.com>2019-02-25 11:19:07 +0200
commit243f829c1c772c1b8e9e0717fbf5839e84244559 (patch)
tree43934a4eeeb002ee85607a7d26c492e4ee8b58cd /sql/sys_vars.cc
parent28cb041754f9f77e915ecd9c5276e02a1ab4cec5 (diff)
downloadmariadb-git-243f829c1c772c1b8e9e0717fbf5839e84244559.tar.gz
MDEV-9519: Data corruption will happen on the Galera cluster size change
If we have a 2+ node cluster which is replicating from an async master and the binlog_format is set to STATEMENT and multi-row inserts are executed on a table with an auto_increment column such that values are automatically generated by MySQL, then the server node generates wrong auto_increment values, which are different from what was generated on the async master. In the title of the MDEV-9519 it was proposed to ban start slave on a Galera if master binlog_format = statement and wsrep_auto_increment_control = 1, but the problem can be solved without such a restriction. The causes and fixes: 1. We need to improve processing of changing the auto-increment values after changing the cluster size. 2. If wsrep auto_increment_control switched on during operation of the node, then we should immediately update the auto_increment_increment and auto_increment_offset global variables, without waiting of the next invocation of the wsrep_view_handler_cb() callback. In the current version these variables retain its initial values if wsrep_auto_increment_control is switched on during operation of the node, which leads to inconsistent results on the different nodes in some scenarios. 3. If wsrep auto_increment_control switched off during operation of the node, then we must return the original values of the auto_increment_increment and auto_increment_offset global variables, as the user has set. To make this possible, we need to add a "shadow copies" of these variables (which stores the latest values set by the user). https://jira.mariadb.org/browse/MDEV-9519
Diffstat (limited to 'sql/sys_vars.cc')
-rw-r--r--sql/sys_vars.cc93
1 files changed, 92 insertions, 1 deletions
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index d1db14d7b35..223015e81c2 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -345,13 +345,56 @@ static Sys_var_long Sys_pfs_connect_attrs_size(
#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
+#ifdef WITH_WSREP
+
+/*
+ We need to keep the original values set by the user, as they will
+ be lost if wsrep_auto_increment_control set to 'ON':
+*/
+static bool update_auto_increment_increment (sys_var *self, THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ global_system_variables.saved_auto_increment_increment=
+ global_system_variables.auto_increment_increment;
+ else
+ thd->variables.saved_auto_increment_increment=
+ thd->variables.auto_increment_increment;
+ return false;
+}
+
+#endif /* WITH_WSREP */
+
static Sys_var_ulong Sys_auto_increment_increment(
"auto_increment_increment",
"Auto-increment columns are incremented by this",
SESSION_VAR(auto_increment_increment),
CMD_LINE(OPT_ARG),
VALID_RANGE(1, 65535), DEFAULT(1), BLOCK_SIZE(1),
+#ifdef WITH_WSREP
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(update_auto_increment_increment));
+#else
NO_MUTEX_GUARD, IN_BINLOG);
+#endif /* WITH_WSREP */
+
+#ifdef WITH_WSREP
+
+/*
+ We need to keep the original values set by the user, as they will
+ be lost if wsrep_auto_increment_control set to 'ON':
+*/
+static bool update_auto_increment_offset (sys_var *self, THD *thd, enum_var_type type)
+{
+ if (type == OPT_GLOBAL)
+ global_system_variables.saved_auto_increment_offset=
+ global_system_variables.auto_increment_offset;
+ else
+ thd->variables.saved_auto_increment_offset=
+ thd->variables.auto_increment_offset;
+ return false;
+}
+
+#endif /* WITH_WSREP */
static Sys_var_ulong Sys_auto_increment_offset(
"auto_increment_offset",
@@ -360,7 +403,12 @@ static Sys_var_ulong Sys_auto_increment_offset(
SESSION_VAR(auto_increment_offset),
CMD_LINE(OPT_ARG),
VALID_RANGE(1, 65535), DEFAULT(1), BLOCK_SIZE(1),
+#ifdef WITH_WSREP
+ NO_MUTEX_GUARD, IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(update_auto_increment_offset));
+#else
NO_MUTEX_GUARD, IN_BINLOG);
+#endif /* WITH_WSREP */
static Sys_var_mybool Sys_automatic_sp_privileges(
"automatic_sp_privileges",
@@ -4851,11 +4899,54 @@ static Sys_var_ulong Sys_wsrep_retry_autocommit(
SESSION_VAR(wsrep_retry_autocommit), CMD_LINE(REQUIRED_ARG),
VALID_RANGE(0, 10000), DEFAULT(1), BLOCK_SIZE(1));
+static bool update_wsrep_auto_increment_control (sys_var *self, THD *thd, enum_var_type type)
+{
+ if (wsrep_auto_increment_control)
+ {
+ /*
+ The variables that control auto increment shall be calculated
+ automaticaly based on the size of the cluster. This usually done
+ within the wsrep_view_handler_cb callback. However, if the user
+ manually sets the value of wsrep_auto_increment_control to 'ON',
+ then we should to re-calculate these variables again (because
+ these values may be required before wsrep_view_handler_cb will
+ be re-invoked, which is rarely invoked if the cluster stays in
+ the stable state):
+ */
+ global_system_variables.auto_increment_increment=
+ wsrep_cluster_size ? wsrep_cluster_size : 1;
+ global_system_variables.auto_increment_offset=
+ wsrep_local_index >= 0 ? wsrep_local_index + 1 : 1;
+ thd->variables.auto_increment_increment=
+ global_system_variables.auto_increment_increment;
+ thd->variables.auto_increment_offset=
+ global_system_variables.auto_increment_offset;
+ }
+ else
+ {
+ /*
+ We must restore the last values of the variables that
+ are explicitly specified by the user:
+ */
+ global_system_variables.auto_increment_increment=
+ global_system_variables.saved_auto_increment_increment;
+ global_system_variables.auto_increment_offset=
+ global_system_variables.saved_auto_increment_offset;
+ thd->variables.auto_increment_increment=
+ thd->variables.saved_auto_increment_increment;
+ thd->variables.auto_increment_offset=
+ thd->variables.saved_auto_increment_offset;
+ }
+ return false;
+}
+
static Sys_var_mybool Sys_wsrep_auto_increment_control(
"wsrep_auto_increment_control", "To automatically control the "
"assignment of autoincrement variables",
GLOBAL_VAR(wsrep_auto_increment_control),
- CMD_LINE(OPT_ARG), DEFAULT(TRUE));
+ CMD_LINE(OPT_ARG), DEFAULT(TRUE),
+ NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
+ ON_UPDATE(update_wsrep_auto_increment_control));
static Sys_var_mybool Sys_wsrep_drupal_282555_workaround(
"wsrep_drupal_282555_workaround", "Enable a workaround to handle the "