mariadb/sql/wsrep_dummy.cc
Julius Goryavsky 50b3632fa4 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
2019-02-26 08:09:04 +02:00

152 lines
3.3 KiB
C++

/* Copyright (C) 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
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; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */
#include "mariadb.h"
#include <sql_class.h>
#include <mysql/service_wsrep.h>
my_bool wsrep_thd_is_BF(THD *, my_bool)
{ return 0; }
int wsrep_trx_order_before(THD *, THD *)
{ return 0; }
enum wsrep_conflict_state wsrep_thd_conflict_state(THD *, my_bool)
{ return NO_CONFLICT; }
int wsrep_is_wsrep_xid(const XID*)
{ return 0; }
long long wsrep_xid_seqno(const XID* x)
{ return -1; }
const unsigned char* wsrep_xid_uuid(const XID*)
{
static const unsigned char uuid[16] = {0};
return uuid;
}
bool wsrep_prepare_key(const uchar*, size_t, const uchar*, size_t, struct wsrep_buf*, size_t*)
{ return 0; }
struct wsrep *get_wsrep()
{ return 0; }
my_bool get_wsrep_certify_nonPK()
{ return 0; }
my_bool get_wsrep_debug()
{ return 0; }
my_bool get_wsrep_drupal_282555_workaround()
{ return 0; }
my_bool get_wsrep_load_data_splitting()
{ return 0; }
my_bool get_wsrep_recovery()
{ return 0; }
my_bool get_wsrep_log_conflicts()
{ return 0; }
long get_wsrep_protocol_version()
{ return 0; }
my_bool wsrep_aborting_thd_contains(THD *)
{ return 0; }
void wsrep_aborting_thd_enqueue(THD *)
{ }
bool wsrep_consistency_check(THD *)
{ return 0; }
void wsrep_lock_rollback()
{ }
int wsrep_on(THD *thd)
{ return 0; }
void wsrep_post_commit(THD*, bool)
{ }
enum wsrep_trx_status wsrep_run_wsrep_commit(THD *, bool)
{ return WSREP_TRX_ERROR; }
void wsrep_thd_LOCK(THD *)
{ }
void wsrep_thd_UNLOCK(THD *)
{ }
void wsrep_thd_awake(THD *, my_bool)
{ }
const char *wsrep_thd_conflict_state_str(THD *)
{ return 0; }
enum wsrep_exec_mode wsrep_thd_exec_mode(THD *)
{ return LOCAL_STATE; }
const char *wsrep_thd_exec_mode_str(THD *)
{ return NULL; }
enum wsrep_conflict_state wsrep_thd_get_conflict_state(THD *)
{ return NO_CONFLICT; }
my_bool wsrep_thd_is_wsrep(THD *)
{ return 0; }
char *wsrep_thd_query(THD *)
{ return 0; }
enum wsrep_query_state wsrep_thd_query_state(THD *)
{ return QUERY_IDLE; }
const char *wsrep_thd_query_state_str(THD *)
{ return 0; }
int wsrep_thd_retry_counter(THD *)
{ return 0; }
void wsrep_thd_set_conflict_state(THD *, enum wsrep_conflict_state)
{ }
bool wsrep_thd_ignore_table(THD *)
{ return 0; }
longlong wsrep_thd_trx_seqno(THD *)
{ return -1; }
struct wsrep_ws_handle* wsrep_thd_ws_handle(THD *)
{ return 0; }
void wsrep_thd_auto_increment_variables(THD *thd,
unsigned long long *offset,
unsigned long long *increment)
{
*offset= thd->variables.auto_increment_offset;
*increment= thd->variables.auto_increment_increment;
}
int wsrep_trx_is_aborting(THD *)
{ return 0; }
void wsrep_unlock_rollback()
{ }
void wsrep_set_data_home_dir(const char *)
{ }