1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

References: lp:1066784 - Merged revisions 3810-3827 from lp:codership-mysql

This commit is contained in:
Seppo Jaakola
2012-11-28 17:38:32 +02:00
parent 9b47a442b5
commit fc6cd855e9
21 changed files with 453 additions and 136 deletions

View File

@ -17,7 +17,7 @@
# so WSREP_VERSION is produced regardless # so WSREP_VERSION is produced regardless
# Set the patch version # Set the patch version
SET(WSREP_PATCH_VERSION "7") SET(WSREP_PATCH_VERSION "7rc1")
# Obtain patch revision number # Obtain patch revision number
SET(WSREP_PATCH_REVNO $ENV{WSREP_REV}) SET(WSREP_PATCH_REVNO $ENV{WSREP_REV})

View File

@ -810,7 +810,9 @@ static int search_default_file_with_ext(Process_option_func opt_handler,
return 1; /* Ignore wrong files */ return 1; /* Ignore wrong files */
#ifdef WITH_WSREP #ifdef WITH_WSREP
strncpy(wsrep_defaults_file, name, sizeof(wsrep_defaults_file) - 1); /* make sure we do this only once - for top-level file */
if ('\0' == wsrep_defaults_file[0])
strncpy(wsrep_defaults_file, name, sizeof(wsrep_defaults_file) - 1);
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
while (mysql_file_fgets(buff, sizeof(buff) - 1, fp)) while (mysql_file_fgets(buff, sizeof(buff) - 1, fp))

View File

@ -63,7 +63,6 @@ Usage: $0 [OPTIONS]
--syslog Log messages to syslog with 'logger' --syslog Log messages to syslog with 'logger'
--skip-syslog Log messages to error log (default) --skip-syslog Log messages to error log (default)
--syslog-tag=TAG Pass -t "mysqld-TAG" to 'logger' --syslog-tag=TAG Pass -t "mysqld-TAG" to 'logger'
--wsrep-urls=WSREP_URLS Comma-separated list of wsrep URLs
All other options are passed to the mysqld program. All other options are passed to the mysqld program.
@ -126,7 +125,7 @@ log_notice () {
} }
eval_log_error () { eval_log_error () {
cmd="$1" local cmd="$1"
case $logging in case $logging in
file) cmd="$cmd >> "`shell_quote_string "$err_log"`" 2>&1" ;; file) cmd="$cmd >> "`shell_quote_string "$err_log"`" 2>&1" ;;
syslog) syslog)
@ -165,6 +164,8 @@ shell_quote_string() {
wsrep_pick_url() { wsrep_pick_url() {
[ $# -eq 0 ] && return 0 [ $# -eq 0 ] && return 0
log_error "WSREP: 'wsrep_urls' is DEPRECATED! Use wsrep_cluster_address to specify multiple addresses instead."
if ! which nc >/dev/null; then if ! which nc >/dev/null; then
log_error "ERROR: nc tool not found in PATH! Make sure you have it installed." log_error "ERROR: nc tool not found in PATH! Make sure you have it installed."
return 1 return 1
@ -193,10 +194,12 @@ wsrep_pick_url() {
# Run mysqld with --wsrep-recover and parse recovered position from log. # Run mysqld with --wsrep-recover and parse recovered position from log.
# Position will be stored in wsrep_start_position_opt global. # Position will be stored in wsrep_start_position_opt global.
wsrep_recovery() { wsrep_recovery() {
cmd="$@" local mysqld_cmd="$@"
wr_logfile=$(mktemp) wr_logfile=$(mktemp)
log_notice "WSREP: Running position recovery" [ "$EUID" = "0" ] && chown $user $wr_logfile
$cmd --log_error=$wr_logfile --wsrep-recover chmod 600 $wr_logfile
log_notice "WSREP: Running position recovery with --log_error=$wr_logfile"
$mysqld_cmd --log_error=$wr_logfile --wsrep-recover
rp=$(grep "WSREP: Recovered position:" $wr_logfile) rp=$(grep "WSREP: Recovered position:" $wr_logfile)
if [ -z "$rp" ]; then if [ -z "$rp" ]; then
skipped=$(grep WSREP $wr_logfile | grep "skipping position recovery") skipped=$(grep WSREP $wr_logfile | grep "skipping position recovery")
@ -276,7 +279,12 @@ parse_arguments() {
--syslog-tag=*) syslog_tag="$val" ;; --syslog-tag=*) syslog_tag="$val" ;;
--timezone=*) TZ="$val"; export TZ; ;; --timezone=*) TZ="$val"; export TZ; ;;
--wsrep[-_]urls=*) wsrep_urls="$val"; ;; --wsrep[-_]urls=*) wsrep_urls="$val"; ;;
--wsrep[-_]provider=*)
if test -n "$val" && test "$val" != "none"
then
wsrep_restart=1
fi
;;
--help) usage ;; --help) usage ;;
*) *)
@ -824,6 +832,9 @@ max_fast_restarts=5
# flag whether a usable sleep command exists # flag whether a usable sleep command exists
have_sleep=1 have_sleep=1
# maximum number of wsrep restarts
max_wsrep_restarts=0
while true while true
do do
rm -f $safe_mysql_unix_port "$pid_file" # Some extra safety rm -f $safe_mysql_unix_port "$pid_file" # Some extra safety
@ -903,6 +914,20 @@ do
I=`expr $I + 1` I=`expr $I + 1`
done done
fi fi
if [ -n "$wsrep_restart" ]
then
if [ $wsrep_restart -le $max_wsrep_restarts ]
then
wsrep_restart=`expr $wsrep_restart + 1`
log_notice "WSREP: sleeping 15 seconds before restart"
sleep 15
else
log_notice "WSREP: not restarting wsrep node automatically"
break
fi
fi
log_notice "mysqld restarted" log_notice "mysqld restarted"
done done

View File

@ -38,7 +38,7 @@ cleanup_joiner()
check_pid() check_pid()
{ {
local pid_file=$1 local pid_file=$1
[ -r $pid_file ] && ps -p $(cat $pid_file) >/dev/null 2>&1 [ -r "$pid_file" ] && ps -p $(cat $pid_file) >/dev/null 2>&1
} }
check_pid_and_port() check_pid_and_port()

View File

@ -34,8 +34,8 @@ cleanup_joiner()
check_pid() check_pid()
{ {
local pid_file=$1 local pid_file="$1"
[ -r $pid_file ] && ps -p $(cat $pid_file) >/dev/null 2>&1 [ -r "$pid_file" ] && ps -p $(cat "$pid_file") >/dev/null 2>&1
} }
kill_xtrabackup() kill_xtrabackup()
@ -133,14 +133,14 @@ then
exit 22 exit 22
fi fi
if check_pid ${XTRABACKUP_PID} if check_pid "${XTRABACKUP_PID}"
then then
wsrep_log_error "xtrabackup process is still running. Killing... " wsrep_log_error "xtrabackup process is still running. Killing... "
kill_xtrabackup kill_xtrabackup
exit 22 exit 22
fi fi
rm -f ${XTRABACKUP_PID} rm -f "${XTRABACKUP_PID}"
else # BYPASS else # BYPASS
STATE="${WSREP_SST_OPT_GTID}" STATE="${WSREP_SST_OPT_GTID}"

View File

