mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
* bzr merge -r4027..4061 codership/5.6
* Merged Innodb changes to xtradb
This commit is contained in:
parent
7d892f69a5
commit
b5871a51e9
28 changed files with 520 additions and 509 deletions
|
@ -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()
|
||||
|
|
|
@ -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 "")
|
||||
|
@ -647,10 +647,6 @@ then
|
|||
[[ -e $SST_PROGRESS_FILE ]] && wsrep_log_info "Stale sst_in_progress file: $SST_PROGRESS_FILE"
|
||||
[[ -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 "")
|
||||
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
11
sql/mdl.cc
11
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",
|
||||
|
|
103
sql/mysqld.cc
103
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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
121
sql/wsrep_sst.cc
121
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 : "") : "");
|
||||
const char* binlog_opt= "";
|
||||
char* binlog_opt_val= NULL;
|
||||
|
||||
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);
|
||||
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 : "") : "");
|
||||
const char* binlog_opt= "";
|
||||
char* binlog_opt_val= NULL;
|
||||
|
||||
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 : "");
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue