summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmake/install_macros.cmake3
-rw-r--r--scripts/wsrep_sst_xtrabackup-v2.sh8
-rw-r--r--scripts/wsrep_sst_xtrabackup.sh4
-rw-r--r--sql/handler.cc23
-rw-r--r--sql/mdl.cc11
-rw-r--r--sql/mysqld.cc103
-rw-r--r--sql/sql_class.cc16
-rw-r--r--sql/wsrep_binlog.cc2
-rw-r--r--sql/wsrep_mysqld.h1
-rw-r--r--sql/wsrep_sst.cc125
-rw-r--r--sql/wsrep_thd.cc2
-rw-r--r--sql/wsrep_thd.h8
-rw-r--r--storage/innobase/handler/ha_innodb.cc42
-rw-r--r--storage/innobase/include/ha_prototypes.h2
-rw-r--r--storage/innobase/include/lock0lock.h1
-rw-r--r--storage/innobase/lock/lock0lock.cc140
-rw-r--r--storage/innobase/lock/lock0wait.cc2
-rw-r--r--storage/innobase/row/row0ins.cc27
-rw-r--r--storage/innobase/row/row0upd.cc2
-rw-r--r--storage/innobase/trx/trx0sys.cc5
-rw-r--r--storage/xtradb/handler/ha_innodb.cc43
-rw-r--r--storage/xtradb/include/ha_prototypes.h28
-rw-r--r--storage/xtradb/include/lock0lock.h1
-rw-r--r--storage/xtradb/lock/lock0lock.cc142
-rw-r--r--storage/xtradb/lock/lock0wait.cc2
-rw-r--r--storage/xtradb/row/row0ins.cc28
-rw-r--r--storage/xtradb/row/row0upd.cc257
-rw-r--r--storage/xtradb/trx/trx0sys.cc5
28 files changed, 522 insertions, 511 deletions
diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake
index ebca9f14c31..43a41811e69 100644
--- a/cmake/install_macros.cmake
+++ b/cmake/install_macros.cmake
@@ -31,6 +31,9 @@ MACRO (INSTALL_DSYM_DIRECTORIES targets)
GET_TARGET_PROPERTY(type ${target} TYPE)
# It's a dirty hack, but cmake too stupid and mysql cmake files too buggy */
STRING(REPLACE "liblibmysql.dylib" "libmysqlclient.${SHARED_LIB_MAJOR_VERSION}.dylib" location ${location})
+ IF(DEBUG_EXTNAME)
+ STRING(REGEX REPLACE "/mysqld$" "/mysqld-debug" location ${location})
+ ENDIF()
IF(type MATCHES "EXECUTABLE" OR type MATCHES "MODULE" OR type MATCHES "SHARED_LIBRARY")
INSTALL(DIRECTORY "${location}.dSYM" DESTINATION ${ARG_DESTINATION} COMPONENT Debuginfo)
ENDIF()
diff --git a/scripts/wsrep_sst_xtrabackup-v2.sh b/scripts/wsrep_sst_xtrabackup-v2.sh
index 59017fff8df..c296c903007 100644
--- a/scripts/wsrep_sst_xtrabackup-v2.sh
+++ b/scripts/wsrep_sst_xtrabackup-v2.sh
@@ -294,7 +294,7 @@ read_cnf()
ekeyfile=$(parse_cnf sst encrypt-key-file "")
fi
rlimit=$(parse_cnf sst rlimit "")
- uextra=$(parse_cnf sst use_extra 0)
+ uextra=$(parse_cnf sst use-extra 0)
speciald=$(parse_cnf sst sst-special-dirs 1)
iopts=$(parse_cnf sst inno-backup-opts "")
iapts=$(parse_cnf sst inno-apply-opts "")
@@ -648,10 +648,6 @@ then
[[ -n $SST_PROGRESS_FILE ]] && touch $SST_PROGRESS_FILE
if [[ $speciald -eq 1 ]];then
- wsrep_log_info "WARNING: sst-special-dirs feature requires PXC 2.1.6 or latter."
- fi
-
- if [[ $speciald -eq 1 ]];then
ib_home_dir=$(parse_cnf mysqld innodb-data-home-dir "")
ib_log_dir=$(parse_cnf mysqld innodb-log-group-home-dir "")
if [[ -z $ib_home_dir && -z $ib_log_dir ]];then
@@ -827,7 +823,7 @@ then
if [[ $incremental -eq 1 ]];then
# Added --ibbackup=xtrabackup_55 because it fails otherwise citing connection issues.
- INNOAPPLY="${INNOBACKUPEX_BIN} --defaults-file=${WSREP_SST_OPT_CONF} \
+ INNOAPPLY="${INNOBACKUPEX_BIN} $disver --defaults-file=${WSREP_SST_OPT_CONF} \
--ibbackup=xtrabackup_55 --apply-log $rebuildcmd --redo-only $BDATA --incremental-dir=${DATA} &>>${BDATA}/innobackup.prepare.log"
fi
diff --git a/scripts/wsrep_sst_xtrabackup.sh b/scripts/wsrep_sst_xtrabackup.sh
index 3948b15c53b..33f2f07946e 100644
--- a/scripts/wsrep_sst_xtrabackup.sh
+++ b/scripts/wsrep_sst_xtrabackup.sh
@@ -38,6 +38,8 @@
# Make sure to read that before proceeding!
+
+
. $(dirname $0)/wsrep_sst_common
ealgo=""
@@ -609,8 +611,6 @@ then
if [[ $ecode -ne 0 ]];then
wsrep_log_error "Error while getting data from donor node: " \
"exit codes: ${RC[@]}"
- wsrep_log_error "Data directory ${DATA} needs to be empty for SST:" \
- "Manual intervention required in that case"
exit 32
fi
done
diff --git a/sql/handler.cc b/sql/handler.cc
index 93c0e6f1a04..524f3931f76 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1144,10 +1144,27 @@ int ha_prepare(THD *thd)
{
if ((err= ht->prepare(ht, thd, all)))
{
+#ifdef WITH_WSREP
+ if (WSREP(thd) && ht->db_type== DB_TYPE_WSREP)
+ {
+ error= 1;
+ /* avoid sending error, if we need to replay */
+ if (thd->wsrep_conflict_state!= MUST_REPLAY)
+ {
+ my_error(ER_LOCK_DEADLOCK, MYF(0), err);
+ }
+ }
+ else
+ {
+ /* not wsrep hton, bail to native mysql behavior */
+#endif
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
ha_rollback_trans(thd, all);
error=1;
break;
+#ifdef WITH_WSREP
+ }
+#endif
}
}
else
@@ -1419,7 +1436,7 @@ int ha_commit_trans(THD *thd, bool all)
my_error(ER_LOCK_DEADLOCK, MYF(0), err);
}
}
- lse
+ else
/* not wsrep hton, bail to native mysql behavior */
#endif /* WITH_WSREP */
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
@@ -5666,7 +5683,9 @@ static bool check_table_binlog_row_based(THD *thd, TABLE *table)
table->s->cached_row_logging_check &&
(thd->variables.option_bits & OPTION_BIN_LOG) &&
#ifdef WITH_WSREP
- ((WSREP(thd) && wsrep_emulate_bin_log) || mysql_bin_log.is_open()));
+ /* applier and replayer should not binlog */
+ ((WSREP_EMULATE_BINLOG(thd) && (thd->wsrep_exec_mode != REPL_RECV)) ||
+ mysql_bin_log.is_open()));
#else
mysql_bin_log.is_open());
#endif
diff --git a/sql/mdl.cc b/sql/mdl.cc
index 399863d4d73..4a3336d0031 100644
--- a/sql/mdl.cc
+++ b/sql/mdl.cc
@@ -22,6 +22,8 @@
#include <mysql/plugin.h>
#include <mysql/service_thd_wait.h>
#include <mysql/psi/mysql_stage.h>
+#include <my_murmur3.h>
+
#ifdef WITH_WSREP
#include "wsrep_mysqld.h"
#include "wsrep_thd.h"
@@ -34,7 +36,6 @@ extern bool
wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
MDL_ticket *ticket);
#endif /* WITH_WSREP */
-
#ifdef HAVE_PSI_INTERFACE
static PSI_mutex_key key_MDL_map_mutex;
static PSI_mutex_key key_MDL_wait_LOCK_wait_status;
@@ -1482,7 +1483,7 @@ void MDL_lock::Ticket_list::add_ticket(MDL_ticket *ticket)
DBUG_ASSERT(ticket->get_lock());
#ifdef WITH_WSREP
if ((this == &(ticket->get_lock()->m_waiting)) &&
- wsrep_thd_is_BF((void *)(ticket->get_ctx()->get_thd()), false))
+ wsrep_thd_is_BF((void *)(ticket->get_ctx()->wsrep_get_thd()), false))
{
Ticket_iterator itw(ticket->get_lock()->m_waiting);
Ticket_iterator itg(ticket->get_lock()->m_granted);
@@ -1493,7 +1494,7 @@ void MDL_lock::Ticket_list::add_ticket(MDL_ticket *ticket)
while ((waiting= itw++) && !added)
{
- if (!wsrep_thd_is_BF((void *)(waiting->get_ctx()->get_thd()), true))
+ if (!wsrep_thd_is_BF((void *)(waiting->get_ctx()->wsrep_get_thd()), true))
{
WSREP_DEBUG("MDL add_ticket inserted before: %lu %s",
wsrep_thd_thread_id(waiting->get_ctx()->wsrep_get_thd()),
@@ -1894,7 +1895,7 @@ MDL_lock::can_grant_lock(enum_mdl_type type_arg,
ticket->is_incompatible_when_granted(type_arg))
#ifdef WITH_WSREP
{
- if (wsrep_thd_is_BF((void *)(requestor_ctx->get_thd()), false) &&
+ if (wsrep_thd_is_BF((void *)(requestor_ctx->wsrep_get_thd()),false) &&
key.mdl_namespace() == MDL_key::GLOBAL)
{
WSREP_DEBUG("global lock granted for BF: %lu %s",
@@ -1935,7 +1936,7 @@ MDL_lock::can_grant_lock(enum_mdl_type type_arg,
#ifdef WITH_WSREP
else
{
- if (wsrep_thd_is_BF((void *)(requestor_ctx->get_thd()), false) &&
+ if (wsrep_thd_is_BF((void *)(requestor_ctx->wsrep_get_thd()), false) &&
key.mdl_namespace() == MDL_key::GLOBAL)
{
WSREP_DEBUG("global lock granted for BF (waiting queue): %lu %s",
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index b2f0595fe94..f56bb01e0a4 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -76,7 +76,6 @@
#include "wsrep_var.h"
#include "wsrep_thd.h"
#include "wsrep_sst.h"
-ulong wsrep_running_threads = 0; // # of currently running wsrep threads
#endif
#include "sql_callback.h"
#include "threadpool.h"
@@ -4876,42 +4875,8 @@ will be ignored as the --log-bin option is not defined.");
}
#endif
-#ifdef WITH_WSREP /* WSREP BEFORE SE */
- if (!wsrep_recovery)
- {
- if (opt_bootstrap) // bootsrap option given - disable wsrep functionality
- {
- wsrep_provider_init(WSREP_NONE);
- if (wsrep_init()) unireg_abort(1);
- }
- else // full wsrep initialization
- {
- // add basedir/bin to PATH to resolve wsrep script names
- char* const tmp_path((char*)alloca(strlen(mysql_home) +
- strlen("/bin") + 1));
- if (tmp_path)
- {
- strcpy(tmp_path, mysql_home);
- strcat(tmp_path, "/bin");
- wsrep_prepend_PATH(tmp_path);
- }
- else
- {
- WSREP_ERROR("Could not append %s/bin to PATH", mysql_home);
- }
DBUG_ASSERT(!opt_bin_log || opt_bin_logname);
- if (wsrep_before_SE())
- {
-#ifndef EMBEDDED_LIBRARY
- set_ports(); // this is also called in network_init() later but we need
- // to know mysqld_port now - lp:1071882
-#endif /* !EMBEDDED_LIBRARY */
- wsrep_init_startup(true);
- }
- }
- }
-#endif /* WITH_WSREP */
if (opt_bin_log)
{
/* Reports an error and aborts, if the --log-bin's path
@@ -4959,10 +4924,67 @@ a file name for --log-bin-index option", opt_binlog_index_name);
{
opt_bin_logname= my_once_strdup(buf, MYF(MY_WME));
}
+#ifdef WITH_WSREP /* WSREP BEFORE SE */
+ /*
+ Wsrep initialization must happen at this point, because:
+ - opt_bin_logname must be known when starting replication
+ since SST may need it
+ - SST may modify binlog index file, so it must be opened
+ after SST has happened
+ */
+ }
+ if (!wsrep_recovery)
+ {
+ if (opt_bootstrap) // bootsrap option given - disable wsrep functionality
+ {
+ wsrep_provider_init(WSREP_NONE);
+ if (wsrep_init()) unireg_abort(1);
+ }
+ else // full wsrep initialization
+ {
+ // add basedir/bin to PATH to resolve wsrep script names
+ char* const tmp_path((char*)alloca(strlen(mysql_home) +
+ strlen("/bin") + 1));
+ if (tmp_path)
+ {
+ strcpy(tmp_path, mysql_home);
+ strcat(tmp_path, "/bin");
+ wsrep_prepend_PATH(tmp_path);
+ }
+ else
+ {
+ WSREP_ERROR("Could not append %s/bin to PATH", mysql_home);
+ }
+
+ if (wsrep_before_SE())
+ {
+ set_ports(); // this is also called in network_init() later but we need
+ // to know mysqld_port now - lp:1071882
+ wsrep_init_startup(true);
+ }
+ }
+ }
+ if (opt_bin_log)
+ {
+ /*
+ Variable ln is not defined at this scope. We use opt_bin_logname instead.
+ It should be the same as ln since
+ - mysql_bin_log.generate_name() returns first argument if new log name
+ is not generated
+ - if new log name is generated, return value is assigned to ln and copied
+ to opt_bin_logname above
+ */
+ if (mysql_bin_log.open_index_file(opt_binlog_index_name, opt_bin_logname,
+ TRUE))
+ {
+ unireg_abort(1);
+ }
+#else
if (mysql_bin_log.open_index_file(opt_binlog_index_name, ln, TRUE))
{
unireg_abort(1);
}
+#endif /* WITH_WSREP */
}
/* call ha_init_key_cache() on all key caches to init them */
@@ -5304,21 +5326,10 @@ pthread_handler_t start_wsrep_THD(void *arg)
++connection_count;
mysql_mutex_unlock(&LOCK_connection_count);
- mysql_mutex_lock(&LOCK_thread_count);
- wsrep_running_threads++;
- mysql_cond_broadcast(&COND_thread_count);
- mysql_mutex_unlock(&LOCK_thread_count);
-
processor(thd);
close_connection(thd, 0);
- mysql_mutex_lock(&LOCK_thread_count);
- wsrep_running_threads--;
- WSREP_DEBUG("wsrep running threads now: %lu", wsrep_running_threads);
- mysql_cond_broadcast(&COND_thread_count);
- mysql_mutex_unlock(&LOCK_thread_count);
-
// Note: We can't call THD destructor without crashing
// if plugins have not been initialized. However, in most of the
// cases this means that pre SE initialization SST failed and
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index b1b8a017992..fd49cafb25c 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -958,6 +958,10 @@ extern "C" void wsrep_thd_awake(THD *thd, my_bool signal)
mysql_mutex_unlock(&LOCK_wsrep_replaying);
}
}
+extern "C" int wsrep_thd_retry_counter(THD *thd)
+{
+ return(thd->wsrep_retry_counter);
+}
extern int
wsrep_trx_order_before(void *thd1, void *thd2)
@@ -2127,7 +2131,19 @@ bool THD::notify_shared_lock(MDL_context_owner *ctx_in_use,
(e.g. see partitioning code).
*/
if (!thd_table->needs_reopen())
+#ifdef WITH_WSREP
+ {
+ signalled|= mysql_lock_abort_for_thread(this, thd_table);
+ if (this && WSREP(this) && wsrep_thd_is_BF((void *)this, FALSE))
+ {
+ WSREP_DEBUG("remove_table_from_cache: %llu",
+ (unsigned long long) this->real_id);
+ wsrep_abort_thd((void *)this, (void *)in_use, FALSE);
+ }
+ }
+#else
signalled|= mysql_lock_abort_for_thread(this, thd_table);
+#endif
}
mysql_mutex_unlock(&in_use->LOCK_thd_data);
}
diff --git a/sql/wsrep_binlog.cc b/sql/wsrep_binlog.cc
index 8458a299130..62c62cb56f0 100644
--- a/sql/wsrep_binlog.cc
+++ b/sql/wsrep_binlog.cc
@@ -81,7 +81,7 @@ int wsrep_write_cache_buf(IO_CACHE *cache, uchar **buf, size_t *buf_len)
error:
if (reinit_io_cache(cache, WRITE_CACHE, saved_pos, 0, 0))
{
- WSREP_ERROR("failed to initialize io-cache");
+ WSREP_WARN("failed to initialize io-cache");
}
cleanup:
my_free(*buf);
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index c8a7e0088e2..30264bf24c1 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -160,6 +160,7 @@ extern "C" char * wsrep_thd_query(THD *thd);
extern "C" query_id_t wsrep_thd_wsrep_last_query_id(THD *thd);
extern "C" void wsrep_thd_set_wsrep_last_query_id(THD *thd, query_id_t id);
extern "C" void wsrep_thd_awake(THD *thd, my_bool signal);
+extern "C" int wsrep_thd_retry_counter(THD *thd);
extern void wsrep_close_client_connections(my_bool wait_to_end);
diff --git a/sql/wsrep_sst.cc b/sql/wsrep_sst.cc
index 23bdf12abe9..ac410438cde 100644
--- a/sql/wsrep_sst.cc
+++ b/sql/wsrep_sst.cc
@@ -51,9 +51,11 @@ extern const char wsrep_defaults_file[];
#define WSREP_SST_OPT_GTID "--gtid"
#define WSREP_SST_OPT_BYPASS "--bypass"
-#define WSREP_SST_MYSQLDUMP "mysqldump"
-#define WSREP_SST_RSYNC "rsync"
-#define WSREP_SST_SKIP "skip"
+#define WSREP_SST_MYSQLDUMP "mysqldump"
+#define WSREP_SST_RSYNC "rsync"
+#define WSREP_SST_SKIP "skip"
+#define WSREP_SST_XTRABACKUP "xtrabackup"
+#define WSREP_SST_XTRABACKUP_V2 "xtrabackup-v2"
#define WSREP_SST_DEFAULT WSREP_SST_RSYNC
#define WSREP_SST_ADDRESS_AUTO "AUTO"
#define WSREP_SST_AUTH_MASK "********"
@@ -321,6 +323,33 @@ static char* my_fgets (char* buf, size_t buf_len, FILE* stream)
return ret;
}
+/*
+ Generate opt_binlog_opt_val for sst_donate_other(), sst_prepare_other().
+
+ Returns zero on success, negative error code otherwise.
+
+ String containing binlog name is stored in param ret if binlog is enabled
+ and GTID mode is on, otherwise empty string. Returned string should be
+ freed with my_free().
+ */
+static int generate_binlog_opt_val(char** ret)
+{
+ DBUG_ASSERT(ret);
+ *ret= NULL;
+ if (opt_bin_log && gtid_mode > 0)
+ {
+ assert(opt_bin_logname);
+ *ret= strcmp(opt_bin_logname, "0") ?
+ my_strdup(opt_bin_logname, MYF(0)) : my_strdup("", MYF(0));
+ }
+ else
+ {
+ *ret= my_strdup("", MYF(0));
+ }
+ if (!*ret) return -ENOMEM;
+ return 0;
+}
+
static void* sst_joiner_thread (void* a)
{
sst_thread_arg* arg= (sst_thread_arg*) a;
@@ -415,21 +444,32 @@ static ssize_t sst_prepare_other (const char* method,
ssize_t cmd_len= 1024;
char cmd_str[cmd_len];
const char* sst_dir= mysql_real_data_home;
- const char* binlog_opt= (opt_bin_logname ? (strcmp(opt_bin_logname, "0") ? WSREP_SST_OPT_BINLOG : "") : "");
- const char* binlog_opt_val= (opt_bin_logname ? (strcmp(opt_bin_logname, "0") ? opt_bin_logname : "") : "");
-
- int ret= snprintf (cmd_str, cmd_len,
- "wsrep_sst_%s "
- WSREP_SST_OPT_ROLE" 'joiner' "
- WSREP_SST_OPT_ADDR" '%s' "
- WSREP_SST_OPT_AUTH" '%s' "
- WSREP_SST_OPT_DATA" '%s' "
- WSREP_SST_OPT_CONF" '%s' "
- WSREP_SST_OPT_PARENT" '%d'"
- " %s '%s' ",
- method, addr_in, (sst_auth_real) ? sst_auth_real : "",
- sst_dir, wsrep_defaults_file, (int)getpid(),
- binlog_opt, binlog_opt_val);
+ const char* binlog_opt= "";
+ char* binlog_opt_val= NULL;
+
+ int ret;
+ if ((ret= generate_binlog_opt_val(&binlog_opt_val)))
+ {
+ WSREP_ERROR("sst_prepare_other(): generate_binlog_opt_val() failed: %d",
+ ret);
+ return ret;
+ }
+ if (strlen(binlog_opt_val)) binlog_opt= WSREP_SST_OPT_BINLOG;
+
+
+ ret= snprintf (cmd_str, cmd_len,
+ "wsrep_sst_%s "
+ WSREP_SST_OPT_ROLE" 'joiner' "
+ WSREP_SST_OPT_ADDR" '%s' "
+ WSREP_SST_OPT_AUTH" '%s' "
+ WSREP_SST_OPT_DATA" '%s' "
+ WSREP_SST_OPT_CONF" '%s' "
+ WSREP_SST_OPT_PARENT" '%d'"
+ " %s '%s' ",
+ method, addr_in, (sst_auth_real) ? sst_auth_real : "",
+ sst_dir, wsrep_defaults_file, (int)getpid(),
+ binlog_opt, binlog_opt_val);
+ my_free(binlog_opt_val);
if (ret < 0 || ret >= cmd_len)
{
@@ -965,6 +1005,8 @@ wait_signal:
return NULL;
}
+
+
static int sst_donate_other (const char* method,
const char* addr,
const char* uuid,
@@ -973,25 +1015,34 @@ static int sst_donate_other (const char* method,
{
ssize_t cmd_len = 4096;
char cmd_str[cmd_len];
- const char* binlog_opt= (opt_bin_logname ? (strcmp(opt_bin_logname, "0") ? WSREP_SST_OPT_BINLOG : "") : "");
- const char* binlog_opt_val= (opt_bin_logname ? (strcmp(opt_bin_logname, "0") ? opt_bin_logname : "") : "");
-
- int ret= snprintf (cmd_str, cmd_len,
- "wsrep_sst_%s "
- WSREP_SST_OPT_ROLE" 'donor' "
- WSREP_SST_OPT_ADDR" '%s' "
- WSREP_SST_OPT_AUTH" '%s' "
- WSREP_SST_OPT_SOCKET" '%s' "
- WSREP_SST_OPT_DATA" '%s' "
- WSREP_SST_OPT_CONF" '%s' "
- " %s '%s' "
- WSREP_SST_OPT_GTID" '%s:%lld'"
- "%s",
- method, addr, sst_auth_real, mysqld_unix_port,
- mysql_real_data_home, wsrep_defaults_file,
- binlog_opt, binlog_opt_val,
- uuid, (long long) seqno,
- bypass ? " "WSREP_SST_OPT_BYPASS : "");
+ const char* binlog_opt= "";
+ char* binlog_opt_val= NULL;
+
+ int ret;
+ if ((ret= generate_binlog_opt_val(&binlog_opt_val)))
+ {
+ WSREP_ERROR("sst_donate_other(): generate_binlog_opt_val() failed: %d",ret);
+ return ret;
+ }
+ if (strlen(binlog_opt_val)) binlog_opt= WSREP_SST_OPT_BINLOG;
+
+ ret= snprintf (cmd_str, cmd_len,
+ "wsrep_sst_%s "
+ WSREP_SST_OPT_ROLE" 'donor' "
+ WSREP_SST_OPT_ADDR" '%s' "
+ WSREP_SST_OPT_AUTH" '%s' "
+ WSREP_SST_OPT_SOCKET" '%s' "
+ WSREP_SST_OPT_DATA" '%s' "
+ WSREP_SST_OPT_CONF" '%s' "
+ " %s '%s' "
+ WSREP_SST_OPT_GTID" '%s:%lld'"
+ "%s",
+ method, addr, sst_auth_real, mysqld_unix_port,
+ mysql_real_data_home, wsrep_defaults_file,
+ binlog_opt, binlog_opt_val,
+ uuid, (long long) seqno,
+ bypass ? " "WSREP_SST_OPT_BYPASS : "");
+ my_free(binlog_opt_val);
if (ret < 0 || ret >= cmd_len)
{
diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc
index e68120ee779..78ba559380b 100644
--- a/sql/wsrep_thd.cc
+++ b/sql/wsrep_thd.cc
@@ -472,7 +472,6 @@ void wsrep_create_rollbacker()
}
}
-extern "C"
my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync)
{
my_bool status = FALSE;
@@ -520,7 +519,6 @@ my_bool wsrep_thd_is_local(void *thd_ptr, my_bool sync)
return status;
}
-extern "C"
int wsrep_abort_thd(void *bf_thd_ptr, void *victim_thd_ptr, my_bool signal)
{
THD *victim_thd = (THD *) victim_thd_ptr;
diff --git a/sql/wsrep_thd.h b/sql/wsrep_thd.h
index 74e3bff120c..f719deae2b7 100644
--- a/sql/wsrep_thd.h
+++ b/sql/wsrep_thd.h
@@ -24,11 +24,13 @@ void wsrep_replay_transaction(THD *thd);
void wsrep_create_appliers(long threads);
void wsrep_create_rollbacker();
-extern "C" my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync);
+int wsrep_abort_thd(void *bf_thd_ptr, void *victim_thd_ptr,
+ my_bool signal);
+
+extern my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync);
+//extern "C" my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync);
extern "C" my_bool wsrep_thd_is_BF_or_commit(void *thd_ptr, my_bool sync);
extern "C" my_bool wsrep_thd_is_local(void *thd_ptr, my_bool sync);
-extern "C" int wsrep_abort_thd(void *bf_thd_ptr, void *victim_thd_ptr,
- my_bool signal);
extern "C" int wsrep_thd_in_locking_session(void *thd_ptr);
#endif /* WSREP_THD_H */
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index abbdb94397c..241637bca8a 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -1184,8 +1184,8 @@ innobase_srv_conc_enter_innodb(
trx_t* trx) /*!< in: transaction handle */
{
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(trx->mysql_thd)) return;
+ if (wsrep_on(trx->mysql_thd) &&
+ wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
#endif /* WITH_WSREP */
if (srv_thread_concurrency) {
if (trx->n_tickets_to_enter_innodb > 0) {
@@ -1222,8 +1222,8 @@ innobase_srv_conc_exit_innodb(
ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
#endif /* UNIV_SYNC_DEBUG */
#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(trx->mysql_thd)) return;
+ if (wsrep_on(trx->mysql_thd) &&
+ wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
#endif /* WITH_WSREP */
/* This is to avoid making an unnecessary function call. */
@@ -3466,11 +3466,6 @@ innobase_commit_low(
/*================*/
trx_t* trx) /*!< in: transaction handle */
{
- if (trx_is_started(trx)) {
-
- trx_commit_for_mysql(trx);
- }
-
#ifdef WITH_WSREP
THD* thd = (THD*)trx->mysql_thd;
const char* tmp = 0;
@@ -3488,7 +3483,10 @@ innobase_commit_low(
#endif /* WSREP_PROC_INFO */
}
#endif /* WITH_WSREP */
+ if (trx_is_started(trx)) {
+ trx_commit_for_mysql(trx);
+ }
#ifdef WITH_WSREP
if (wsrep_on((void*)thd)) { thd_proc_info(thd, tmp); }
#endif /* WITH_WSREP */
@@ -5544,7 +5542,7 @@ wsrep_innobase_mysql_sort(
tmp_length = charset->coll->strnxfrm(charset, str, str_length,
str_length, tmp_str, tmp_length, 0);
/**/
- DBUG_ASSERT(tmp_length == str_length);
+ DBUG_ASSERT(tmp_length <= str_length);
break;
}
@@ -7434,9 +7432,10 @@ no_commit:
#ifdef WITH_WSREP
/* workaround for LP bug #355000, retrying the insert */
case SQLCOM_INSERT:
- if (wsrep_on(current_thd) &&
- auto_inc_inserted &&
- wsrep_drupal_282555_workaround &&
+ if (wsrep_on(current_thd) &&
+ auto_inc_inserted &&
+ wsrep_drupal_282555_workaround &&
+ wsrep_thd_retry_counter(current_thd) == 0 &&
!thd_test_options(current_thd,
OPTION_NOT_AUTOCOMMIT |
OPTION_BEGIN)) {
@@ -9545,6 +9544,13 @@ ha_innobase::wsrep_append_keys(
} else {
ut_a(table->s->keys <= 256);
uint i;
+ bool hasPK= false;
+
+ for (i=0; i<table->s->keys && !hasPK; ++i) {
+ KEY* key_info = table->key_info + i;
+ if (key_info->flags & HA_NOSAME) hasPK = true;
+ }
+
for (i=0; i<table->s->keys; ++i) {
uint len;
char keyval0[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'};
@@ -9565,14 +9571,11 @@ ha_innobase::wsrep_append_keys(
table->s->table_name.str,
key_info->name);
}
- if (key_info->flags & HA_NOSAME ||
+ if (!hasPK || key_info->flags & HA_NOSAME ||
((tab &&
dict_table_get_referenced_constraint(tab, idx)) ||
(!tab && referenced_by_foreign_key()))) {
- if (key_info->flags & HA_NOSAME || shared)
- key_appended = true;
-
len = wsrep_store_key_val_for_row(
table, i, key0, key_info->key_length,
record0, &is_null);
@@ -9581,6 +9584,10 @@ ha_innobase::wsrep_append_keys(
thd, trx, table_share, table,
keyval0, len+1, shared);
if (rcode) DBUG_RETURN(rcode);
+
+ if (key_info->flags & HA_NOSAME || shared)
+ key_appended = true;
+
}
else
{
@@ -16699,6 +16706,7 @@ wsrep_abort_slave_trx(wsrep_seqno_t bf_seqno, wsrep_seqno_t victim_seqno)
}
/*******************************************************************//**
This function is used to kill one transaction in BF. */
+
int
wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
const trx_t * const bf_trx,
diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h
index 08ac2a74405..dc78964a873 100644
--- a/storage/innobase/include/ha_prototypes.h
+++ b/storage/innobase/include/ha_prototypes.h
@@ -291,7 +291,7 @@ UNIV_INTERN
int
wsrep_innobase_kill_one_trx(void *thd_ptr,
const trx_t *bf_trx, trx_t *victim_trx, ibool signal);
-extern "C" int wsrep_thd_is_brute_force(void *thd_ptr);
+my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync);
int wsrep_trx_order_before(void *thd1, void *thd2);
void wsrep_innobase_mysql_sort(int mysql_type, uint charset_number,
unsigned char* str, unsigned int str_length);
diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
index 24e612e63f5..2f89c02bb7a 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -873,7 +873,6 @@ lock_trx_has_sys_table_locks(
record */
#define LOCK_CONV_BY_OTHER 4096 /*!< this bit is set when the lock is created
by other transaction */
-#define WSREP_BF 8192
#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_CONV_BY_OTHER)&LOCK_TYPE_MASK
# error
#endif
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index f6779ff5acd..0e4c1e7c82f 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -978,47 +978,6 @@ lock_rec_has_to_wait(
&& !lock_mode_compatible(static_cast<enum lock_mode>(
LOCK_MODE_MASK & type_mode),
lock_get_mode(lock2))) {
-#ifdef WITH_WSREP
- /* if BF thread is locking and has conflict with another BF
- thread, we need to look at trx ordering and lock types */
- if (for_locking &&
- wsrep_thd_is_brute_force(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(lock2->trx->mysql_thd)) {
-
- if (wsrep_debug) {
- fprintf(stderr, "\n BF-BF lock conflict \n");
- lock_rec_print(stderr, lock2);
- }
-
- if (wsrep_trx_order_before(trx->mysql_thd,
- lock2->trx->mysql_thd) &&
- (type_mode & LOCK_MODE_MASK) == LOCK_X &&
- (lock2->type_mode & LOCK_MODE_MASK) == LOCK_X)
- {
- /* exclusive lock conflicts are not accepted */
- fprintf(stderr, "BF-BF X lock conflict\n");
- lock_rec_print(stderr, lock2);
-
- abort();
- } else {
- if (wsrep_debug) {
- fprintf(stderr,
- "BF conflict, modes: %lu %lu\n",
- type_mode,
- lock2->type_mode);
-#ifdef OUT
- fprintf(stderr,
- "seqnos %llu %llu\n",
- (long long)wsrep_thd_trx_seqno(
- trx->mysql_thd),
- (long long)wsrep_thd_trx_seqno(
- lock2->trx->mysql_thd));
-#endif
- }
- return FALSE;
- }
- }
-#endif /* WITH_WSREP */
/* We have somewhat complex rules when gap type record locks
cause waits */
@@ -1068,6 +1027,44 @@ lock_rec_has_to_wait(
return(FALSE);
}
+#ifdef WITH_WSREP
+ /* if BF thread is locking and has conflict with another BF
+ thread, we need to look at trx ordering and lock types */
+ if (for_locking &&
+ wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
+ wsrep_thd_is_BF(lock2->trx->mysql_thd, TRUE)) {
+
+ if (wsrep_debug) {
+ fprintf(stderr, "\n BF-BF lock conflict \n");
+ lock_rec_print(stderr, lock2);
+ }
+
+ if (wsrep_trx_order_before(trx->mysql_thd,
+ lock2->trx->mysql_thd) &&
+ (type_mode & LOCK_MODE_MASK) == LOCK_X &&
+ (lock2->type_mode & LOCK_MODE_MASK) == LOCK_X)
+ {
+ /* exclusive lock conflicts are not accepted */
+ fprintf(stderr, "BF-BF X lock conflict\n");
+ lock_rec_print(stderr, lock2);
+ abort();
+ } else {
+ /* if lock2->index->n_uniq <=
+ lock2->index->n_user_defined_cols
+ operation is on uniq index
+ */
+ if (wsrep_debug) fprintf(stderr,
+ "BF conflict, modes: %lu %lu, "
+ "idx: %s-%s n_uniq %u n_user %u\n",
+ type_mode, lock2->type_mode,
+ lock2->index->name,
+ lock2->index->table_name,
+ lock2->index->n_uniq,
+ lock2->index->n_user_defined_cols);
+ return FALSE;
+ }
+ }
+#endif /* WITH_WSREP */
return(TRUE);
}
@@ -1630,8 +1627,8 @@ void
wsrep_kill_victim(const trx_t * const trx, const lock_t *lock) {
ut_ad(lock_mutex_own());
ut_ad(trx_mutex_own(lock->trx));
- my_bool bf_this = wsrep_thd_is_brute_force(trx->mysql_thd);
- my_bool bf_other = wsrep_thd_is_brute_force(lock->trx->mysql_thd);
+ my_bool bf_this = wsrep_thd_is_BF(trx->mysql_thd, FALSE);
+ my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE);
if ((bf_this && !bf_other) ||
(bf_this && bf_other && wsrep_trx_order_before(
trx->mysql_thd, lock->trx->mysql_thd))) {
@@ -1929,11 +1926,6 @@ lock_rec_create(
lock->trx = trx;
lock->type_mode = (type_mode & ~LOCK_TYPE_MASK) | LOCK_REC;
-#ifdef WITH_WSREP
- if (wsrep_thd_is_brute_force(trx->mysql_thd)) {
- lock->type_mode |= WSREP_BF;
- }
-#endif /* WITH_WSREP */
lock->index = index;
lock->un_member.rec_lock.space = space;
@@ -1953,12 +1945,12 @@ lock_rec_create(
ut_ad(index->table->n_ref_count > 0 || !index->table->can_be_evicted);
#ifdef WITH_WSREP
- if (c_lock && wsrep_thd_is_brute_force(trx->mysql_thd)) {
+ if (c_lock && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
lock_t *hash = (lock_t *)c_lock->hash;
lock_t *prev = NULL;
while (hash &&
- wsrep_thd_is_brute_force(((lock_t *)hash)->trx->mysql_thd) &&
+ wsrep_thd_is_BF(((lock_t *)hash)->trx->mysql_thd, TRUE) &&
wsrep_trx_order_before(
((lock_t *)hash)->trx->mysql_thd,
trx->mysql_thd)) {
@@ -2361,11 +2353,6 @@ lock_rec_lock_fast(
|| (LOCK_MODE_MASK & mode) == LOCK_X);
ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
|| mode - (LOCK_MODE_MASK & mode) == 0
-#ifdef WITH_WSREP
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == 0
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_GAP
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_REC_NOT_GAP
-#endif /* WITH_WSREP */
|| mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP);
ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index));
@@ -2382,8 +2369,7 @@ lock_rec_lock_fast(
#else
lock = lock_rec_create(
mode, block, heap_no, index, trx, FALSE);
-#endif
-
+#endif /* WITH_WSREP */
}
status = LOCK_REC_SUCCESS_CREATED;
} else {
@@ -2451,11 +2437,6 @@ lock_rec_lock_slow(
|| (LOCK_MODE_MASK & mode) == LOCK_X);
ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
|| mode - (LOCK_MODE_MASK & mode) == 0
-#ifdef WITH_WSREP
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == 0
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_GAP
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_REC_NOT_GAP
-#endif /* WITH_WSREP */
|| mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP);
ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index));
@@ -2564,11 +2545,6 @@ lock_rec_lock(
|| (LOCK_MODE_MASK & mode) == LOCK_X);
ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
|| mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP
-#ifdef WITH_WSREP
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == 0
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_GAP
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_REC_NOT_GAP
-#endif /* WITH_WSREP */
|| mode - (LOCK_MODE_MASK & mode) == 0);
#ifdef WITH_WSREP
@@ -4023,18 +3999,18 @@ lock_deadlock_select_victim(
/* The joining transaction is 'smaller',
choose it as the victim and roll it back. */
#ifdef WITH_WSREP
- if (!wsrep_thd_is_brute_force(ctx->start->mysql_thd)) {
- return(ctx->start);
- }
-#else
- return(ctx->start);
-#endif
+ if (wsrep_thd_is_BF(ctx->start->mysql_thd, TRUE))
+ return(ctx->wait_lock->trx);
+ else
+#endif /* WITH_WSREP */
+ return(ctx->start);
}
+
#ifdef WITH_WSREP
- if (wsrep_thd_is_brute_force(ctx->wait_lock->trx->mysql_thd)) {
- return(ctx->start);
- }
-#endif
+ if (wsrep_thd_is_BF(ctx->wait_lock->trx->mysql_thd, TRUE))
+ return(ctx->start);
+ else
+#endif /* WITH_WSREP */
return(ctx->wait_lock->trx);
}
@@ -4184,7 +4160,7 @@ lock_deadlock_search(
ctx->too_deep = TRUE;
#ifdef WITH_WSREP
- if (wsrep_thd_is_brute_force(ctx->start->mysql_thd))
+ if (wsrep_thd_is_BF(ctx->start->mysql_thd, TRUE))
return(ctx->wait_lock->trx->id);
else
#endif /* WITH_WSREP */
@@ -4205,7 +4181,7 @@ lock_deadlock_search(
ctx->too_deep = TRUE;
#ifdef WITH_WSREP
- if (wsrep_thd_is_brute_force(ctx->start->mysql_thd))
+ if (wsrep_thd_is_BF(ctx->start->mysql_thd, TRUE))
return(lock->trx->id);
else
#endif /* WITH_WSREP */
@@ -4342,7 +4318,7 @@ lock_deadlock_check_and_resolve(
ut_a(victim_trx_id == trx->id);
#ifdef WITH_WSREP
- if (!wsrep_thd_is_brute_force(ctx.start->mysql_thd))
+ if (!wsrep_thd_is_BF(ctx.start->mysql_thd, TRUE))
{
#endif /* WITH_WSREP */
if (!srv_read_only_mode) {
@@ -4438,7 +4414,7 @@ lock_table_create(
UT_LIST_ADD_LAST(trx_locks, trx->lock.trx_locks, lock);
#ifdef WITH_WSREP
- if (c_lock && wsrep_thd_is_brute_force(trx->mysql_thd)) {
+ if (c_lock && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
UT_LIST_INSERT_AFTER(
un_member.tab_lock.locks, table->locks, c_lock, lock);
} else {
@@ -6476,7 +6452,7 @@ lock_rec_convert_impl_to_expl(
if (rec_get_deleted_flag(rec, rec_offs_comp(offsets))
#ifdef WITH_WSREP
- && !wsrep_thd_is_brute_force(impl_trx->mysql_thd)
+ && !wsrep_thd_is_BF(impl_trx->mysql_thd, FALSE)
/* BF-BF conflict is possible if advancing into
lock_rec_other_has_conflicting*/
#endif /* WITH_WSREP */
diff --git a/storage/innobase/lock/lock0wait.cc b/storage/innobase/lock/lock0wait.cc
index f957c1855cc..5a793ae7af8 100644
--- a/storage/innobase/lock/lock0wait.cc
+++ b/storage/innobase/lock/lock0wait.cc
@@ -195,7 +195,7 @@ wsrep_is_BF_lock_timeout(
trx_t* trx) /* in: trx to check for lock priority */
{
if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(trx->mysql_thd)) {
+ wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
fprintf(stderr, "WSREP: BF lock wait long\n");
srv_print_innodb_monitor = TRUE;
srv_print_innodb_lock_monitor = TRUE;
diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc
index 57687e77b2b..14226d04eaa 100644
--- a/storage/innobase/row/row0ins.cc
+++ b/storage/innobase/row/row0ins.cc
@@ -1920,9 +1920,6 @@ row_ins_scan_sec_index_for_duplicate(
mem_heap_t* offsets_heap)
/*!< in/out: memory heap that can be emptied */
{
-#ifdef WITH_WSREP
- trx_t* trx = thr_get_trx(thr);
-#endif
ulint n_unique;
int cmp;
ulint n_fields_cmp;
@@ -1980,16 +1977,8 @@ row_ins_scan_sec_index_for_duplicate(
if (flags & BTR_NO_LOCKING_FLAG) {
/* Set no locks when applying log
in online table rebuild. */
-#ifdef WITH_WSREP
- /* slave applier must not get duplicate error */
- } else if (allow_duplicates ||
- (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(trx->mysql_thd))) {
-#else
} else if (allow_duplicates) {
-#endif
-
/* If the SQL-query will update or replace
duplicate key we will take X-lock for
duplicates ( REPLACE, LOAD DATAFILE REPLACE,
@@ -2000,6 +1989,10 @@ row_ins_scan_sec_index_for_duplicate(
rec, index, offsets, thr);
} else {
+#ifdef WITH_WSREP
+ /* appliers don't need dupkey checks */
+ if (!wsrep_thd_is_BF(thr_get_trx(thr)->mysql_thd, 0))
+#endif /* WITH_WSREP */
err = row_ins_set_shared_rec_lock(
LOCK_ORDINARY, block,
rec, index, offsets, thr);
@@ -2183,13 +2176,7 @@ row_ins_duplicate_error_in_clust(
sure that in roll-forward we get the same duplicate
errors as in original execution */
-#ifdef WITH_WSREP
- if (trx->duplicates ||
- (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(trx->mysql_thd))) {
-#else
if (trx->duplicates) {
-#endif
/* If the SQL-query will update or replace
duplicate key we will take X-lock for
@@ -2234,13 +2221,7 @@ duplicate:
offsets = rec_get_offsets(rec, cursor->index, offsets,
ULINT_UNDEFINED, &heap);
-#ifdef WITH_WSREP
- if (trx->duplicates ||
- (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(trx->mysql_thd))) {
-#else
if (trx->duplicates) {
-#endif
/* If the SQL-query will update or replace
duplicate key we will take X-lock for
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index 5d236cc40e5..d3ca4ec6b8e 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -373,6 +373,8 @@ wsrep_row_upd_check_foreign_constraints(
trx = thr_get_trx(thr);
+ /* TODO: make native slave thread bail out here */
+
rec = btr_pcur_get_rec(pcur);
ut_ad(rec_offs_validate(rec, index, offsets));
diff --git a/storage/innobase/trx/trx0sys.cc b/storage/innobase/trx/trx0sys.cc
index 0b2837a09b5..2562064b51b 100644
--- a/storage/innobase/trx/trx0sys.cc
+++ b/storage/innobase/trx/trx0sys.cc
@@ -178,7 +178,12 @@ trx_sys_flush_max_trx_id(void)
mtr_t mtr;
trx_sysf_t* sys_header;
+#ifndef WITH_WSREP
+ /* wsrep_fake_trx_id violates this assert
+ * Copied from trx_sys_get_new_trx_id
+ */
ut_ad(mutex_own(&trx_sys->mutex));
+#endif /* WITH_WSREP */
if (!srv_read_only_mode) {
mtr_start(&mtr);
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index e3a3f71f559..ce3e8f250c9 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -1448,9 +1448,8 @@ innobase_srv_conc_enter_innodb(
{
#ifdef WITH_WSREP
if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(trx->mysql_thd)) return;
+ wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
#endif /* WITH_WSREP */
-
if (srv_thread_concurrency) {
if (trx->n_tickets_to_enter_innodb > 0) {
@@ -1482,14 +1481,13 @@ innobase_srv_conc_exit_innodb(
/*==========================*/
trx_t* trx) /*!< in: transaction handle */
{
-#ifdef WITH_WSREP
- if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(trx->mysql_thd)) return;
-#endif /* WITH_WSREP */
-
#ifdef UNIV_SYNC_DEBUG
ut_ad(!sync_thread_levels_nonempty_trx(trx->has_search_latch));
#endif /* UNIV_SYNC_DEBUG */
+#ifdef WITH_WSREP
+ if (wsrep_on(trx->mysql_thd) &&
+ wsrep_thd_is_BF(trx->mysql_thd, FALSE)) return;
+#endif /* WITH_WSREP */
/* This is to avoid making an unnecessary function call. */
if (trx->declared_to_be_inside_innodb
@@ -3937,12 +3935,10 @@ innobase_commit_low(
#endif /* WSREP_PROC_INFO */
}
#endif /* WITH_WSREP */
-
if (trx_is_started(trx)) {
trx_commit_for_mysql(trx);
}
-
#ifdef WITH_WSREP
if (wsrep_on((void*)thd)) { thd_proc_info(thd, tmp); }
#endif /* WITH_WSREP */
@@ -6002,7 +5998,7 @@ wsrep_innobase_mysql_sort(
tmp_length = charset->coll->strnxfrm(charset, str, str_length,
str_length, tmp_str, tmp_length, 0);
- DBUG_ASSERT(tmp_length == str_length);
+ DBUG_ASSERT(tmp_length <= str_length);
break;
}
@@ -7896,9 +7892,10 @@ no_commit:
#ifdef WITH_WSREP
/* workaround for LP bug #355000, retrying the insert */
case SQLCOM_INSERT:
- if (wsrep_on(current_thd) &&
- auto_inc_inserted &&
- wsrep_drupal_282555_workaround &&
+ if (wsrep_on(current_thd) &&
+ auto_inc_inserted &&
+ wsrep_drupal_282555_workaround &&
+ wsrep_thd_retry_counter(current_thd) == 0 &&
!thd_test_options(current_thd,
OPTION_NOT_AUTOCOMMIT |
OPTION_BEGIN)) {
@@ -7910,8 +7907,7 @@ no_commit:
error= DB_SUCCESS;
wsrep_thd_set_conflict_state(
current_thd, MUST_ABORT);
- innobase_srv_conc_exit_innodb(
- prebuilt->trx);
+ innobase_srv_conc_exit_innodb(prebuilt->trx);
/* jump straight to func exit over
* later wsrep hooks */
goto func_exit;
@@ -10059,6 +10055,13 @@ ha_innobase::wsrep_append_keys(
} else {
ut_a(table->s->keys <= 256);
uint i;
+ bool hasPK= false;
+
+ for (i=0; i<table->s->keys && !hasPK; ++i) {
+ KEY* key_info = table->key_info + i;
+ if (key_info->flags & HA_NOSAME) hasPK = true;
+ }
+
for (i=0; i<table->s->keys; ++i) {
uint len;
char keyval0[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'};
@@ -10079,14 +10082,11 @@ ha_innobase::wsrep_append_keys(
table->s->table_name.str,
key_info->name);
}
- if (key_info->flags & HA_NOSAME ||
+ if (!hasPK || key_info->flags & HA_NOSAME ||
((tab &&
dict_table_get_referenced_constraint(tab, idx)) ||
(!tab && referenced_by_foreign_key()))) {
- if (key_info->flags & HA_NOSAME || shared)
- key_appended = true;
-
len = wsrep_store_key_val_for_row(
table, i, key0, key_info->key_length,
record0, &is_null);
@@ -10095,6 +10095,10 @@ ha_innobase::wsrep_append_keys(
thd, trx, table_share, table,
keyval0, len+1, shared);
if (rcode) DBUG_RETURN(rcode);
+
+ if (key_info->flags & HA_NOSAME || shared)
+ key_appended = true;
+
}
else
{
@@ -17755,6 +17759,7 @@ wsrep_abort_slave_trx(wsrep_seqno_t bf_seqno, wsrep_seqno_t victim_seqno)
}
/*******************************************************************//**
This function is used to kill one transaction in BF. */
+
int
wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
const trx_t * const bf_trx,
diff --git a/storage/xtradb/include/ha_prototypes.h b/storage/xtradb/include/ha_prototypes.h
index d1652c1f0d8..d027deb6140 100644
--- a/storage/xtradb/include/ha_prototypes.h
+++ b/storage/xtradb/include/ha_prototypes.h
@@ -285,6 +285,19 @@ innobase_casedn_str(
/*================*/
char* a); /*!< in/out: string to put in lower case */
+#ifdef WITH_WSREP
+UNIV_INTERN
+int
+wsrep_innobase_kill_one_trx(void *thd_ptr,
+ const trx_t *bf_trx, trx_t *victim_trx, ibool signal);
+my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync);
+int wsrep_trx_order_before(void *thd1, void *thd2);
+void wsrep_innobase_mysql_sort(int mysql_type, uint charset_number,
+ unsigned char* str, unsigned int str_length);
+int
+wsrep_on(void *thd_ptr);
+extern "C" int wsrep_is_wsrep_xid(const void*);
+#endif /* WITH_WSREP */
/**********************************************************************//**
Determines the connection character set.
@return connection character set */
@@ -375,21 +388,6 @@ thd_flush_log_at_trx_commit(
/*================================*/
void* thd);
-#ifdef WITH_WSREP
-UNIV_INTERN
-int
-wsrep_innobase_kill_one_trx(void *thd_ptr,
- const trx_t *bf_trx, trx_t *victim_trx, ibool signal);
-
-extern "C" int wsrep_thd_is_brute_force(void *thd_ptr);
-int wsrep_trx_order_before(void *thd1, void *thd2);
-void wsrep_innobase_mysql_sort(int mysql_type, uint charset_number,
- unsigned char* str, unsigned int str_length);
-//UNIV_INTERN
-int
-wsrep_on(void *thd_ptr);
-extern "C" int wsrep_is_wsrep_xid(const void*);
-#endif /* WITH_WSREP */
/**********************************************************************//**
Get the current setting of the lower_case_table_names global parameter from
mysqld.cc. We do a dirty read because for one there is no synchronization
diff --git a/storage/xtradb/include/lock0lock.h b/storage/xtradb/include/lock0lock.h
index d11f3b006d4..466e728f65b 100644
--- a/storage/xtradb/include/lock0lock.h
+++ b/storage/xtradb/include/lock0lock.h
@@ -906,7 +906,6 @@ lock_trx_has_rec_x_lock(
record */
#define LOCK_CONV_BY_OTHER 4096 /*!< this bit is set when the lock is created
by other transaction */
-#define WSREP_BF 8192
#if (LOCK_WAIT|LOCK_GAP|LOCK_REC_NOT_GAP|LOCK_INSERT_INTENTION|LOCK_CONV_BY_OTHER)&LOCK_TYPE_MASK
# error
#endif
diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc
index 8773e2e1868..67985c642c6 100644
--- a/storage/xtradb/lock/lock0lock.cc
+++ b/storage/xtradb/lock/lock0lock.cc
@@ -982,48 +982,6 @@ lock_rec_has_to_wait(
LOCK_MODE_MASK & type_mode),
lock_get_mode(lock2))) {
-#ifdef WITH_WSREP
- /* if BF thread is locking and has conflict with another BF
- thread, we need to look at trx ordering and lock types */
- if (for_locking &&
- wsrep_thd_is_brute_force(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(lock2->trx->mysql_thd)) {
-
- if (wsrep_debug) {
- fprintf(stderr, "\n BF-BF lock conflict \n");
- lock_rec_print(stderr, lock2);
- }
-
- if (wsrep_trx_order_before(trx->mysql_thd,
- lock2->trx->mysql_thd) &&
- (type_mode & LOCK_MODE_MASK) == LOCK_X &&
- (lock2->type_mode & LOCK_MODE_MASK) == LOCK_X)
- {
- /* exclusive lock conflicts are not accepted */
- fprintf(stderr, "BF-BF X lock conflict\n");
- lock_rec_print(stderr, lock2);
-
- abort();
- } else {
- if (wsrep_debug) {
- fprintf(stderr,
- "BF conflict, modes: %lu %lu\n",
- type_mode,
- lock2->type_mode);
-#ifdef OUT
- fprintf(stderr,
- "seqnos %llu %llu\n",
- (long long)wsrep_thd_trx_seqno(
- trx->mysql_thd),
- (long long)wsrep_thd_trx_seqno(
- lock2->trx->mysql_thd));
-#endif
- }
- return FALSE;
- }
- }
-#endif /* WITH_WSREP */
-
/* We have somewhat complex rules when gap type record locks
cause waits */
@@ -1072,6 +1030,44 @@ lock_rec_has_to_wait(
return(FALSE);
}
+#ifdef WITH_WSREP
+ /* if BF thread is locking and has conflict with another BF
+ thread, we need to look at trx ordering and lock types */
+ if (for_locking &&
+ wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
+ wsrep_thd_is_BF(lock2->trx->mysql_thd, TRUE)) {
+
+ if (wsrep_debug) {
+ fprintf(stderr, "\n BF-BF lock conflict \n");
+ lock_rec_print(stderr, lock2);
+ }
+
+ if (wsrep_trx_order_before(trx->mysql_thd,
+ lock2->trx->mysql_thd) &&
+ (type_mode & LOCK_MODE_MASK) == LOCK_X &&
+ (lock2->type_mode & LOCK_MODE_MASK) == LOCK_X)
+ {
+ /* exclusive lock conflicts are not accepted */
+ fprintf(stderr, "BF-BF X lock conflict\n");
+ lock_rec_print(stderr, lock2);
+ abort();
+ } else {
+ /* if lock2->index->n_uniq <=
+ lock2->index->n_user_defined_cols
+ operation is on uniq index
+ */
+ if (wsrep_debug) fprintf(stderr,
+ "BF conflict, modes: %lu %lu, "
+ "idx: %s-%s n_uniq %u n_user %u\n",
+ type_mode, lock2->type_mode,
+ lock2->index->name,
+ lock2->index->table_name,
+ lock2->index->n_uniq,
+ lock2->index->n_user_defined_cols);
+ return FALSE;
+ }
+ }
+#endif /* WITH_WSREP */
return(TRUE);
}
@@ -1634,10 +1630,8 @@ static void
wsrep_kill_victim(trx_t *trx, lock_t *lock) {
ut_ad(lock_mutex_own());
ut_ad(trx_mutex_own(lock->trx));
-
- my_bool bf_this = wsrep_thd_is_brute_force(trx->mysql_thd);
- my_bool bf_other = wsrep_thd_is_brute_force(lock->trx->mysql_thd);
-
+ my_bool bf_this = wsrep_thd_is_BF(trx->mysql_thd, FALSE);
+ my_bool bf_other = wsrep_thd_is_BF(lock->trx->mysql_thd, TRUE);
if ((bf_this && !bf_other) ||
(bf_this && bf_other && wsrep_trx_order_before(
trx->mysql_thd, lock->trx->mysql_thd))) {
@@ -1935,13 +1929,8 @@ lock_rec_create(
lock->trx = trx;
lock->type_mode = (type_mode & ~LOCK_TYPE_MASK) | LOCK_REC;
-#ifdef WITH_WSREP
- if (wsrep_thd_is_brute_force(trx->mysql_thd)) {
- lock->type_mode |= WSREP_BF;
- }
-#endif /* WITH_WSREP */
-
lock->index = index;
+
lock->un_member.rec_lock.space = space;
lock->un_member.rec_lock.page_no = page_no;
lock->un_member.rec_lock.n_bits = n_bytes * 8;
@@ -1959,12 +1948,12 @@ lock_rec_create(
ut_ad(index->table->n_ref_count > 0 || !index->table->can_be_evicted);
#ifdef WITH_WSREP
- if (c_lock && wsrep_thd_is_brute_force(trx->mysql_thd)) {
+ if (c_lock && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
lock_t *hash = (lock_t *)c_lock->hash;
lock_t *prev = NULL;
while (hash &&
- wsrep_thd_is_brute_force(((lock_t *)hash)->trx->mysql_thd) &&
+ wsrep_thd_is_BF(((lock_t *)hash)->trx->mysql_thd, TRUE) &&
wsrep_trx_order_before(
((lock_t *)hash)->trx->mysql_thd,
trx->mysql_thd)) {
@@ -2378,11 +2367,6 @@ lock_rec_lock_fast(
|| (LOCK_MODE_MASK & mode) == LOCK_X);
ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
|| mode - (LOCK_MODE_MASK & mode) == 0
-#ifdef WITH_WSREP
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == 0
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_GAP
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_REC_NOT_GAP
-#endif /* WITH_WSREP */
|| mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP);
ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index));
@@ -2454,11 +2438,11 @@ lock_rec_lock_slow(
que_thr_t* thr) /*!< in: query thread */
{
trx_t* trx;
- lock_t* lock;
- dberr_t err = DB_SUCCESS;
#ifdef WITH_WSREP
lock_t* c_lock = NULL;
#endif
+ lock_t* lock;
+ dberr_t err = DB_SUCCESS;
ut_ad(lock_mutex_own());
ut_ad((LOCK_MODE_MASK & mode) != LOCK_S
@@ -2469,11 +2453,6 @@ lock_rec_lock_slow(
|| (LOCK_MODE_MASK & mode) == LOCK_X);
ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
|| mode - (LOCK_MODE_MASK & mode) == 0
-#ifdef WITH_WSREP
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == 0
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_GAP
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_REC_NOT_GAP
-#endif /* WITH_WSREP */
|| mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP);
ut_ad(dict_index_is_clust(index) || !dict_index_is_online_ddl(index));
@@ -2582,11 +2561,6 @@ lock_rec_lock(
|| (LOCK_MODE_MASK & mode) == LOCK_X);
ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP
|| mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP
-#ifdef WITH_WSREP
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == 0
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_GAP
- || mode - (LOCK_MODE_MASK & mode) - WSREP_BF == LOCK_REC_NOT_GAP
-#endif /* WITH_WSREP */
|| mode - (LOCK_MODE_MASK & mode) == 0);
#ifdef WITH_WSREP
@@ -4040,20 +4014,19 @@ lock_deadlock_select_victim(
if (trx_weight_ge(ctx->wait_lock->trx, ctx->start)) {
/* The joining transaction is 'smaller',
choose it as the victim and roll it back. */
-
#ifdef WITH_WSREP
- if (!wsrep_thd_is_brute_force(ctx->start->mysql_thd))
- return(ctx->start);
- else
+ if (wsrep_thd_is_BF(ctx->start->mysql_thd, TRUE))
+ return(ctx->wait_lock->trx);
+ else
#endif /* WITH_WSREP */
return(ctx->start);
}
#ifdef WITH_WSREP
- if (wsrep_thd_is_brute_force(ctx->wait_lock->trx->mysql_thd)) {
- return(ctx->start);
- }
-#endif
+ if (wsrep_thd_is_BF(ctx->wait_lock->trx->mysql_thd, TRUE))
+ return(ctx->start);
+ else
+#endif /* WITH_WSREP */
return(ctx->wait_lock->trx);
}
@@ -4184,7 +4157,7 @@ lock_deadlock_search(
ctx->too_deep = TRUE;
#ifdef WITH_WSREP
- if (wsrep_thd_is_brute_force(ctx->start->mysql_thd))
+ if (wsrep_thd_is_BF(ctx->start->mysql_thd, TRUE))
return(ctx->wait_lock->trx->id);
else
#endif /* WITH_WSREP */
@@ -4207,7 +4180,7 @@ lock_deadlock_search(
ctx->too_deep = TRUE;
#ifdef WITH_WSREP
- if (wsrep_thd_is_brute_force(ctx->start->mysql_thd))
+ if (wsrep_thd_is_BF(ctx->start->mysql_thd, TRUE))
return(lock->trx->id);
else
#endif /* WITH_WSREP */
@@ -4330,7 +4303,7 @@ lock_deadlock_check_and_resolve(
ut_a(victim_trx_id == trx->id);
#ifdef WITH_WSREP
- if (!wsrep_thd_is_brute_force(ctx.start->mysql_thd))
+ if (!wsrep_thd_is_BF(ctx.start->mysql_thd, TRUE))
{
#endif /* WITH_WSREP */
if (!srv_read_only_mode) {
@@ -4426,8 +4399,9 @@ lock_table_create(
ut_ad(table->n_ref_count > 0 || !table->can_be_evicted);
UT_LIST_ADD_LAST(trx_locks, trx->lock.trx_locks, lock);
+
#ifdef WITH_WSREP
- if (c_lock && wsrep_thd_is_brute_force(trx->mysql_thd)) {
+ if (c_lock && wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
UT_LIST_INSERT_AFTER(
un_member.tab_lock.locks, table->locks, c_lock, lock);
} else {
@@ -6533,7 +6507,7 @@ lock_rec_convert_impl_to_expl(
if (rec_get_deleted_flag(rec, rec_offs_comp(offsets))
#ifdef WITH_WSREP
- && !wsrep_thd_is_brute_force(impl_trx->mysql_thd)
+ && !wsrep_thd_is_BF(impl_trx->mysql_thd, FALSE)
/* BF-BF conflict is possible if advancing into
lock_rec_other_has_conflicting*/
#endif /* WITH_WSREP */
diff --git a/storage/xtradb/lock/lock0wait.cc b/storage/xtradb/lock/lock0wait.cc
index 0c1269f02d5..388c847f580 100644
--- a/storage/xtradb/lock/lock0wait.cc
+++ b/storage/xtradb/lock/lock0wait.cc
@@ -195,7 +195,7 @@ wsrep_is_BF_lock_timeout(
trx_t* trx) /* in: trx to check for lock priority */
{
if (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(trx->mysql_thd)) {
+ wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
fprintf(stderr, "WSREP: BF lock wait long\n");
srv_print_innodb_monitor = TRUE;
srv_print_innodb_lock_monitor = TRUE;
diff --git a/storage/xtradb/row/row0ins.cc b/storage/xtradb/row/row0ins.cc
index d36d589e6c6..9cf2a4fc00d 100644
--- a/storage/xtradb/row/row0ins.cc
+++ b/storage/xtradb/row/row0ins.cc
@@ -1939,9 +1939,6 @@ row_ins_scan_sec_index_for_duplicate(
mem_heap_t* offsets_heap)
/*!< in/out: memory heap that can be emptied */
{
-#ifdef WITH_WSREP
- trx_t* trx = thr_get_trx(thr);
-#endif
ulint n_unique;
int cmp;
ulint n_fields_cmp;
@@ -2010,16 +2007,7 @@ row_ins_scan_sec_index_for_duplicate(
if (flags & BTR_NO_LOCKING_FLAG) {
/* Set no locks when applying log
in online table rebuild. */
-
-#ifdef WITH_WSREP
- /* slave applier must not get duplicate error */
- } else if (allow_duplicates ||
- (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(trx->mysql_thd))) {
-#else
-
} else if (allow_duplicates) {
-#endif
/* If the SQL-query will update or replace
duplicate key we will take X-lock for
@@ -2030,6 +2018,10 @@ row_ins_scan_sec_index_for_duplicate(
lock_type, block, rec, index, offsets, thr);
} else {
+#ifdef WITH_WSREP
+ /* appliers don't need dupkey checks */
+ if (!wsrep_thd_is_BF(thr_get_trx(thr)->mysql_thd, 0))
+#endif /* WITH_WSREP */
err = row_ins_set_shared_rec_lock(
lock_type, block, rec, index, offsets, thr);
}
@@ -2225,13 +2217,7 @@ row_ins_duplicate_error_in_clust(
sure that in roll-forward we get the same duplicate
errors as in original execution */
-#ifdef WITH_WSREP
- if (trx->duplicates ||
- (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(trx->mysql_thd))) {
-#else
if (trx->duplicates) {
-#endif
/* If the SQL-query will update or replace
duplicate key we will take X-lock for
@@ -2276,13 +2262,7 @@ duplicate:
offsets = rec_get_offsets(rec, cursor->index, offsets,
ULINT_UNDEFINED, &heap);
-#ifdef WITH_WSREP
- if (trx->duplicates ||
- (wsrep_on(trx->mysql_thd) &&
- wsrep_thd_is_brute_force(trx->mysql_thd))) {
-#else
if (trx->duplicates) {
-#endif
/* If the SQL-query will update or replace
duplicate key we will take X-lock for
diff --git a/storage/xtradb/row/row0upd.cc b/storage/xtradb/row/row0upd.cc
index 9d40848c2fc..5725b229a07 100644
--- a/storage/xtradb/row/row0upd.cc
+++ b/storage/xtradb/row/row0upd.cc
@@ -175,27 +175,6 @@ func_exit:
return(is_referenced);
}
-#ifdef WITH_WSREP
-ulint
-wsrep_append_foreign_key(
- trx_t* trx,
- dict_foreign_t* foreign,
- const rec_t* clust_rec,
- dict_index_t* clust_index,
- ibool referenced,
- ibool shared);
-
-ulint
-wsrep_row_upd_check_foreign_constraints(
- upd_node_t* node, /*!< in: row update node */
- btr_pcur_t* pcur, /*!< in: cursor positioned on a record; NOTE: the
- cursor position is lost in this function! */
- dict_table_t* table, /*!< in: table in question */
- dict_index_t* index, /*!< in: index of the cursor */
- ulint* offsets,/*!< in/out: rec_get_offsets(pcur.rec, index) */
- que_thr_t* thr, /*!< in: query thread */
- mtr_t* mtr); /*!< in: mtr */
-#endif /* WITH_WSREP */
/*********************************************************************//**
Checks if possible foreign key constraints hold after a delete of the record
@@ -314,7 +293,125 @@ run_again:
}
err = DB_SUCCESS;
+func_exit:
+ if (got_s_lock) {
+ row_mysql_unfreeze_data_dictionary(trx);
+ }
+
+ mem_heap_free(heap);
+
+ return(err);
+}
+#ifdef WITH_WSREP
+static
+dberr_t
+wsrep_row_upd_check_foreign_constraints(
+/*=================================*/
+ upd_node_t* node, /*!< in: row update node */
+ btr_pcur_t* pcur, /*!< in: cursor positioned on a record; NOTE: the
+ cursor position is lost in this function! */
+ dict_table_t* table, /*!< in: table in question */
+ dict_index_t* index, /*!< in: index of the cursor */
+ ulint* offsets,/*!< in/out: rec_get_offsets(pcur.rec, index) */
+ que_thr_t* thr, /*!< in: query thread */
+ mtr_t* mtr) /*!< in: mtr */
+{
+ dict_foreign_t* foreign;
+ mem_heap_t* heap;
+ dtuple_t* entry;
+ trx_t* trx;
+ const rec_t* rec;
+ ulint n_ext;
+ dberr_t err;
+ ibool got_s_lock = FALSE;
+
+ if (UT_LIST_GET_FIRST(table->foreign_list) == NULL) {
+
+ return(DB_SUCCESS);
+ }
+
+ trx = thr_get_trx(thr);
+
+ /* TODO: make native slave thread bail out here */
+
+ rec = btr_pcur_get_rec(pcur);
+ ut_ad(rec_offs_validate(rec, index, offsets));
+
+ heap = mem_heap_create(500);
+
+ entry = row_rec_to_index_entry(rec, index, offsets,
+ &n_ext, heap);
+
+ mtr_commit(mtr);
+
+ mtr_start(mtr);
+ if (trx->dict_operation_lock_mode == 0) {
+ got_s_lock = TRUE;
+
+ row_mysql_freeze_data_dictionary(trx);
+ }
+
+ foreign = UT_LIST_GET_FIRST(table->foreign_list);
+
+ while (foreign) {
+ /* Note that we may have an update which updates the index
+ record, but does NOT update the first fields which are
+ referenced in a foreign key constraint. Then the update does
+ NOT break the constraint. */
+
+ if (foreign->foreign_index == index
+ && (node->is_delete
+ || row_upd_changes_first_fields_binary(
+ entry, index, node->update,
+ foreign->n_fields))) {
+
+ if (foreign->referenced_table == NULL) {
+ foreign->referenced_table =
+ dict_table_open_on_name(
+ foreign->referenced_table_name_lookup,
+ FALSE, FALSE, DICT_ERR_IGNORE_NONE);
+ }
+
+ if (foreign->referenced_table) {
+ mutex_enter(&(dict_sys->mutex));
+
+ (foreign->referenced_table
+ ->n_foreign_key_checks_running)++;
+
+ mutex_exit(&(dict_sys->mutex));
+ }
+
+ /* NOTE that if the thread ends up waiting for a lock
+ we will release dict_operation_lock temporarily!
+ But the counter on the table protects 'foreign' from
+ being dropped while the check is running. */
+
+ err = row_ins_check_foreign_constraint(
+ TRUE, foreign, table, entry, thr);
+
+ if (foreign->referenced_table) {
+ mutex_enter(&(dict_sys->mutex));
+
+ ut_a(foreign->referenced_table
+ ->n_foreign_key_checks_running > 0);
+
+ (foreign->referenced_table
+ ->n_foreign_key_checks_running)--;
+
+ mutex_exit(&(dict_sys->mutex));
+ }
+
+ if (err != DB_SUCCESS) {
+
+ goto func_exit;
+ }
+ }
+
+ foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
+ }
+
+ err = DB_SUCCESS;
func_exit:
if (got_s_lock) {
row_mysql_unfreeze_data_dictionary(trx);
@@ -326,6 +423,7 @@ func_exit:
return(err);
}
+#endif /* WITH_WSREP */
/*********************************************************************//**
Creates an update node for a query graph.
@@ -2015,123 +2113,6 @@ row_upd_clust_rec_by_insert_inherit_func(
return(inherit);
}
-#ifdef WITH_WSREP
-ulint
-wsrep_row_upd_check_foreign_constraints(
-/*=================================*/
- upd_node_t* node, /*!< in: row update node */
- btr_pcur_t* pcur, /*!< in: cursor positioned on a record; NOTE: the
- cursor position is lost in this function! */
- dict_table_t* table, /*!< in: table in question */
- dict_index_t* index, /*!< in: index of the cursor */
- ulint* offsets,/*!< in/out: rec_get_offsets(pcur.rec, index) */
- que_thr_t* thr, /*!< in: query thread */
- mtr_t* mtr) /*!< in: mtr */
-{
- dict_foreign_t* foreign;
- mem_heap_t* heap;
- dtuple_t* entry;
- trx_t* trx;
- const rec_t* rec;
- ulint n_ext;
- ulint err;
- ibool got_s_lock = FALSE;
-
- if (UT_LIST_GET_FIRST(table->foreign_list) == NULL) {
-
- return(DB_SUCCESS);
- }
-
- trx = thr_get_trx(thr);
-
- rec = btr_pcur_get_rec(pcur);
- ut_ad(rec_offs_validate(rec, index, offsets));
-
- heap = mem_heap_create(500);
-
- entry = row_rec_to_index_entry(rec, index, offsets, &n_ext, heap);
-
- mtr_commit(mtr);
-
- mtr_start(mtr);
-
- if (trx->dict_operation_lock_mode == 0) {
- got_s_lock = TRUE;
-
- row_mysql_freeze_data_dictionary(trx);
- }
-
- foreign = UT_LIST_GET_FIRST(table->foreign_list);
-
- while (foreign) {
- /* Note that we may have an update which updates the index
- record, but does NOT update the first fields which are
- referenced in a foreign key constraint. Then the update does
- NOT break the constraint. */
-
- if (foreign->foreign_index == index
- && (node->is_delete
- || row_upd_changes_first_fields_binary(
- entry, index, node->update,
- foreign->n_fields))) {
-
- if (foreign->referenced_table == NULL) {
- foreign->referenced_table =
- dict_table_open_on_name(
- foreign->referenced_table_name_lookup,
- FALSE, FALSE, DICT_ERR_IGNORE_NONE);
- }
-
- if (foreign->referenced_table) {
- mutex_enter(&(dict_sys->mutex));
-
- (foreign->referenced_table
- ->n_foreign_key_checks_running)++;
-
- mutex_exit(&(dict_sys->mutex));
- }
-
- /* NOTE that if the thread ends up waiting for a lock
- we will release dict_operation_lock temporarily!
- But the counter on the table protects 'foreign' from
- being dropped while the check is running. */
-
- err = row_ins_check_foreign_constraint(
- TRUE, foreign, table, entry, thr);
-
- if (foreign->referenced_table) {
- mutex_enter(&(dict_sys->mutex));
-
- ut_a(foreign->referenced_table
- ->n_foreign_key_checks_running > 0);
-
- (foreign->referenced_table
- ->n_foreign_key_checks_running)--;
-
- mutex_exit(&(dict_sys->mutex));
- }
-
- if (err != DB_SUCCESS) {
-
- goto func_exit;
- }
- }
-
- foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
- }
-
- err = DB_SUCCESS;
-func_exit:
- if (got_s_lock) {
- row_mysql_unfreeze_data_dictionary(trx);
- }
-
- mem_heap_free(heap);
-
- return(err);
-}
-#endif /* WITH_WSREP */
-
/***********************************************************//**
Marks the clustered index record deleted and inserts the updated version
of the record to the index. This function should be used when the ordering
diff --git a/storage/xtradb/trx/trx0sys.cc b/storage/xtradb/trx/trx0sys.cc
index daa13b8b2c5..0a8d41c9a50 100644
--- a/storage/xtradb/trx/trx0sys.cc
+++ b/storage/xtradb/trx/trx0sys.cc
@@ -178,7 +178,12 @@ trx_sys_flush_max_trx_id(void)
mtr_t mtr;
trx_sysf_t* sys_header;
+#ifndef WITH_WSREP
+ /* wsrep_fake_trx_id violates this assert
+ * Copied from trx_sys_get_new_trx_id
+ */
ut_ad(mutex_own(&trx_sys->mutex));
+#endif /* WITH_WSREP */
if (!srv_read_only_mode) {
mtr_start(&mtr);