@ -1121,6 +1121,15 @@ bool Global_read_lock::make_global_read_lock_block_commit(THD *thd)
if (m_state != GRL_ACQUIRED) if (m_state != GRL_ACQUIRED)
DBUG_RETURN(0); DBUG_RETURN(0);
mdl_request.init(MDL_key::COMMIT, "", "", MDL_SHARED, MDL_EXPLICIT);
if (thd->mdl_context.acquire_lock(&mdl_request,
thd->variables.lock_wait_timeout))
DBUG_RETURN(TRUE);
m_mdl_blocks_commits_lock= mdl_request.ticket;
m_state= GRL_ACQUIRED_AND_BLOCKS_COMMIT;
#ifdef WITH_WSREP #ifdef WITH_WSREP
long long ret = wsrep->pause(wsrep); long long ret = wsrep->pause(wsrep);
if (ret >= 0) if (ret >= 0)
@ -1137,15 +1146,6 @@ bool Global_read_lock::make_global_read_lock_block_commit(THD *thd)
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
mdl_request.init(MDL_key::COMMIT, "", "", MDL_SHARED, MDL_EXPLICIT);
if (thd->mdl_context.acquire_lock(&mdl_request,
thd->variables.lock_wait_timeout))
DBUG_RETURN(TRUE);
m_mdl_blocks_commits_lock= mdl_request.ticket;
m_state= GRL_ACQUIRED_AND_BLOCKS_COMMIT;
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }

View File

@ -3015,3 +3015,33 @@ void MDL_context::set_transaction_duration_for_all_locks()
ticket->m_duration= MDL_TRANSACTION; ticket->m_duration= MDL_TRANSACTION;
#endif #endif
} }
#ifdef WITH_WSREP
void MDL_ticket::wsrep_report(bool debug)
{
if (debug)
{
WSREP_DEBUG("MDL ticket: type: %s space: %s db: %s name: %s (%s)",
(get_type() == MDL_INTENTION_EXCLUSIVE) ? "intention exclusive" :
((get_type() == MDL_SHARED) ? "shared" :
((get_type() == MDL_SHARED_HIGH_PRIO ? "shared high prio" :
((get_type() == MDL_SHARED_READ) ? "shared read" :
((get_type() == MDL_SHARED_WRITE) ? "shared write" :
((get_type() == MDL_SHARED_NO_WRITE) ? "shared no write" :
((get_type() == MDL_SHARED_NO_READ_WRITE) ? "shared no read write" :
((get_type() == MDL_EXCLUSIVE) ? "exclusive" :
"UNKNOWN")))))))),
(m_lock->key.mdl_namespace() == MDL_key::GLOBAL) ? "GLOBAL" :
((m_lock->key.mdl_namespace() == MDL_key::SCHEMA) ? "SCHEMA" :
((m_lock->key.mdl_namespace() == MDL_key::TABLE) ? "TABLE" :
((m_lock->key.mdl_namespace() == MDL_key::TABLE) ? "FUNCTION" :
((m_lock->key.mdl_namespace() == MDL_key::TABLE) ? "PROCEDURE" :
((m_lock->key.mdl_namespace() == MDL_key::TABLE) ? "TRIGGER" :
((m_lock->key.mdl_namespace() == MDL_key::TABLE) ? "EVENT" :
((m_lock->key.mdl_namespace() == MDL_key::COMMIT) ? "COMMIT" :
(char *)"UNKNOWN"))))))),
m_lock->key.db_name(),
m_lock->key.name(),
m_lock->key.get_wait_state_name());
}
}
#endif /* WITH_WSREP */

View File

@ -475,6 +475,9 @@ public:
MDL_ticket *next_in_lock; MDL_ticket *next_in_lock;
MDL_ticket **prev_in_lock; MDL_ticket **prev_in_lock;
public: public:
#ifdef WITH_WSREP
void wsrep_report(bool debug);
#endif /* WITH_WSREP */
bool has_pending_conflicting_lock() const; bool has_pending_conflicting_lock() const;
MDL_context *get_ctx() const { return m_ctx; } MDL_context *get_ctx() const { return m_ctx; }

View File

@ -3639,7 +3639,13 @@ static int init_common_variables()
} }
else else
opt_log_basename= glob_hostname; opt_log_basename= glob_hostname;
#ifdef WITH_WSREP
if (0 == wsrep_node_name || 0 == wsrep_node_name[0])
{
my_free((void *)wsrep_node_name);
wsrep_node_name= my_strdup(glob_hostname, MYF(MY_WME));
}
#endif /* WITH_WSREP */
if (!*pidfile_name) if (!*pidfile_name)
{ {
strmake(pidfile_name, opt_log_basename, sizeof(pidfile_name)-5); strmake(pidfile_name, opt_log_basename, sizeof(pidfile_name)-5);
@ -4390,29 +4396,37 @@ will be ignored as the --log-bin option is not defined.");
} }
#endif #endif
/* WSREP BEFORE */ #ifdef WITH_WSREP /* WSREP BEFORE SE */
#ifdef WITH_WSREP if (!wsrep_recovery)
// 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); if (opt_bootstrap) // bootsrap option given - disable wsrep functionality
strcat(tmp_path, "/bin"); {
wsrep_prepend_PATH(tmp_path); wsrep_provider_init(WSREP_NONE);
} if (wsrep_init()) unireg_abort(1);
else }
{ else // full wsrep initialization
WSREP_ERROR("Could not append %s/bin to PATH", mysql_home); {
} // 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 (opt_bootstrap) if (wsrep_before_SE())
{ {
wsrep_provider_init(WSREP_NONE); set_ports(); // this is also called in network_init() later but we need
if (wsrep_init()) unireg_abort(1); // to know mysqld_port now - lp:1071882
} wsrep_init_startup(true);
else if (!wsrep_recovery && wsrep_init_first()) }
{ }
wsrep_init_startup(true);
} }
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
if (opt_bin_log) if (opt_bin_log)
@ -5622,32 +5636,37 @@ int mysqld_main(int argc, char **argv)
if (Events::init(opt_noacl || opt_bootstrap)) if (Events::init(opt_noacl || opt_bootstrap))
unireg_abort(1); unireg_abort(1);
/* WSREP AFTER */ #ifdef WITH_WSREP /* WSREP AFTER SE */
#ifdef WITH_WSREP if (wsrep_recovery)
wsrep_SE_initialized();
if (opt_bootstrap)
{
/*! bootstrap wsrep init was taken care of above */
}
else if (wsrep_recovery)
{ {
select_thread_in_use= 0; select_thread_in_use= 0;
wsrep_recover(); wsrep_recover();
unireg_abort(0); unireg_abort(0);
} }
else if (wsrep_init_first())
if (opt_bootstrap)
{ {
/*! in case of no SST wsrep waits in view handler callback */ /*! bootstrap wsrep init was taken care of above */
wsrep_SE_init_grab();
wsrep_SE_init_done();
/*! in case of SST wsrep waits for wsrep->sst_received */
wsrep_sst_continue();
} }
else else
{ {
wsrep_init_startup (false); wsrep_SE_initialized();
if (wsrep_before_SE())
{
/*! in case of no SST wsrep waits in view handler callback */
wsrep_SE_init_grab();
wsrep_SE_init_done();
/*! in case of SST wsrep waits for wsrep->sst_received */
wsrep_sst_continue();
}
else
{
wsrep_init_startup (false);
}
wsrep_create_appliers(wsrep_slave_threads - 1);
} }
wsrep_create_appliers(wsrep_slave_threads - 1);
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
if (opt_bootstrap) if (opt_bootstrap)
{ {
@ -8451,15 +8470,6 @@ mysqld_get_one_option(int optid,
lower_case_table_names_used= 1; lower_case_table_names_used= 1;
break; break;
#ifdef WITH_WSREP #ifdef WITH_WSREP
case OPT_WSREP_PROVIDER:
wsrep_provider_init (argument);
break;
case OPT_WSREP_PROVIDER_OPTIONS:
wsrep_provider_options_init (argument);
break;
case OPT_WSREP_CLUSTER_ADDRESS:
wsrep_cluster_address_init (argument);
break;
case OPT_WSREP_START_POSITION: case OPT_WSREP_START_POSITION:
wsrep_start_position_init (argument); wsrep_start_position_init (argument);
break; break;

View File

@ -2601,10 +2601,10 @@ int apply_event_and_update_pos(Log_event* ev, THD* thd, Relay_log_info* rli)
int reason= ev->shall_skip(rli); int reason= ev->shall_skip(rli);
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (ev->get_type_code() == XID_EVENT || if (WSREP_ON && (ev->get_type_code() == XID_EVENT ||
(ev->get_type_code() == QUERY_EVENT && thd->wsrep_mysql_replicated > 0 && (ev->get_type_code() == QUERY_EVENT && thd->wsrep_mysql_replicated > 0 &&
(!strncasecmp(((Query_log_event*)ev)->query , "BEGIN", 5) || (!strncasecmp(((Query_log_event*)ev)->query , "BEGIN", 5) ||
!strncasecmp(((Query_log_event*)ev)->query , "COMMIT", 6) ))) !strncasecmp(((Query_log_event*)ev)->query , "COMMIT", 6) ))))
{ {
if (++thd->wsrep_mysql_replicated < (int)wsrep_mysql_replication_bundle) if (++thd->wsrep_mysql_replicated < (int)wsrep_mysql_replication_bundle)
{ {
@ -3568,7 +3568,7 @@ pthread_handler_t handle_slave_sql(void *arg)
#ifdef WITH_WSREP #ifdef WITH_WSREP
thd->wsrep_exec_mode= LOCAL_STATE; thd->wsrep_exec_mode= LOCAL_STATE;
/* synchronize with wsrep replication */ /* synchronize with wsrep replication */
wsrep_ready_wait (); if (WSREP_ON) wsrep_ready_wait();
#endif #endif
DBUG_PRINT("master_info",("log_file_name: %s position: %s", DBUG_PRINT("master_info",("log_file_name: %s position: %s",
rli->group_master_log_name, rli->group_master_log_name,

View File

@ -1059,7 +1059,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
thd->mysys_var->abort = 0; thd->mysys_var->abort = 0;
thd->wsrep_conflict_state = NO_CONFLICT; thd->wsrep_conflict_state = NO_CONFLICT;
thd->wsrep_retry_counter = 0; thd->wsrep_retry_counter = 0;
/*
Increment threads running to compensate dec_thread_running() called
after dispatch_end label.
*/
inc_thread_running();
goto dispatch_end; goto dispatch_end;
} }
mysql_mutex_unlock(&thd->LOCK_wsrep_thd); mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
@ -4883,7 +4887,6 @@ finish:
thd_proc_info(thd, "closing tables"); thd_proc_info(thd, "closing tables");
close_thread_tables(thd); close_thread_tables(thd);
#ifdef WITH_WSREP #ifdef WITH_WSREP
WSREP_TO_ISOLATION_END
thd->wsrep_consistency_check= NO_CONSISTENCY_CHECK; thd->wsrep_consistency_check= NO_CONSISTENCY_CHECK;
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
thd_proc_info(thd, 0); thd_proc_info(thd, 0);
@ -4922,6 +4925,7 @@ finish:
{ {
thd->mdl_context.release_statement_locks(); thd->mdl_context.release_statement_locks();
} }
WSREP_TO_ISOLATION_END
DBUG_RETURN(res || thd->is_error()); DBUG_RETURN(res || thd->is_error());
} }
@ -6127,14 +6131,14 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
{ {
mysql_reset_thd_for_next_command(thd, opt_userstat_running); mysql_reset_thd_for_next_command(thd, opt_userstat_running);
thd->killed= NOT_KILLED; thd->killed= NOT_KILLED;
if (is_autocommit && if (is_autocommit &&
(thd->wsrep_retry_counter < thd->variables.wsrep_retry_autocommit)) thd->lex->sql_command != SQLCOM_SELECT &&
(thd->wsrep_retry_counter < thd->variables.wsrep_retry_autocommit))
{ {
WSREP_DEBUG("wsrep retrying AC query: %s", WSREP_DEBUG("wsrep retrying AC query: %s",
(thd->query()) ? thd->query() : "void"); (thd->query()) ? thd->query() : "void");
close_thread_tables(thd);
close_thread_tables(thd);
thd->wsrep_conflict_state= RETRY_AUTOCOMMIT; thd->wsrep_conflict_state= RETRY_AUTOCOMMIT;
thd->wsrep_retry_counter++; // grow thd->wsrep_retry_counter++; // grow
@ -6166,7 +6170,12 @@ static void wsrep_mysql_parse(THD *thd, char *rawbuf, uint length,
if (thd->wsrep_retry_query) if (thd->wsrep_retry_query)
{ {
WSREP_DEBUG("releasing retry_query: %s", thd->wsrep_retry_query); WSREP_DEBUG("releasing retry_query: conf %d sent %d kill %d errno %d SQL %s",
thd->wsrep_conflict_state,
thd->stmt_da->is_sent,
thd->killed,
thd->stmt_da->is_error() ? thd->stmt_da->sql_errno() : 0,
thd->wsrep_retry_query);
my_free(thd->wsrep_retry_query); my_free(thd->wsrep_retry_query);
thd->wsrep_retry_query = NULL; thd->wsrep_retry_query = NULL;
thd->wsrep_retry_query_len = 0; thd->wsrep_retry_query_len = 0;
@ -8316,8 +8325,6 @@ void wsrep_replication_process(THD *thd)
struct wsrep_thd_shadow shadow; struct wsrep_thd_shadow shadow;
wsrep_prepare_bf_thd(thd, &shadow); wsrep_prepare_bf_thd(thd, &shadow);
wsrep_format_desc= new Format_description_log_event(4);
rcode = wsrep->recv(wsrep, (void *)thd); rcode = wsrep->recv(wsrep, (void *)thd);
DBUG_PRINT("wsrep",("wsrep_repl returned: %d", rcode)); DBUG_PRINT("wsrep",("wsrep_repl returned: %d", rcode));
@ -8428,8 +8435,8 @@ void wsrep_rollback_process(THD *thd)
mysql_mutex_lock(&aborting->LOCK_wsrep_thd); mysql_mutex_lock(&aborting->LOCK_wsrep_thd);
wsrep_client_rollback(aborting); wsrep_client_rollback(aborting);
WSREP_DEBUG("WSREP rollbacker aborted thd: %llu", WSREP_DEBUG("WSREP rollbacker aborted thd: (%lu %llu)",
(long long)aborting->real_id); aborting->thread_id, (long long)aborting->real_id);
mysql_mutex_unlock(&aborting->LOCK_wsrep_thd); mysql_mutex_unlock(&aborting->LOCK_wsrep_thd);
mysql_mutex_lock(&LOCK_wsrep_rollback); mysql_mutex_lock(&LOCK_wsrep_rollback);

View File

@ -3620,7 +3620,7 @@ static Sys_var_tz Sys_time_zone(
static Sys_var_charptr Sys_wsrep_provider( static Sys_var_charptr Sys_wsrep_provider(
"wsrep_provider", "Path to replication provider library", "wsrep_provider", "Path to replication provider library",
GLOBAL_VAR(wsrep_provider), CMD_LINE(REQUIRED_ARG, OPT_WSREP_PROVIDER), PREALLOCATED GLOBAL_VAR(wsrep_provider), CMD_LINE(REQUIRED_ARG, OPT_WSREP_PROVIDER),
IN_FS_CHARSET, DEFAULT(wsrep_provider), IN_FS_CHARSET, DEFAULT(wsrep_provider),
// IN_FS_CHARSET, DEFAULT(wsrep_provider_default), // IN_FS_CHARSET, DEFAULT(wsrep_provider_default),
NO_MUTEX_GUARD, NOT_IN_BINLOG, NO_MUTEX_GUARD, NOT_IN_BINLOG,
@ -3628,7 +3628,7 @@ static Sys_var_charptr Sys_wsrep_provider(
static Sys_var_charptr Sys_wsrep_provider_options( static Sys_var_charptr Sys_wsrep_provider_options(
"wsrep_provider_options", "provider specific options", "wsrep_provider_options", "provider specific options",
GLOBAL_VAR(wsrep_provider_options), PREALLOCATED GLOBAL_VAR(wsrep_provider_options),
CMD_LINE(REQUIRED_ARG, OPT_WSREP_PROVIDER_OPTIONS), CMD_LINE(REQUIRED_ARG, OPT_WSREP_PROVIDER_OPTIONS),
IN_FS_CHARSET, DEFAULT(wsrep_provider_options), IN_FS_CHARSET, DEFAULT(wsrep_provider_options),
NO_MUTEX_GUARD, NOT_IN_BINLOG, NO_MUTEX_GUARD, NOT_IN_BINLOG,
@ -3652,7 +3652,7 @@ static Sys_var_charptr Sys_wsrep_cluster_name(
static PolyLock_mutex PLock_wsrep_slave_threads(&LOCK_wsrep_slave_threads); static PolyLock_mutex PLock_wsrep_slave_threads(&LOCK_wsrep_slave_threads);
static Sys_var_charptr Sys_wsrep_cluster_address ( static Sys_var_charptr Sys_wsrep_cluster_address (
"wsrep_cluster_address", "Address to initially connect to cluster", "wsrep_cluster_address", "Address to initially connect to cluster",
GLOBAL_VAR(wsrep_cluster_address), PREALLOCATED GLOBAL_VAR(wsrep_cluster_address),
CMD_LINE(REQUIRED_ARG, OPT_WSREP_CLUSTER_ADDRESS), CMD_LINE(REQUIRED_ARG, OPT_WSREP_CLUSTER_ADDRESS),
IN_FS_CHARSET, DEFAULT(wsrep_cluster_address), IN_FS_CHARSET, DEFAULT(wsrep_cluster_address),
&PLock_wsrep_slave_threads, NOT_IN_BINLOG, &PLock_wsrep_slave_threads, NOT_IN_BINLOG,
@ -3741,7 +3741,7 @@ static Sys_var_charptr Sys_wsrep_sst_receive_address(
static Sys_var_charptr Sys_wsrep_sst_auth( static Sys_var_charptr Sys_wsrep_sst_auth(
"wsrep_sst_auth", "Authentication for SST connection", "wsrep_sst_auth", "Authentication for SST connection",
GLOBAL_VAR(wsrep_sst_auth), CMD_LINE(REQUIRED_ARG, OPT_WSREP_SST_AUTH), PREALLOCATED GLOBAL_VAR(wsrep_sst_auth), CMD_LINE(REQUIRED_ARG, OPT_WSREP_SST_AUTH),
IN_FS_CHARSET, DEFAULT(wsrep_sst_auth), NO_MUTEX_GUARD, IN_FS_CHARSET, DEFAULT(wsrep_sst_auth), NO_MUTEX_GUARD,
NOT_IN_BINLOG, NOT_IN_BINLOG,
ON_CHECK(wsrep_sst_auth_check), ON_CHECK(wsrep_sst_auth_check),

View File

@ -21,6 +21,7 @@
#include <cstdlib> #include <cstdlib>
#include "log_event.h" #include "log_event.h"
extern Format_description_log_event *wsrep_format_desc;
wsrep_t *wsrep = NULL; wsrep_t *wsrep = NULL;
my_bool wsrep_emulate_bin_log = FALSE; // activating parts of binlog interface my_bool wsrep_emulate_bin_log = FALSE; // activating parts of binlog interface
@ -94,6 +95,11 @@ wsrep_seqno_t local_seqno = WSREP_SEQNO_UNDEFINED;
wsp::node_status local_status; wsp::node_status local_status;
long wsrep_protocol_version = 2; long wsrep_protocol_version = 2;
// Boolean denoting if server is in initial startup phase. This is needed
// to make sure that main thread waiting in wsrep_sst_wait() is signaled
// if there was no state gap on receiving first view event.
static my_bool wsrep_startup = TRUE;
// action execute callback // action execute callback
extern wsrep_status_t wsrep_apply_cb(void *ctx, extern wsrep_status_t wsrep_apply_cb(void *ctx,
const void* buf, size_t buf_len, const void* buf, size_t buf_len,
@ -283,13 +289,12 @@ static void wsrep_view_handler_cb (void* app_ctx,
* NOTE: Initialize wsrep_group_uuid here only if it wasn't initialized * NOTE: Initialize wsrep_group_uuid here only if it wasn't initialized
* before - OR - it was reinitilized on startup (lp:992840) * before - OR - it was reinitilized on startup (lp:992840)
*/ */
if (!memcmp (&local_uuid, &WSREP_UUID_UNDEFINED, sizeof(wsrep_uuid_t)) || if (wsrep_startup)
0 == wsrep_cluster_conf_id)
{ {
if (wsrep_init_first()) if (wsrep_before_SE())
{ {
wsrep_SE_init_grab(); wsrep_SE_init_grab();
// Signal init thread to continue // Signal mysqld init thread to continue
wsrep_sst_complete (&cluster_uuid, view->seqno, false); wsrep_sst_complete (&cluster_uuid, view->seqno, false);
// and wait for SE initialization // and wait for SE initialization
wsrep_SE_init_wait(); wsrep_SE_init_wait();
@ -305,15 +310,14 @@ static void wsrep_view_handler_cb (void* app_ctx,
wsrep_set_SE_checkpoint(&xid); wsrep_set_SE_checkpoint(&xid);
new_status= WSREP_MEMBER_JOINED; new_status= WSREP_MEMBER_JOINED;
} }
else // just some sanity check
// just some sanity check
if (memcmp (&local_uuid, &cluster_uuid, sizeof (wsrep_uuid_t)))
{ {
if (memcmp (&local_uuid, &cluster_uuid, sizeof (wsrep_uuid_t))) WSREP_ERROR("Undetected state gap. Can't continue.");
{ wsrep_log_states(WSREP_LOG_FATAL, &cluster_uuid, view->seqno,
WSREP_ERROR("Undetected state gap. Can't continue."); &local_uuid, -1);
wsrep_log_states (WSREP_LOG_FATAL, &cluster_uuid, view->seqno, unireg_abort(1);
&local_uuid, -1);
abort();
}
} }
} }
@ -324,7 +328,7 @@ static void wsrep_view_handler_cb (void* app_ctx,
} }
out: out:
wsrep_startup= FALSE;
local_status.set(new_status, view); local_status.set(new_status, view);
} }
@ -415,7 +419,7 @@ int wsrep_init()
wsrep_ready_set(FALSE); wsrep_ready_set(FALSE);
assert(wsrep_provider); assert(wsrep_provider);
wsrep_format_desc= new Format_description_log_event(4);
wsrep_init_position(); wsrep_init_position();
if ((rcode= wsrep_load(wsrep_provider, &wsrep, wsrep_log_cb)) != WSREP_OK) if ((rcode= wsrep_load(wsrep_provider, &wsrep, wsrep_log_cb)) != WSREP_OK)
@ -476,8 +480,10 @@ int wsrep_init()
} }
static char inc_addr[512]= { 0, }; static char inc_addr[512]= { 0, };
if ((!wsrep_node_incoming_address || if ((!wsrep_node_incoming_address ||
!strcmp (wsrep_node_incoming_address, WSREP_NODE_INCOMING_AUTO))) { !strcmp (wsrep_node_incoming_address, WSREP_NODE_INCOMING_AUTO)))
{
size_t const node_addr_len= strlen(node_addr); size_t const node_addr_len= strlen(node_addr);
if (node_addr_len > 0) if (node_addr_len > 0)
{ {
@ -579,6 +585,9 @@ void wsrep_deinit()
provider_name[0]= '\0'; provider_name[0]= '\0';
provider_version[0]= '\0'; provider_version[0]= '\0';
provider_vendor[0]= '\0'; provider_vendor[0]= '\0';
delete wsrep_format_desc;
wsrep_format_desc= NULL;
} }
void wsrep_recover() void wsrep_recover()
@ -1181,6 +1190,21 @@ int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_,
const TABLE_LIST* table_list) const TABLE_LIST* table_list)
{ {
int ret= 0; int ret= 0;
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
if (thd->wsrep_conflict_state == MUST_ABORT)
{
WSREP_INFO("thread: %lu, %s has been aborted due to multi-master conflict",
thd->thread_id, thd->query());
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
return WSREP_TRX_FAIL;
}
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
if (wsrep_debug && thd->mdl_context.has_locks())
{
WSREP_DEBUG("thread holds MDL locks at TI begin: %s %lu",
thd->query(), thd->thread_id);
}
if (thd->variables.wsrep_on && thd->wsrep_exec_mode==LOCAL_STATE) if (thd->variables.wsrep_on && thd->wsrep_exec_mode==LOCAL_STATE)
{ {
switch (wsrep_OSU_method_options) { switch (wsrep_OSU_method_options) {
@ -1236,24 +1260,28 @@ wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
{ {
mysql_mutex_unlock(&request_thd->LOCK_wsrep_thd); mysql_mutex_unlock(&request_thd->LOCK_wsrep_thd);
WSREP_MDL_LOG(DEBUG, "MDL conflict ", request_thd, granted_thd); WSREP_MDL_LOG(DEBUG, "MDL conflict ", request_thd, granted_thd);
ticket->wsrep_report(wsrep_debug);
mysql_mutex_lock(&granted_thd->LOCK_wsrep_thd); mysql_mutex_lock(&granted_thd->LOCK_wsrep_thd);
if (granted_thd->wsrep_exec_mode == TOTAL_ORDER || if (granted_thd->wsrep_exec_mode == TOTAL_ORDER ||
granted_thd->wsrep_exec_mode == REPL_RECV) granted_thd->wsrep_exec_mode == REPL_RECV)
{ {
WSREP_MDL_LOG(INFO, "MDL BF-BF conflict", request_thd, granted_thd); WSREP_MDL_LOG(INFO, "MDL BF-BF conflict", request_thd, granted_thd);
ticket->wsrep_report(true);
mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd); mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd);
ret = TRUE; ret = TRUE;
} }
else if (granted_thd->lex->sql_command == SQLCOM_FLUSH) else if (granted_thd->lex->sql_command == SQLCOM_FLUSH)
{ {
WSREP_DEBUG("mdl granted over FLUSH BF"); WSREP_DEBUG("mdl granted over FLUSH BF");
ticket->wsrep_report(wsrep_debug);
mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd); mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd);
ret = TRUE; ret = TRUE;
} }
else if (request_thd->lex->sql_command == SQLCOM_DROP_TABLE) else if (request_thd->lex->sql_command == SQLCOM_DROP_TABLE)
{ {
WSREP_DEBUG("DROP caused BF abort"); WSREP_DEBUG("DROP caused BF abort");
ticket->wsrep_report(wsrep_debug);
mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd); mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd);
wsrep_abort_thd((void*)request_thd, (void*)granted_thd, 1); wsrep_abort_thd((void*)request_thd, (void*)granted_thd, 1);
ret = FALSE; ret = FALSE;
@ -1261,6 +1289,7 @@ wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
else if (granted_thd->wsrep_query_state == QUERY_COMMITTING) else if (granted_thd->wsrep_query_state == QUERY_COMMITTING)
{ {
WSREP_DEBUG("mdl granted, but commiting thd abort scheduled"); WSREP_DEBUG("mdl granted, but commiting thd abort scheduled");
ticket->wsrep_report(wsrep_debug);
mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd); mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd);
wsrep_abort_thd((void*)request_thd, (void*)granted_thd, 1); wsrep_abort_thd((void*)request_thd, (void*)granted_thd, 1);
ret = FALSE; ret = FALSE;
@ -1268,6 +1297,7 @@ wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
else else
{ {
WSREP_MDL_LOG(DEBUG, "MDL conflict-> BF abort", request_thd, granted_thd); WSREP_MDL_LOG(DEBUG, "MDL conflict-> BF abort", request_thd, granted_thd);
ticket->wsrep_report(wsrep_debug);
mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd); mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd);
wsrep_abort_thd((void*)request_thd, (void*)granted_thd, 1); wsrep_abort_thd((void*)request_thd, (void*)granted_thd, 1);
ret = FALSE; ret = FALSE;

View File

@ -167,7 +167,7 @@ extern bool wsrep_sst_donor_update UPDATE_ARGS;
extern bool wsrep_slave_threads_check CHECK_ARGS; extern bool wsrep_slave_threads_check CHECK_ARGS;
extern bool wsrep_slave_threads_update UPDATE_ARGS; extern bool wsrep_slave_threads_update UPDATE_ARGS;
extern bool wsrep_init_first(); // initialize wsrep before storage extern bool wsrep_before_SE(); // initialize wsrep before storage
// engines (true) or after (false) // engines (true) or after (false)
extern int wsrep_init(); extern int wsrep_init();
extern void wsrep_deinit(); extern void wsrep_deinit();
@ -206,8 +206,8 @@ extern "C" void wsrep_thd_awake(THD *thd, my_bool signal);
/* wsrep initialization sequence at startup /* wsrep initialization sequence at startup
* @param first wsrep_init_first() value */ * @param first wsrep_before_SE() value */
extern void wsrep_init_startup(bool first); extern void wsrep_init_startup(bool before);
extern void wsrep_close_client_connections(my_bool wait_to_end); extern void wsrep_close_client_connections(my_bool wait_to_end);
extern int wsrep_wait_committing_connections_close(int wait_time); extern int wsrep_wait_committing_connections_close(int wait_time);
@ -258,11 +258,11 @@ extern wsrep_seqno_t wsrep_locked_seqno;
#define WSREP_LOG_CONFLICT_THD(thd, role) \ #define WSREP_LOG_CONFLICT_THD(thd, role) \
WSREP_LOG(sql_print_information, \ WSREP_LOG(sql_print_information, \
"%s: \n " \ "%s: \n " \
" THD: %lu, mode: %s, state: %s, conflict: %s, seqno: %ld\n " \ " THD: %lu, mode: %s, state: %s, conflict: %s, seqno: %lld\n " \
" SQL: %s", \ " SQL: %s", \
role, wsrep_thd_thread_id(thd), wsrep_thd_exec_mode_str(thd), \ role, wsrep_thd_thread_id(thd), wsrep_thd_exec_mode_str(thd), \
wsrep_thd_query_state_str(thd), \ wsrep_thd_query_state_str(thd), \
wsrep_thd_conflict_state_str(thd), wsrep_thd_trx_seqno(thd), \ wsrep_thd_conflict_state_str(thd), (long long)wsrep_thd_trx_seqno(thd), \
wsrep_thd_query(thd) \ wsrep_thd_query(thd) \
); );

View File

@ -164,10 +164,10 @@ bool wsrep_sst_donor_update (sys_var *self, THD* thd, enum_var_type type)
static wsrep_uuid_t cluster_uuid = WSREP_UUID_UNDEFINED; static wsrep_uuid_t cluster_uuid = WSREP_UUID_UNDEFINED;
bool wsrep_init_first() bool wsrep_before_SE()
{ {
return (wsrep_provider != NULL return (wsrep_provider != NULL
&& strcmp (wsrep_provider, WSREP_NONE) && strcmp (wsrep_provider, WSREP_NONE)
&& strcmp (wsrep_sst_method, WSREP_SST_SKIP) && strcmp (wsrep_sst_method, WSREP_SST_SKIP)
&& strcmp (wsrep_sst_method, WSREP_SST_MYSQLDUMP)); && strcmp (wsrep_sst_method, WSREP_SST_MYSQLDUMP));
} }

View File

@ -354,8 +354,9 @@ size_t guess_ip (char* buf, size_t buf_len)
// try to find the address of the first one // try to find the address of the first one
#if (TARGET_OS_LINUX == 1) #if (TARGET_OS_LINUX == 1)
const char cmd[] = "/sbin/ifconfig | " const char cmd[] = "/sbin/ifconfig | "
"grep -m1 -1 -E '^[a-z]?eth[0-9]' | tail -n 1 | " // "grep -m1 -1 -E '^[a-z]?eth[0-9]' | tail -n 1 | "
"awk '{ print $2 }' | awk -F : '{ print $2 }'"; "grep -E '^[[:space:]]+inet addr:' | grep -m1 -v 'inet addr:127' | "
"sed 's/:/ /' | awk '{ print $3 }'";
#elif defined(__sun__) #elif defined(__sun__)
const char cmd[] = "/sbin/ifconfig -a | " const char cmd[] = "/sbin/ifconfig -a | "
"/usr/gnu/bin/grep -m1 -1 -E 'net[0-9]:' | tail -n 1 | awk '{ print $2 }'"; "/usr/gnu/bin/grep -m1 -1 -E 'net[0-9]:' | tail -n 1 | awk '{ print $2 }'";

View File

@ -24,21 +24,28 @@
#include <cstdlib> #include <cstdlib>
#define WSREP_START_POSITION_ZERO "00000000-0000-0000-0000-000000000000:-1" #define WSREP_START_POSITION_ZERO "00000000-0000-0000-0000-000000000000:-1"
#define WSREP_CLUSTER_NAME "my_wsrep_cluster"
// trx history position to start with const char* wsrep_provider = 0;
const char* wsrep_start_position = WSREP_START_POSITION_ZERO; const char* wsrep_provider_options = 0;
const char* wsrep_provider = WSREP_NONE; const char* wsrep_cluster_address = 0;
const char* wsrep_provider_options = (const char*)my_memdup("", 1, MYF(MY_WME)); const char* wsrep_cluster_name = 0;
const char* wsrep_cluster_address = NULL; const char* wsrep_node_name = 0;
const char* wsrep_cluster_name = "my_wsrep_cluster"; static char node_address[256] = { 0, };
const char* wsrep_node_name = glob_hostname; const char* wsrep_node_address = node_address; // ???
static char node_address[256] = { 0, }; const char* wsrep_start_position = 0;
const char* wsrep_node_address = node_address;
ulong wsrep_OSU_method_options; ulong wsrep_OSU_method_options;
static int wsrep_thread_change = 0; static int wsrep_thread_change = 0;
int wsrep_init_vars() int wsrep_init_vars()
{ {
wsrep_provider = my_strdup(WSREP_NONE, MYF(MY_WME));
wsrep_provider_options= my_strdup("", MYF(MY_WME));
wsrep_cluster_address = my_strdup("", MYF(MY_WME));
wsrep_cluster_name = my_strdup(WSREP_CLUSTER_NAME, MYF(MY_WME));
wsrep_node_name = my_strdup("", MYF(MY_WME));
wsrep_start_position = my_strdup(WSREP_START_POSITION_ZERO, MYF(MY_WME));
global_system_variables.binlog_format=BINLOG_FORMAT_ROW; global_system_variables.binlog_format=BINLOG_FORMAT_ROW;
return 0; return 0;
} }
@ -152,13 +159,13 @@ void wsrep_start_position_init (const char* val)
return; return;
} }
wsrep_start_position = my_strdup(val, MYF(0));
wsrep_set_local_position (val); wsrep_set_local_position (val);
} }
static bool refresh_provider_options() static bool refresh_provider_options()
{ {
WSREP_DEBUG("refresh_provider_options: %s",
(wsrep_provider_options) ? wsrep_provider_options : "null");
char* opts= wsrep->options_get(wsrep); char* opts= wsrep->options_get(wsrep);
if (opts) if (opts)
{ {
@ -225,6 +232,8 @@ bool wsrep_provider_update (sys_var *self, THD* thd, enum_var_type type)
bool wsrep_on_saved= thd->variables.wsrep_on; bool wsrep_on_saved= thd->variables.wsrep_on;
thd->variables.wsrep_on= false; thd->variables.wsrep_on= false;
WSREP_DEBUG("wsrep_provider_update: %s", wsrep_provider);
wsrep_stop_replication(thd); wsrep_stop_replication(thd);
wsrep_deinit(); wsrep_deinit();
@ -250,12 +259,17 @@ bool wsrep_provider_update (sys_var *self, THD* thd, enum_var_type type)
void wsrep_provider_init (const char* value) void wsrep_provider_init (const char* value)
{ {
WSREP_DEBUG("wsrep_provider_init: %s -> %s",
(wsrep_provider) ? wsrep_provider : "null",
(value) ? value : "null");
if (NULL == value || wsrep_provider_verify (value)) if (NULL == value || wsrep_provider_verify (value))
{ {
WSREP_ERROR("Bad initial value for wsrep_provider: %s", WSREP_ERROR("Bad initial value for wsrep_provider: %s",
(value ? value : "")); (value ? value : ""));
return; return;
} }
if (wsrep_provider) my_free((void *)wsrep_provider);
wsrep_provider = my_strdup(value, MYF(0)); wsrep_provider = my_strdup(value, MYF(0));
} }
@ -327,9 +341,11 @@ bool wsrep_cluster_address_update (sys_var *self, THD* thd, enum_var_type type)
void wsrep_cluster_address_init (const char* value) void wsrep_cluster_address_init (const char* value)
{ {
if (wsrep_cluster_address && wsrep_cluster_address != value) WSREP_DEBUG("wsrep_cluster_address_init: %s -> %s",
my_free ((void*)wsrep_cluster_address); (wsrep_cluster_address) ? wsrep_cluster_address : "null",
(value) ? value : "null");
if (wsrep_cluster_address) my_free ((void*)wsrep_cluster_address);
wsrep_cluster_address = (value) ? my_strdup(value, MYF(0)) : NULL; wsrep_cluster_address = (value) ? my_strdup(value, MYF(0)) : NULL;
} }

View File

@ -2489,7 +2489,26 @@ next_rec:
return(NULL); return(NULL);
} }
#ifdef WITH_WSREP
dict_index_t*
wsrep_dict_foreign_find_index(
/*====================*/
dict_table_t* table, /*!< in: table */
const char** columns,/*!< in: array of column names */
ulint n_cols, /*!< in: number of columns */
dict_index_t* types_idx, /*!< in: NULL or an index to whose types the
column types must match */
ibool check_charsets,
/*!< in: whether to check charsets.
only has an effect if types_idx != NULL */
ulint check_null)
/*!< in: nonzero if none of the columns must
be declared NOT NULL */
{
return dict_foreign_find_index(
table, columns, n_cols, types_idx, check_charsets, check_null);
}
#endif /* WITH_WSREP */
/**********************************************************************//** /**********************************************************************//**
Find an index that is equivalent to the one passed in and is not marked Find an index that is equivalent to the one passed in and is not marked
for deletion. for deletion.

View File

@ -6980,6 +6980,15 @@ ha_innobase::rnd_pos(
} }
#ifdef WITH_WSREP #ifdef WITH_WSREP
extern "C" { extern "C" {
dict_index_t*
wsrep_dict_foreign_find_index(
dict_table_t* table,
const char** columns,
ulint n_cols,
dict_index_t* types_idx,
ibool check_charsets,
ulint check_null);
ulint ulint
wsrep_append_foreign_key( wsrep_append_foreign_key(
/*===========================*/ /*===========================*/
@ -6990,15 +6999,75 @@ wsrep_append_foreign_key(
ibool referenced, /*!<in: is check for referenced table */ ibool referenced, /*!<in: is check for referenced table */
ibool shared) /*!<in: is shared access */ ibool shared) /*!<in: is shared access */
{ {
ut_a(trx);
THD* thd = (THD*)trx->mysql_thd; THD* thd = (THD*)trx->mysql_thd;
ulint rcode = DB_SUCCESS; ulint rcode = DB_SUCCESS;
char cache_key[512] = {'\0'}; char cache_key[513] = {'\0'};
int cache_key_len; int cache_key_len;
if (!wsrep_on(trx->mysql_thd) || if (!wsrep_on(trx->mysql_thd) ||
wsrep_thd_exec_mode(thd) != LOCAL_STATE) wsrep_thd_exec_mode(thd) != LOCAL_STATE)
return DB_SUCCESS; return DB_SUCCESS;
if (!thd || !foreign ||
(!foreign->referenced_table && !foreign->foreign_table))
{
WSREP_INFO("FK: %s missing in: %s",
(!thd) ? "thread" :
((!foreign) ? "constraint" :
((!foreign->referenced_table) ?
"referenced table" : "foreign table")),
(thd && wsrep_thd_query(thd)) ?
wsrep_thd_query(thd) : "void");
return DB_ERROR;
}
if ( !((referenced) ?
foreign->referenced_table : foreign->foreign_table))
{
WSREP_DEBUG("pulling %s table into cache",
(referenced) ? "referenced" : "foreign");
mutex_enter(&(dict_sys->mutex));
if (referenced)
{
foreign->referenced_table =
dict_table_check_if_in_cache_low(
foreign->referenced_table_name_lookup);
foreign->referenced_index =
wsrep_dict_foreign_find_index(
foreign->referenced_table,
foreign->referenced_col_names,
foreign->n_fields,
foreign->foreign_index,
TRUE, FALSE);
}
else
{
foreign->foreign_table =
dict_table_check_if_in_cache_low(
foreign->foreign_table_name_lookup);
foreign->foreign_index =
wsrep_dict_foreign_find_index(
foreign->foreign_table,
foreign->foreign_col_names,
foreign->n_fields,
foreign->referenced_index,
TRUE, FALSE);
}
mutex_exit(&(dict_sys->mutex));
}
if ( !((referenced) ?
foreign->referenced_table : foreign->foreign_table))
{
WSREP_WARN("FK: %s missing in query: %s",
(!foreign->referenced_table) ?
"referenced table" : "foreign table",
(wsrep_thd_query(thd)) ?
wsrep_thd_query(thd) : "void");
return DB_ERROR;
}
byte key[WSREP_MAX_SUPPORTED_KEY_LENGTH+1]; byte key[WSREP_MAX_SUPPORTED_KEY_LENGTH+1];
ulint len = WSREP_MAX_SUPPORTED_KEY_LENGTH; ulint len = WSREP_MAX_SUPPORTED_KEY_LENGTH;
@ -7022,8 +7091,10 @@ wsrep_append_foreign_key(
WSREP_ERROR( WSREP_ERROR(
"FK key set failed: %lu (%lu %lu), index: %s %s, %s", "FK key set failed: %lu (%lu %lu), index: %s %s, %s",
rcode, referenced, shared, rcode, referenced, shared,
(index->name) ? index->name : "void index", (index && index->name) ? index->name :
(index->table_name) ? index->table_name : "void table", "void index",
(index && index->table_name) ? index->table_name :
"void table",
wsrep_thd_query(thd)); wsrep_thd_query(thd));
return rcode; return rcode;
} }
@ -7032,7 +7103,7 @@ wsrep_append_foreign_key(
((referenced) ? ((referenced) ?
foreign->referenced_table->name : foreign->referenced_table->name :
foreign->foreign_table->name) : foreign->foreign_table->name) :
foreign->foreign_table->name, 512); foreign->foreign_table->name, sizeof(cache_key) - 1);
cache_key_len = strlen(cache_key); cache_key_len = strlen(cache_key);
#ifdef WSREP_DEBUG_PRINT #ifdef WSREP_DEBUG_PRINT
ulint j; ulint j;
@ -7048,7 +7119,8 @@ wsrep_append_foreign_key(
*p = '\0'; *p = '\0';
} else { } else {
WSREP_WARN("unexpected foreign key table %s %s", WSREP_WARN("unexpected foreign key table %s %s",
foreign->referenced_table->name, foreign->foreign_table->name); foreign->referenced_table->name,
foreign->foreign_table->name);
} }
wsrep_key_part_t wkey_part[3]; wsrep_key_part_t wkey_part[3];
@ -12260,6 +12332,9 @@ wsrep_innobase_kill_one_trx(void *bf_thd_ptr, trx_t *bf_trx, trx_t *victim_trx,
case QUERY_COMMITTING: case QUERY_COMMITTING:
enum wsrep_status rcode; enum wsrep_status rcode;
WSREP_DEBUG("kill query for: %ld",
wsrep_thd_thread_id(thd));
wsrep_thd_awake(thd, signal);
WSREP_DEBUG("kill trx QUERY_COMMITTING for %llu", WSREP_DEBUG("kill trx QUERY_COMMITTING for %llu",
victim_trx->id); victim_trx->id);

View File

@ -2560,7 +2560,26 @@ next_rec:
return(NULL); return(NULL);
} }
#ifdef WITH_WSREP
dict_index_t*
wsrep_dict_foreign_find_index(
/*====================*/
dict_table_t* table, /*!< in: table */
const char** columns,/*!< in: array of column names */
ulint n_cols, /*!< in: number of columns */
dict_index_t* types_idx, /*!< in: NULL or an index to whose types the
column types must match */
ibool check_charsets,
/*!< in: whether to check charsets.
only has an effect if types_idx != NULL */
ulint check_null)
/*!< in: nonzero if none of the columns must
be declared NOT NULL */
{
return dict_foreign_find_index(
table, columns, n_cols, types_idx, check_charsets, check_null);
}
#endif /* WITH_WSREP */
/**********************************************************************//** /**********************************************************************//**
Find an index that is equivalent to the one passed in and is not marked Find an index that is equivalent to the one passed in and is not marked
for deletion. for deletion.

View File

@ -7810,6 +7810,15 @@ ha_innobase::rnd_pos(
} }
#ifdef WITH_WSREP #ifdef WITH_WSREP
extern "C" { extern "C" {
dict_index_t*
wsrep_dict_foreign_find_index(
dict_table_t* table,
const char** columns,
ulint n_cols,
dict_index_t* types_idx,
ibool check_charsets,
ulint check_null);
ulint ulint
wsrep_append_foreign_key( wsrep_append_foreign_key(
/*===========================*/ /*===========================*/
@ -7820,15 +7829,75 @@ wsrep_append_foreign_key(
ibool referenced, /*!<in: is check for referenced table */ ibool referenced, /*!<in: is check for referenced table */
ibool shared) /*!<in: is shared access */ ibool shared) /*!<in: is shared access */
{ {
ut_a(trx);
THD* thd = (THD*)trx->mysql_thd; THD* thd = (THD*)trx->mysql_thd;
ulint rcode = DB_SUCCESS; ulint rcode = DB_SUCCESS;
char cache_key[512] = {'\0'}; char cache_key[513] = {'\0'};
int cache_key_len; int cache_key_len;
if (!wsrep_on(trx->mysql_thd) || if (!wsrep_on(trx->mysql_thd) ||
wsrep_thd_exec_mode(thd) != LOCAL_STATE) wsrep_thd_exec_mode(thd) != LOCAL_STATE)
return DB_SUCCESS; return DB_SUCCESS;
if (!thd || !foreign ||
(!foreign->referenced_table && !foreign->foreign_table))
{
WSREP_INFO("FK: %s missing in: %s",
(!thd) ? "thread" :
((!foreign) ? "constraint" :
((!foreign->referenced_table) ?
"referenced table" : "foreign table")),
(thd && wsrep_thd_query(thd)) ?
wsrep_thd_query(thd) : "void");
return DB_ERROR;
}
if ( !((referenced) ?
foreign->referenced_table : foreign->foreign_table))
{
WSREP_DEBUG("pulling %s table into cache",
(referenced) ? "referenced" : "foreign");
mutex_enter(&(dict_sys->mutex));
if (referenced)
{
foreign->referenced_table =
dict_table_check_if_in_cache_low(
foreign->referenced_table_name_lookup);
foreign->referenced_index =
wsrep_dict_foreign_find_index(
foreign->referenced_table,
foreign->referenced_col_names,
foreign->n_fields,
foreign->foreign_index,
TRUE, FALSE);
}
else
{
foreign->foreign_table =
dict_table_check_if_in_cache_low(
foreign->foreign_table_name_lookup);
foreign->foreign_index =
wsrep_dict_foreign_find_index(
foreign->foreign_table,
foreign->foreign_col_names,
foreign->n_fields,
foreign->referenced_index,
TRUE, FALSE);
}
mutex_exit(&(dict_sys->mutex));
}
if ( !((referenced) ?
foreign->referenced_table : foreign->foreign_table))
{
WSREP_WARN("FK: %s missing in query: %s",
(!foreign->referenced_table) ?
"referenced table" : "foreign table",
(wsrep_thd_query(thd)) ?
wsrep_thd_query(thd) : "void");
return DB_ERROR;
}
byte key[WSREP_MAX_SUPPORTED_KEY_LENGTH+1]; byte key[WSREP_MAX_SUPPORTED_KEY_LENGTH+1];
ulint len = WSREP_MAX_SUPPORTED_KEY_LENGTH; ulint len = WSREP_MAX_SUPPORTED_KEY_LENGTH;
@ -7849,7 +7918,14 @@ wsrep_append_foreign_key(
&key[1], &len, rec, index, &key[1], &len, rec, index,
wsrep_protocol_version > 1); wsrep_protocol_version > 1);
if (rcode != DB_SUCCESS) { if (rcode != DB_SUCCESS) {
WSREP_ERROR("FK key set failed: %lu", rcode); WSREP_ERROR(
"FK key set failed: %lu (%lu %lu), index: %s %s, %s",
rcode, referenced, shared,
(index && index->name) ? index->name :
"void index",
(index && index->table_name) ? index->table_name :
"void table",
wsrep_thd_query(thd));
return rcode; return rcode;
} }
strncpy(cache_key, strncpy(cache_key,
@ -7857,7 +7933,7 @@ wsrep_append_foreign_key(
((referenced) ? ((referenced) ?
foreign->referenced_table->name : foreign->referenced_table->name :
foreign->foreign_table->name) : foreign->foreign_table->name) :
foreign->foreign_table->name, 512); foreign->foreign_table->name, sizeof(cache_key) - 1);
cache_key_len = strlen(cache_key); cache_key_len = strlen(cache_key);
#ifdef WSREP_DEBUG_PRINT #ifdef WSREP_DEBUG_PRINT
ulint j; ulint j;
@ -7873,7 +7949,8 @@ wsrep_append_foreign_key(
*p = '\0'; *p = '\0';
} else { } else {
WSREP_WARN("unexpected foreign key table %s %s", WSREP_WARN("unexpected foreign key table %s %s",
foreign->referenced_table->name, foreign->foreign_table->name); foreign->referenced_table->name,
foreign->foreign_table->name);
} }
wsrep_key_part_t wkey_part[3]; wsrep_key_part_t wkey_part[3];
@ -13259,6 +13336,9 @@ wsrep_innobase_kill_one_trx(trx_t *bf_trx, trx_t *victim_trx, ibool signal)
case QUERY_COMMITTING: case QUERY_COMMITTING:
enum wsrep_status rcode; enum wsrep_status rcode;
WSREP_DEBUG("kill query for: %ld",
wsrep_thd_thread_id(thd));
wsrep_thd_awake(thd, signal);
WSREP_DEBUG("kill trx QUERY_COMMITTING for %llu", WSREP_DEBUG("kill trx QUERY_COMMITTING for %llu",
victim_trx->id); victim_trx->id);