bzr merge -r3895..3903 lp:codership-mysql/5.5

This is just before 5.5.34 merge in wsrep-5.5 branch
This commit is contained in:
Seppo Jaakola 2013-11-26 22:09:14 +02:00
parent 4a11e84414
commit 6422d276fa
16 changed files with 315 additions and 207 deletions

View File

@ -92,34 +92,6 @@ static my_bool defaults_already_read= FALSE;
/* The only purpose of this global array is to hold full name of my.cnf /* The only purpose of this global array is to hold full name of my.cnf
* which seems to be otherwise unavailable */ * which seems to be otherwise unavailable */
char wsrep_defaults_file[FN_REFLEN + 10]={0,}; char wsrep_defaults_file[FN_REFLEN + 10]={0,};
/* Command-line only option to start a new wsrep service instance */
#define WSREP_NEW_CLUSTER1 "--wsrep-new-cluster"
#define WSREP_NEW_CLUSTER2 "--wsrep_new_cluster"
/* This one is set to true when --wsrep-new-cluster is found in the command
* line arguments */
my_bool wsrep_new_cluster= FALSE;
/* Finds and removes --wsrep-new-cluster from the arguments list.
* Returns true if found. */
static my_bool find_wsrep_new_cluster (int* argc, char* argv[])
{
my_bool ret= FALSE;
int i;
for (i= *argc - 1; i > 0; i--)
{
if (!strcmp(argv[i], WSREP_NEW_CLUSTER1) ||
!strcmp(argv[i], WSREP_NEW_CLUSTER2))
{
ret= TRUE;
*argc -= 1;
/* preserve the order of remaining arguments */
memmove(&argv[i], &argv[i + 1], (*argc - i)*sizeof(argv[i]));
argv[*argc]= NULL;
}
}
return ret;
}
#endif /* WITH_WREP */ #endif /* WITH_WREP */
/* Which directories are searched for options (and in which order) */ /* Which directories are searched for options (and in which order) */
@ -558,9 +530,6 @@ int my_load_defaults(const char *conf_file, const char **groups,
init_alloc_root(&alloc, 512, 0, MYF(0)); init_alloc_root(&alloc, 512, 0, MYF(0));
if ((dirs= init_default_directories(&alloc)) == NULL) if ((dirs= init_default_directories(&alloc)) == NULL)
goto err; goto err;
#ifdef WITH_WSREP
wsrep_new_cluster= find_wsrep_new_cluster(argc, argv[0]);
#endif /* WITH_WSREP */
/* /*
Check if the user doesn't want any default option processing Check if the user doesn't want any default option processing
--no-defaults is always the first option --no-defaults is always the first option

View File

@ -1303,11 +1303,7 @@ int ha_commit_trans(THD *thd, bool all)
Free resources and perform other cleanup even for 'empty' transactions. Free resources and perform other cleanup even for 'empty' transactions.
*/ */
if (is_real_trans) if (is_real_trans)
#ifdef WITH_WSREP
thd->transaction.cleanup(thd);
#else
thd->transaction.cleanup(); thd->transaction.cleanup();
#endif /* WITH_WSREP */
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@ -1388,6 +1384,7 @@ int ha_commit_trans(THD *thd, bool all)
status_var_increment(thd->status_var.ha_prepare_count); status_var_increment(thd->status_var.ha_prepare_count);
if (err) if (err)
#ifdef WITH_WSREP #ifdef WITH_WSREP
{
if (WSREP(thd) && ht->db_type== DB_TYPE_WSREP) if (WSREP(thd) && ht->db_type== DB_TYPE_WSREP)
{ {
error= 1; error= 1;
@ -1397,10 +1394,13 @@ int ha_commit_trans(THD *thd, bool all)
my_error(ER_LOCK_DEADLOCK, MYF(0), err); my_error(ER_LOCK_DEADLOCK, MYF(0), err);
} }
} }
else else
/* not wsrep hton, bail to native mysql behavior */ /* not wsrep hton, bail to native mysql behavior */
#endif #endif /* WITH_WSREP */
my_error(ER_ERROR_DURING_COMMIT, MYF(0), err); my_error(ER_ERROR_DURING_COMMIT, MYF(0), err);
#ifdef WITH_WSREP
}
#endif /* WITH_WSREP */
if (err) if (err)
goto err; goto err;
@ -1535,12 +1535,7 @@ commit_one_phase_2(THD *thd, bool all, THD_TRANS *trans, bool is_real_trans)
} }
/* Free resources and perform other cleanup even for 'empty' transactions. */ /* Free resources and perform other cleanup even for 'empty' transactions. */
if (is_real_trans) if (is_real_trans)
#ifdef WITH_WSREP thd->transaction.cleanup();
thd->transaction.cleanup(thd);
#else
thd->transaction.cleanup();
#endif /* WITH_WSREP */
DBUG_RETURN(error); DBUG_RETURN(error);
} }
@ -1614,11 +1609,7 @@ int ha_rollback_trans(THD *thd, bool all)
} }
/* Always cleanup. Even if nht==0. There may be savepoints. */ /* Always cleanup. Even if nht==0. There may be savepoints. */
if (is_real_trans) if (is_real_trans)
#ifdef WITH_WSREP thd->transaction.cleanup();
thd->transaction.cleanup(thd);
#else
thd->transaction.cleanup();
#endif /* WITH_WSREP */
if (all) if (all)
thd->transaction_rollback_request= FALSE; thd->transaction_rollback_request= FALSE;

View File

@ -548,20 +548,9 @@ IO_CACHE * get_trans_log(THD * thd)
bool wsrep_trans_cache_is_empty(THD *thd) bool wsrep_trans_cache_is_empty(THD *thd)
{ {
bool res= TRUE; binlog_cache_mngr *const cache_mngr=
if (thd_sql_command((const THD*) thd) != SQLCOM_SELECT)
res= FALSE;
else
{
binlog_cache_mngr *const cache_mngr=
(binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton); (binlog_cache_mngr*) thd_get_ha_data(thd, binlog_hton);
if (cache_mngr) return (!cache_mngr || cache_mngr->trx_cache.empty());
{
res= cache_mngr->trx_cache.empty();
}
}
return res;
} }
void thd_binlog_flush_pending_rows_event(THD *thd, bool stmt_end) void thd_binlog_flush_pending_rows_event(THD *thd, bool stmt_end)

View File

@ -73,6 +73,7 @@
#include "debug_sync.h" #include "debug_sync.h"
#ifdef WITH_WSREP #ifdef WITH_WSREP
#include "wsrep_mysqld.h" #include "wsrep_mysqld.h"
#include "wsrep_var.h"
#include "wsrep_thd.h" #include "wsrep_thd.h"
#include "wsrep_sst.h" #include "wsrep_sst.h"
ulong wsrep_running_threads = 0; // # of currently running wsrep threads ulong wsrep_running_threads = 0; // # of currently running wsrep threads
@ -5705,6 +5706,9 @@ int mysqld_main(int argc, char **argv)
return 1; return 1;
} }
#endif #endif
#ifdef WITH_WSREP
wsrep_filter_new_cluster (&argc, argv);
#endif /* WITH_WSREP */
orig_argc= argc; orig_argc= argc;
orig_argv= argv; orig_argv= argv;

View File

@ -832,7 +832,7 @@ extern "C" const char *wsrep_thd_exec_mode_str(THD *thd)
(!thd) ? "void" : (!thd) ? "void" :
(thd->wsrep_exec_mode == LOCAL_STATE) ? "local" : (thd->wsrep_exec_mode == LOCAL_STATE) ? "local" :
(thd->wsrep_exec_mode == REPL_RECV) ? "applier" : (thd->wsrep_exec_mode == REPL_RECV) ? "applier" :
(thd->wsrep_exec_mode == TOTAL_ORDER) ? "total order" : (thd->wsrep_exec_mode == TOTAL_ORDER) ? "total order" :
(thd->wsrep_exec_mode == LOCAL_COMMIT) ? "local commit" : "void"; (thd->wsrep_exec_mode == LOCAL_COMMIT) ? "local commit" : "void";
} }
@ -896,7 +896,7 @@ extern "C" my_thread_id wsrep_thd_thread_id(THD *thd)
} }
extern "C" wsrep_seqno_t wsrep_thd_trx_seqno(THD *thd) extern "C" wsrep_seqno_t wsrep_thd_trx_seqno(THD *thd)
{ {
return (thd) ? thd->wsrep_trx_meta.gtid.seqno : -1; return (thd) ? thd->wsrep_trx_meta.gtid.seqno : WSREP_SEQNO_UNDEFINED;
} }
extern "C" query_id_t wsrep_thd_query_id(THD *thd) extern "C" query_id_t wsrep_thd_query_id(THD *thd)
{ {
@ -1145,7 +1145,6 @@ THD::THD()
wsrep_ws_handle.opaque = NULL; wsrep_ws_handle.opaque = NULL;
wsrep_retry_counter = 0; wsrep_retry_counter = 0;
wsrep_PA_safe = true; wsrep_PA_safe = true;
wsrep_seqno_changed = false;
wsrep_retry_query = NULL; wsrep_retry_query = NULL;
wsrep_retry_query_len = 0; wsrep_retry_query_len = 0;
wsrep_retry_command = COM_CONNECT; wsrep_retry_command = COM_CONNECT;
@ -1552,7 +1551,6 @@ void THD::init(void)
wsrep_retry_counter= 0; wsrep_retry_counter= 0;
wsrep_rli= NULL; wsrep_rli= NULL;
wsrep_PA_safe= true; wsrep_PA_safe= true;
wsrep_seqno_changed= false;
wsrep_consistency_check = NO_CONSISTENCY_CHECK; wsrep_consistency_check = NO_CONSISTENCY_CHECK;
wsrep_mysql_replicated = 0; wsrep_mysql_replicated = 0;

View File

@ -1038,9 +1038,6 @@ struct st_savepoint {
/** State of metadata locks before this savepoint was set. */ /** State of metadata locks before this savepoint was set. */
MDL_savepoint mdl_savepoint; MDL_savepoint mdl_savepoint;
}; };
#ifdef WITH_WSREP
void wsrep_cleanup_transaction(THD *thd); // THD.transactions.cleanup calls it
#endif
enum xa_states {XA_NOTR=0, XA_ACTIVE, XA_IDLE, XA_PREPARED, XA_ROLLBACK_ONLY}; enum xa_states {XA_NOTR=0, XA_ACTIVE, XA_IDLE, XA_PREPARED, XA_ROLLBACK_ONLY};
extern const char *xa_state_names[]; extern const char *xa_state_names[];
@ -1984,11 +1981,7 @@ public:
*/ */
CHANGED_TABLE_LIST* changed_tables; CHANGED_TABLE_LIST* changed_tables;
MEM_ROOT mem_root; // Transaction-life memory allocation pool MEM_ROOT mem_root; // Transaction-life memory allocation pool
#ifdef WITH_WSREP
void cleanup(THD *thd)
#else
void cleanup() void cleanup()
#endif
{ {
DBUG_ENTER("thd::cleanup"); DBUG_ENTER("thd::cleanup");
changed_tables= 0; changed_tables= 0;
@ -2002,11 +1995,6 @@ public:
if (!xid_state.rm_error) if (!xid_state.rm_error)
xid_state.xid.null(); xid_state.xid.null();
free_root(&mem_root,MYF(MY_KEEP_PREALLOC)); free_root(&mem_root,MYF(MY_KEEP_PREALLOC));
#ifdef WITH_WSREP
// Todo: convert into a plugin method
// wsrep's post-commit. LOCAL_COMMIT designates wsrep's commit was ok
if (WSREP(thd)) wsrep_cleanup_transaction(thd);
#endif /* WITH_WSREP */
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
my_bool is_active() my_bool is_active()
@ -2560,7 +2548,6 @@ public:
Relay_log_info* wsrep_rli; Relay_log_info* wsrep_rli;
bool wsrep_converted_lock_session; bool wsrep_converted_lock_session;
wsrep_ws_handle_t wsrep_ws_handle; wsrep_ws_handle_t wsrep_ws_handle;
bool wsrep_seqno_changed;
#ifdef WSREP_PROC_INFO #ifdef WSREP_PROC_INFO
char wsrep_info[128]; /* string for dynamic proc info */ char wsrep_info[128]; /* string for dynamic proc info */
#endif /* WSREP_PROC_INFO */ #endif /* WSREP_PROC_INFO */

View File

@ -4629,7 +4629,20 @@ end_with_restore_list:
thd->killed= KILL_CONNECTION; thd->killed= KILL_CONNECTION;
thd->print_aborted_warning(3, "RELEASE"); thd->print_aborted_warning(3, "RELEASE");
} }
#ifdef WITH_WSREP
if (WSREP(thd)) {
if (thd->wsrep_conflict_state == NO_CONFLICT ||
thd->wsrep_conflict_state == REPLAYING)
{
my_ok(thd);
}
} else {
#endif /* WITH_WSREP */
my_ok(thd); my_ok(thd);
#ifdef WITH_WSREP
}
#endif /* WITH_WSREP */
break; break;
} }
case SQLCOM_ROLLBACK: case SQLCOM_ROLLBACK:
@ -4664,17 +4677,15 @@ end_with_restore_list:
/* Disconnect the current client connection. */ /* Disconnect the current client connection. */
if (tx_release) if (tx_release)
thd->killed= KILL_CONNECTION; thd->killed= KILL_CONNECTION;
#ifdef WITH_WSREP #ifdef WITH_WSREP
if (WSREP(thd)) { if (WSREP(thd)) {
if (thd->wsrep_conflict_state == NO_CONFLICT || if (thd->wsrep_conflict_state == NO_CONFLICT) {
thd->wsrep_conflict_state == REPLAYING)
{
my_ok(thd); my_ok(thd);
} }
} else { } else {
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
my_ok(thd); my_ok(thd);
#ifdef WITH_WSREP #ifdef WITH_WSREP
} }
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
break; break;
@ -5156,7 +5167,7 @@ create_sp_error:
if (check_table_access(thd, DROP_ACL, all_tables, FALSE, UINT_MAX, FALSE)) if (check_table_access(thd, DROP_ACL, all_tables, FALSE, UINT_MAX, FALSE))
goto error; goto error;
/* Conditionally writes to binlog. */ /* Conditionally writes to binlog. */
WSREP_TO_ISOLATION_BEGIN(NULL, NULL, NULL) WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
res= mysql_drop_view(thd, first_table, thd->lex->drop_mode); res= mysql_drop_view(thd, first_table, thd->lex->drop_mode);
break; break;
} }

View File

@ -145,6 +145,9 @@ bool trans_begin(THD *thd, uint flags)
~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY);
DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS")); DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS"));
res= test(ha_commit_trans(thd, TRUE)); res= test(ha_commit_trans(thd, TRUE));
#ifdef WITH_WSREP
wsrep_post_commit(thd, TRUE);
#endif /* WITH_WSREP */
} }
thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG); thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
@ -226,6 +229,9 @@ bool trans_commit(THD *thd)
~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY);
DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS")); DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS"));
res= ha_commit_trans(thd, TRUE); res= ha_commit_trans(thd, TRUE);
#ifdef WITH_WSREP
wsrep_post_commit(thd, TRUE);
#endif /* WITH_WSREP */
/* /*
if res is non-zero, then ha_commit_trans has rolled back the if res is non-zero, then ha_commit_trans has rolled back the
transaction, so the hooks for rollback will be called. transaction, so the hooks for rollback will be called.
@ -274,6 +280,9 @@ bool trans_commit_implicit(THD *thd)
~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY); ~(SERVER_STATUS_IN_TRANS | SERVER_STATUS_IN_TRANS_READONLY);
DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS")); DBUG_PRINT("info", ("clearing SERVER_STATUS_IN_TRANS"));
res= test(ha_commit_trans(thd, TRUE)); res= test(ha_commit_trans(thd, TRUE));
#ifdef WITH_WSREP
wsrep_post_commit(thd, TRUE);
#endif /* WITH_WSREP */
} }
thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG); thd->variables.option_bits&= ~(OPTION_BEGIN | OPTION_KEEP_LOG);
@ -362,10 +371,14 @@ bool trans_commit_stmt(THD *thd)
#endif /* WITH_WSREP */ #endif /* WITH_WSREP */
res= ha_commit_trans(thd, FALSE); res= ha_commit_trans(thd, FALSE);
if (! thd->in_active_multi_stmt_transaction()) if (! thd->in_active_multi_stmt_transaction())
#ifdef WITH_WSREP
{ {
#endif /* WITH_WSREP */
thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation; thd->tx_isolation= (enum_tx_isolation) thd->variables.tx_isolation;
thd->tx_read_only= thd->variables.tx_read_only; #ifdef WITH_WSREP
wsrep_post_commit(thd, FALSE);
} }
#endif /* WITH_WSREP */
} }
/* /*
@ -781,6 +794,9 @@ bool trans_xa_commit(THD *thd)
int r= ha_commit_trans(thd, TRUE); int r= ha_commit_trans(thd, TRUE);
if ((res= test(r))) if ((res= test(r)))
my_error(r == 1 ? ER_XA_RBROLLBACK : ER_XAER_RMERR, MYF(0)); my_error(r == 1 ? ER_XA_RBROLLBACK : ER_XAER_RMERR, MYF(0));
#ifdef WITH_WSREP
wsrep_post_commit(thd, TRUE);
#endif /* WITH_WSREP */
} }
else if (xa_state == XA_PREPARED && thd->lex->xa_opt == XA_NONE) else if (xa_state == XA_PREPARED && thd->lex->xa_opt == XA_NONE)
{ {

View File

@ -33,34 +33,16 @@ enum wsrep_trx_status wsrep_run_wsrep_commit(THD *thd, handlerton *hton,
bool all); bool all);
/* /*
a post-commit cleanup on behalf of wsrep. Can't be a part of hton struct. Cleanup after local transaction commit/rollback, replay or TOI.
Is called by THD::transactions.cleanup()
*/ */
void wsrep_cleanup_transaction(THD *thd) void wsrep_cleanup_transaction(THD *thd)
{ {
if (thd->thread_id == 0) return; if (wsrep_emulate_bin_log) thd_binlog_trx_reset(thd);
if (thd->wsrep_exec_mode == LOCAL_COMMIT) thd->wsrep_ws_handle.trx_id= WSREP_UNDEFINED_TRX_ID;
{ thd->wsrep_trx_meta.gtid= WSREP_GTID_UNDEFINED;
if (thd->variables.wsrep_on && thd->wsrep_trx_meta.depends_on= WSREP_SEQNO_UNDEFINED;
thd->wsrep_conflict_state != MUST_REPLAY) thd->wsrep_exec_mode= LOCAL_STATE;
{ return;
if (thd->wsrep_seqno_changed)
{
if (wsrep->post_commit(wsrep, &thd->wsrep_ws_handle))
{
DBUG_PRINT("wsrep", ("set committed fail"));
WSREP_WARN("set committed fail: %llu %d",
(long long)thd->real_id, thd->get_stmt_da()->status());
}
}
//else
//WSREP_DEBUG("no trx handle for %s", thd->query());
thd_binlog_trx_reset(thd);
thd->wsrep_seqno_changed = false;
}
thd->wsrep_exec_mode= LOCAL_STATE;
}
thd->wsrep_ws_handle.trx_id = WSREP_UNDEFINED_TRX_ID;
} }
/* /*
@ -68,9 +50,25 @@ void wsrep_cleanup_transaction(THD *thd)
*/ */
handlerton *wsrep_hton; handlerton *wsrep_hton;
/*
Registers wsrep hton at commit time if transaction has registered htons
for supported engine types.
Hton should not be registered for TOTAL_ORDER operations.
Registration is needed for both LOCAL_MODE and REPL_RECV transactions to run
commit in 2pc so that wsrep position gets properly recorded in storage
engines.
Note that all hton calls should immediately return for threads that are
in REPL_RECV mode as their states are controlled by wsrep appliers or
replaying code. Only threads in LOCAL_MODE should run wsrep callbacks
from hton methods.
*/
void wsrep_register_hton(THD* thd, bool all) void wsrep_register_hton(THD* thd, bool all)
{ {
if (thd->wsrep_exec_mode == LOCAL_STATE) if (thd->wsrep_exec_mode != TOTAL_ORDER)
{ {
THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt; THD_TRANS *trans=all ? &thd->transaction.all : &thd->transaction.stmt;
for (Ha_trx_info *i= trans->ha_list; WSREP(thd) && i; i = i->next()) for (Ha_trx_info *i= trans->ha_list; WSREP(thd) && i; i = i->next())
@ -90,6 +88,25 @@ void wsrep_register_hton(THD* thd, bool all)
} }
} }
/*
Calls wsrep->post_commit() for locally executed transactions that have
got seqno from provider (must commit) and don't require replaying.
*/
void wsrep_post_commit(THD* thd, bool all)
{
if (thd->wsrep_exec_mode == LOCAL_COMMIT)
{
DBUG_ASSERT(thd->wsrep_trx_meta.gtid.seqno != WSREP_SEQNO_UNDEFINED);
if (wsrep->post_commit(wsrep, &thd->wsrep_ws_handle))
{
DBUG_PRINT("wsrep", ("set committed fail"));
WSREP_WARN("set committed fail: %llu %d",
(long long)thd->real_id, thd->get_stmt_da()->status());
}
wsrep_cleanup_transaction(thd);
}
}
/* /*
wsrep exploits binlog's caches even if binlogging itself is not wsrep exploits binlog's caches even if binlogging itself is not
activated. In such case connection close needs calling activated. In such case connection close needs calling
@ -101,7 +118,13 @@ static int
wsrep_close_connection(handlerton* hton, THD* thd) wsrep_close_connection(handlerton* hton, THD* thd)
{ {
DBUG_ENTER("wsrep_close_connection"); DBUG_ENTER("wsrep_close_connection");
if (thd_get_ha_data(thd, binlog_hton) != NULL)
if (thd->wsrep_exec_mode == REPL_RECV)
{
DBUG_RETURN(0);
}
if (wsrep_emulate_bin_log && thd_get_ha_data(thd, binlog_hton) != NULL)
binlog_hton->close_connection (binlog_hton, thd); binlog_hton->close_connection (binlog_hton, thd);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@ -117,10 +140,17 @@ wsrep_close_connection(handlerton* hton, THD* thd)
*/ */
static int wsrep_prepare(handlerton *hton, THD *thd, bool all) static int wsrep_prepare(handlerton *hton, THD *thd, bool all)
{ {
#ifndef DBUG_OFF
//wsrep_seqno_t old = thd->wsrep_trx_seqno;
#endif
DBUG_ENTER("wsrep_prepare"); DBUG_ENTER("wsrep_prepare");
if (thd->wsrep_exec_mode == REPL_RECV)
{
DBUG_RETURN(0);
}
DBUG_ASSERT(thd->ha_data[wsrep_hton->slot].ha_info[all].is_trx_read_write());
DBUG_ASSERT(thd->wsrep_exec_mode == LOCAL_STATE);
DBUG_ASSERT(thd->wsrep_trx_meta.gtid.seqno == WSREP_SEQNO_UNDEFINED);
if ((all || if ((all ||
!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) && !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
(thd->variables.wsrep_on && !wsrep_trans_cache_is_empty(thd))) (thd->variables.wsrep_on && !wsrep_trans_cache_is_empty(thd)))
@ -128,9 +158,6 @@ static int wsrep_prepare(handlerton *hton, THD *thd, bool all)
switch (wsrep_run_wsrep_commit(thd, hton, all)) switch (wsrep_run_wsrep_commit(thd, hton, all))
{ {
case WSREP_TRX_OK: case WSREP_TRX_OK:
// DBUG_ASSERT(thd->wsrep_trx_seqno > old ||
// thd->wsrep_exec_mode == REPL_RECV ||
// thd->wsrep_exec_mode == TOTAL_ORDER);
break; break;
case WSREP_TRX_ROLLBACK: case WSREP_TRX_ROLLBACK:
case WSREP_TRX_ERROR: case WSREP_TRX_ERROR:
@ -142,12 +169,26 @@ static int wsrep_prepare(handlerton *hton, THD *thd, bool all)
static int wsrep_savepoint_set(handlerton *hton, THD *thd, void *sv) static int wsrep_savepoint_set(handlerton *hton, THD *thd, void *sv)
{ {
DBUG_ENTER("wsrep_savepoint_set");
if (thd->wsrep_exec_mode == REPL_RECV)
{
DBUG_RETURN(0);
}
if (!wsrep_emulate_bin_log) return 0; if (!wsrep_emulate_bin_log) return 0;
int rcode = binlog_hton->savepoint_set(binlog_hton, thd, sv); int rcode = binlog_hton->savepoint_set(binlog_hton, thd, sv);
return rcode; return rcode;
} }
static int wsrep_savepoint_rollback(handlerton *hton, THD *thd, void *sv) static int wsrep_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
{ {
DBUG_ENTER("wsrep_savepoint_rollback");
if (thd->wsrep_exec_mode == REPL_RECV)
{
DBUG_RETURN(0);
}
if (!wsrep_emulate_bin_log) return 0; if (!wsrep_emulate_bin_log) return 0;
int rcode = binlog_hton->savepoint_rollback(binlog_hton, thd, sv); int rcode = binlog_hton->savepoint_rollback(binlog_hton, thd, sv);
return rcode; return rcode;
@ -156,6 +197,12 @@ static int wsrep_savepoint_rollback(handlerton *hton, THD *thd, void *sv)
static int wsrep_rollback(handlerton *hton, THD *thd, bool all) static int wsrep_rollback(handlerton *hton, THD *thd, bool all)
{ {
DBUG_ENTER("wsrep_rollback"); DBUG_ENTER("wsrep_rollback");
if (thd->wsrep_exec_mode == REPL_RECV)
{
DBUG_RETURN(0);
}
mysql_mutex_lock(&thd->LOCK_wsrep_thd); mysql_mutex_lock(&thd->LOCK_wsrep_thd);
if ((all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) && if ((all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
(thd->variables.wsrep_on && thd->wsrep_conflict_state != MUST_REPLAY)) (thd->variables.wsrep_on && thd->wsrep_conflict_state != MUST_REPLAY))
@ -166,25 +213,54 @@ static int wsrep_rollback(handlerton *hton, THD *thd, bool all)
WSREP_ERROR("settting rollback fail: thd: %llu SQL: %s", WSREP_ERROR("settting rollback fail: thd: %llu SQL: %s",
(long long)thd->real_id, thd->query()); (long long)thd->real_id, thd->query());
} }
wsrep_cleanup_transaction(thd);
} }
int rcode = 0;
if (!wsrep_emulate_bin_log)
{
if (all) thd_binlog_trx_reset(thd);
}
mysql_mutex_unlock(&thd->LOCK_wsrep_thd); mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
DBUG_RETURN(rcode); DBUG_RETURN(0);
} }
int wsrep_commit(handlerton *hton, THD *thd, bool all) int wsrep_commit(handlerton *hton, THD *thd, bool all)
{ {
DBUG_ENTER("wsrep_commit"); DBUG_ENTER("wsrep_commit");
if (thd->wsrep_exec_mode == REPL_RECV)
{
DBUG_RETURN(0);
}
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
if ((all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) &&
(thd->variables.wsrep_on && thd->wsrep_conflict_state != MUST_REPLAY))
{
if (thd->wsrep_exec_mode == LOCAL_COMMIT)
{
DBUG_ASSERT(thd->ha_data[wsrep_hton->slot].ha_info[all].is_trx_read_write());
/*
Call to wsrep->post_commit() (moved to wsrep_post_commit()) must
be done only after commit has done for all involved htons.
*/
DBUG_PRINT("wsrep", ("commit"));
}
else
{
/*
Transaction didn't go through wsrep->pre_commit() so just roll back
possible changes to clean state.
*/
if (wsrep->post_rollback(wsrep, &thd->wsrep_ws_handle))
{
DBUG_PRINT("wsrep", ("setting rollback fail"));
WSREP_ERROR("settting rollback fail: thd: %llu SQL: %s",
(long long)thd->real_id, thd->query());
}
wsrep_cleanup_transaction(thd);
}
}
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
extern Rpl_filter* binlog_filter; extern Rpl_filter* binlog_filter;
extern my_bool opt_log_slave_updates; extern my_bool opt_log_slave_updates;
@ -310,9 +386,6 @@ wsrep_run_wsrep_commit(THD *thd, handlerton *hton, bool all)
if (data_len == 0) if (data_len == 0)
{ {
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
thd->wsrep_exec_mode = LOCAL_COMMIT;
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
if (thd->get_stmt_da()->is_ok() && if (thd->get_stmt_da()->is_ok() &&
thd->get_stmt_da()->affected_rows() > 0 && thd->get_stmt_da()->affected_rows() > 0 &&
!binlog_filter->is_on()) !binlog_filter->is_on())
@ -354,14 +427,13 @@ wsrep_run_wsrep_commit(THD *thd, handlerton *hton, bool all)
0ULL : WSREP_FLAG_PA_UNSAFE), 0ULL : WSREP_FLAG_PA_UNSAFE),
&thd->wsrep_trx_meta); &thd->wsrep_trx_meta);
switch (rcode) if (rcode == WSREP_TRX_MISSING) {
{
case WSREP_TRX_MISSING:
WSREP_WARN("Transaction missing in provider, thd: %ld, SQL: %s", WSREP_WARN("Transaction missing in provider, thd: %ld, SQL: %s",
thd->thread_id, thd->query()); thd->thread_id, thd->query());
rcode = WSREP_OK; rcode = WSREP_TRX_FAIL;
break; } else if (rcode == WSREP_BF_ABORT) {
case WSREP_BF_ABORT: WSREP_DEBUG("thd %lu seqno %lld BF aborted by provider, will replay",
thd->thread_id, (long long)thd->wsrep_trx_meta.gtid.seqno);
mysql_mutex_lock(&thd->LOCK_wsrep_thd); mysql_mutex_lock(&thd->LOCK_wsrep_thd);
thd->wsrep_conflict_state = MUST_REPLAY; thd->wsrep_conflict_state = MUST_REPLAY;
mysql_mutex_unlock(&thd->LOCK_wsrep_thd); mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
@ -370,10 +442,6 @@ wsrep_run_wsrep_commit(THD *thd, handlerton *hton, bool all)
WSREP_DEBUG("replaying increased: %d, thd: %lu", WSREP_DEBUG("replaying increased: %d, thd: %lu",
wsrep_replaying, thd->thread_id); wsrep_replaying, thd->thread_id);
mysql_mutex_unlock(&LOCK_wsrep_replaying); mysql_mutex_unlock(&LOCK_wsrep_replaying);
break;
default:
thd->wsrep_seqno_changed = true;
break;
} }
} else { } else {
WSREP_ERROR("I/O error reading from thd's binlog iocache: " WSREP_ERROR("I/O error reading from thd's binlog iocache: "
@ -385,7 +453,24 @@ wsrep_run_wsrep_commit(THD *thd, handlerton *hton, bool all)
mysql_mutex_lock(&thd->LOCK_wsrep_thd); mysql_mutex_lock(&thd->LOCK_wsrep_thd);
switch(rcode) { switch(rcode) {
case 0: case 0:
thd->wsrep_exec_mode = LOCAL_COMMIT; /*
About MUST_ABORT: We assume that even if thd conflict state was set
to MUST_ABORT, underlying transaction was not rolled back or marked
as deadlock victim in QUERY_COMMITTING state. Conflict state is
set to NO_CONFLICT and commit proceeds as usual.
*/
if (thd->wsrep_conflict_state == MUST_ABORT)
thd->wsrep_conflict_state= NO_CONFLICT;
if (thd->wsrep_conflict_state != NO_CONFLICT)
{
WSREP_WARN("thd %lu seqno %lld: conflict state %d after post commit",
thd->thread_id,
(long long)thd->wsrep_trx_meta.gtid.seqno,
thd->wsrep_conflict_state);
}
thd->wsrep_exec_mode= LOCAL_COMMIT;
DBUG_ASSERT(thd->wsrep_trx_meta.gtid.seqno != WSREP_SEQNO_UNDEFINED);
/* Override XID iff it was generated by mysql */ /* Override XID iff it was generated by mysql */
if (thd->transaction.xid_state.xid.get_my_xid()) if (thd->transaction.xid_state.xid.get_my_xid())
{ {
@ -394,10 +479,10 @@ wsrep_run_wsrep_commit(THD *thd, handlerton *hton, bool all)
thd->wsrep_trx_meta.gtid.seqno); thd->wsrep_trx_meta.gtid.seqno);
} }
DBUG_PRINT("wsrep", ("replicating commit success")); DBUG_PRINT("wsrep", ("replicating commit success"));
break; break;
case WSREP_TRX_FAIL:
case WSREP_BF_ABORT: case WSREP_BF_ABORT:
DBUG_ASSERT(thd->wsrep_trx_meta.gtid.seqno != WSREP_SEQNO_UNDEFINED);
case WSREP_TRX_FAIL:
WSREP_DEBUG("commit failed for reason: %d", rcode); WSREP_DEBUG("commit failed for reason: %d", rcode);
DBUG_PRINT("wsrep", ("replicating commit fail")); DBUG_PRINT("wsrep", ("replicating commit fail"));

View File

@ -697,8 +697,36 @@ void wsrep_stop_replication(THD *thd)
return; return;
} }
/* This one is set to true when --wsrep-new-cluster is found in the command
* line arguments */
static my_bool wsrep_new_cluster= FALSE;
#define WSREP_NEW_CLUSTER "--wsrep-new-cluster"
/* Finds and hides --wsrep-new-cluster from the arguments list
* by moving it to the end of the list and decrementing argument count */
void wsrep_filter_new_cluster (int* argc, char* argv[])
{
int i;
for (i= *argc - 1; i > 0; i--)
{
/* make a copy of the argument to convert possible underscores to hyphens.
* the copy need not to be longer than WSREP_NEW_CLUSTER option */
char arg[sizeof(WSREP_NEW_CLUSTER) + 2]= { 0, };
strncpy(arg, argv[i], sizeof(arg) - 1);
char* underscore;
while (NULL != (underscore= strchr(arg, '_'))) *underscore= '-';
extern my_bool wsrep_new_cluster; if (!strcmp(arg, WSREP_NEW_CLUSTER))
{
wsrep_new_cluster= TRUE;
*argc -= 1;
/* preserve the order of remaining arguments AND
* preserve the original argument pointers - just in case */
char* wnc= argv[i];
memmove(&argv[i], &argv[i + 1], (*argc - i)*sizeof(argv[i]));
argv[*argc]= wnc; /* this will be invisible to the rest of the program */
}
}
}
bool wsrep_start_replication() bool wsrep_start_replication()
{ {
@ -1187,15 +1215,16 @@ static int wsrep_TOI_begin(THD *thd, char *db_, char *table_,
static void wsrep_TOI_end(THD *thd) { static void wsrep_TOI_end(THD *thd) {
wsrep_status_t ret; wsrep_status_t ret;
wsrep_to_isolation--; wsrep_to_isolation--;
WSREP_DEBUG("TO END: %lld, %d : %s", (long long)wsrep_thd_trx_seqno(thd), WSREP_DEBUG("TO END: %lld, %d : %s", (long long)wsrep_thd_trx_seqno(thd),
thd->wsrep_exec_mode, (thd->query()) ? thd->query() : "void") thd->wsrep_exec_mode, (thd->query()) ? thd->query() : "void");
if (WSREP_OK == (ret = wsrep->to_execute_end(wsrep, thd->thread_id))) { if (WSREP_OK == (ret = wsrep->to_execute_end(wsrep, thd->thread_id))) {
WSREP_DEBUG("TO END: %lld", (long long)wsrep_thd_trx_seqno(thd)); WSREP_DEBUG("TO END: %lld", (long long)wsrep_thd_trx_seqno(thd));
} }
else { else {
WSREP_WARN("TO isolation end failed for: %d, sql: %s", WSREP_WARN("TO isolation end failed for: %d, sql: %s",
ret, (thd->query()) ? thd->query() : "void"); ret, (thd->query()) ? thd->query() : "void");
} }
} }
static int wsrep_RSU_begin(THD *thd, char *db_, char *table_) static int wsrep_RSU_begin(THD *thd, char *db_, char *table_)
@ -1266,14 +1295,20 @@ static void wsrep_RSU_end(THD *thd)
return; return;
} }
thd->variables.wsrep_on = 1; thd->variables.wsrep_on = 1;
return;
} }
int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_, int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_,
const TABLE_LIST* table_list) const TABLE_LIST* table_list)
{ {
/*
No isolation for applier or replaying threads.
*/
if (thd->wsrep_exec_mode == REPL_RECV) return 0;
int ret= 0; int ret= 0;
mysql_mutex_lock(&thd->LOCK_wsrep_thd); mysql_mutex_lock(&thd->LOCK_wsrep_thd);
if (thd->wsrep_conflict_state == MUST_ABORT) if (thd->wsrep_conflict_state == MUST_ABORT)
{ {
WSREP_INFO("thread: %lu, %s has been aborted due to multi-master conflict", WSREP_INFO("thread: %lu, %s has been aborted due to multi-master conflict",
@ -1283,6 +1318,9 @@ int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_,
} }
mysql_mutex_unlock(&thd->LOCK_wsrep_thd); mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
DBUG_ASSERT(thd->wsrep_exec_mode == LOCAL_STATE);
DBUG_ASSERT(thd->wsrep_trx_meta.gtid.seqno == WSREP_SEQNO_UNDEFINED);
if (wsrep_debug && thd->mdl_context.has_locks()) if (wsrep_debug && thd->mdl_context.has_locks())
{ {
WSREP_DEBUG("thread holds MDL locks at TI begin: %s %lu", WSREP_DEBUG("thread holds MDL locks at TI begin: %s %lu",
@ -1309,14 +1347,16 @@ int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_,
return ret; return ret;
} }
void wsrep_to_isolation_end(THD *thd) { void wsrep_to_isolation_end(THD *thd)
if (thd->wsrep_exec_mode==TOTAL_ORDER) {
if (thd->wsrep_exec_mode == TOTAL_ORDER)
{ {
switch(wsrep_OSU_method_options) switch(wsrep_OSU_method_options)
{ {
case WSREP_OSU_TOI: return wsrep_TOI_end(thd); case WSREP_OSU_TOI: wsrep_TOI_end(thd); break;
case WSREP_OSU_RSU: return wsrep_RSU_end(thd); case WSREP_OSU_RSU: wsrep_RSU_end(thd); break;
} }
wsrep_cleanup_transaction(thd);
} }
} }

View File

@ -32,8 +32,9 @@ class THD;
LOCAL_STATE, LOCAL_STATE,
REPL_RECV, REPL_RECV,
TOTAL_ORDER, TOTAL_ORDER,
LOCAL_COMMIT, LOCAL_COMMIT
}; };
enum wsrep_query_state { enum wsrep_query_state {
QUERY_IDLE, QUERY_IDLE,
QUERY_EXEC, QUERY_EXEC,
@ -109,24 +110,22 @@ extern long wsrep_local_index;
extern const char* wsrep_provider_name; extern const char* wsrep_provider_name;
extern const char* wsrep_provider_version; extern const char* wsrep_provider_version;
extern const char* wsrep_provider_vendor; extern const char* wsrep_provider_vendor;
extern int wsrep_show_status(THD *thd, SHOW_VAR *var, char *buff);
extern void wsrep_free_status(THD *thd);
int wsrep_show_status(THD *thd, SHOW_VAR *var, char *buff);
void wsrep_free_status(THD *thd);
extern int wsrep_init_vars(); /* Filters out --wsrep-new-cluster oprtion from argv[]
extern void wsrep_provider_init (const char* provider); * should be called in the very beginning of main() */
extern void wsrep_start_position_init (const char* position); void wsrep_filter_new_cluster (int* argc, char* argv[]);
extern void wsrep_sst_auth_init (const char* auth);
extern int wsrep_init(); int wsrep_init();
extern void wsrep_deinit(); void wsrep_deinit();
extern void wsrep_recover(); void wsrep_recover();
extern bool wsrep_before_SE(); // initialize wsrep before storage bool wsrep_before_SE(); // initialize wsrep before storage
// engines (true) or after (false) // engines (true) or after (false)
/* wsrep initialization sequence at startup /* wsrep initialization sequence at startup
* @param before wsrep_before_SE() value */ * @param before wsrep_before_SE() value */
extern void wsrep_init_startup(bool before); void wsrep_init_startup(bool before);
@ -238,6 +237,7 @@ wsrep_run_wsrep_commit(THD *thd, handlerton *hton, bool all);
class Ha_trx_info; class Ha_trx_info;
struct THD_TRANS; struct THD_TRANS;
void wsrep_register_hton(THD* thd, bool all); void wsrep_register_hton(THD* thd, bool all);
void wsrep_post_commit(THD* thd, bool all);
void wsrep_brute_force_killer(THD *thd); void wsrep_brute_force_killer(THD *thd);
int wsrep_hire_brute_force_killer(THD *thd, uint64_t trx_id); int wsrep_hire_brute_force_killer(THD *thd, uint64_t trx_id);
@ -285,7 +285,7 @@ struct TABLE_LIST;
int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_, int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_,
const TABLE_LIST* table_list); const TABLE_LIST* table_list);
void wsrep_to_isolation_end(THD *thd); void wsrep_to_isolation_end(THD *thd);
void wsrep_cleanup_transaction(THD *thd);
int wsrep_to_buf_helper( int wsrep_to_buf_helper(
THD* thd, const char *query, uint query_len, uchar** buf, int* buf_len); THD* thd, const char *query, uint query_len, uchar** buf, int* buf_len);
int wsrep_create_sp(THD *thd, uchar** buf, int* buf_len); int wsrep_create_sp(THD *thd, uchar** buf, int* buf_len);

View File

@ -93,8 +93,6 @@ static void wsrep_prepare_bf_thd(THD *thd, struct wsrep_thd_shadow* shadow)
thd->net.vio= 0; thd->net.vio= 0;
thd->clear_error(); thd->clear_error();
thd->variables.option_bits|= OPTION_NOT_AUTOCOMMIT;
shadow->tx_isolation = thd->variables.tx_isolation; shadow->tx_isolation = thd->variables.tx_isolation;
thd->variables.tx_isolation = ISO_READ_COMMITTED; thd->variables.tx_isolation = ISO_READ_COMMITTED;
thd->tx_isolation = ISO_READ_COMMITTED; thd->tx_isolation = ISO_READ_COMMITTED;
@ -140,6 +138,11 @@ void wsrep_replay_transaction(THD *thd)
(long long)wsrep_thd_trx_seqno(thd)); (long long)wsrep_thd_trx_seqno(thd));
struct wsrep_thd_shadow shadow; struct wsrep_thd_shadow shadow;
wsrep_prepare_bf_thd(thd, &shadow); wsrep_prepare_bf_thd(thd, &shadow);
/* From trans_begin() */
thd->variables.option_bits|= OPTION_BEGIN;
thd->server_status|= SERVER_STATUS_IN_TRANS;
int rcode = wsrep->replay_trx(wsrep, int rcode = wsrep->replay_trx(wsrep,
&thd->wsrep_ws_handle, &thd->wsrep_ws_handle,
(void *)thd); (void *)thd);
@ -161,6 +164,14 @@ void wsrep_replay_transaction(THD *thd)
{ {
WSREP_WARN("replay ok, thd has reported status"); WSREP_WARN("replay ok, thd has reported status");
} }
else if (thd->get_stmt_da()->is_set())
{
if (thd->get_stmt_da()->status() != Diagnostics_area::DA_OK)
{
WSREP_WARN("replay ok, thd has error status %d",
thd->get_stmt_da()->status());
}
}
else else
{ {
my_ok(thd); my_ok(thd);
@ -186,6 +197,9 @@ void wsrep_replay_transaction(THD *thd)
unireg_abort(1); unireg_abort(1);
break; break;
} }
wsrep_cleanup_transaction(thd);
mysql_mutex_lock(&LOCK_wsrep_replaying); mysql_mutex_lock(&LOCK_wsrep_replaying);
wsrep_replaying--; wsrep_replaying--;
WSREP_DEBUG("replaying decreased: %d, thd: %lu", WSREP_DEBUG("replaying decreased: %d, thd: %lu",
@ -204,6 +218,10 @@ static 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);
/* From trans_begin() */
thd->variables.option_bits|= OPTION_BEGIN;
thd->server_status|= SERVER_STATUS_IN_TRANS;
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));
@ -371,21 +389,24 @@ void wsrep_create_rollbacker()
extern "C" extern "C"
int wsrep_thd_is_brute_force(void *thd_ptr) int wsrep_thd_is_brute_force(void *thd_ptr)
{ {
/*
Brute force:
Appliers and replaying are running in REPL_RECV mode. TOI statements
in TOTAL_ORDER mode. Locally committing transaction that has got
past wsrep->pre_commit() without error is running in LOCAL_COMMIT mode.
Everything else is running in LOCAL_STATE and should not be considered
brute force.
*/
if (thd_ptr) { if (thd_ptr) {
switch (((THD *)thd_ptr)->wsrep_exec_mode) { switch (((THD *)thd_ptr)->wsrep_exec_mode) {
case LOCAL_STATE: case LOCAL_STATE: return 0;
{
if (((THD *)thd_ptr)->wsrep_conflict_state== REPLAYING)
{
return 1;
}
return 0;
}
case REPL_RECV: return 1; case REPL_RECV: return 1;
case TOTAL_ORDER: return 2; case TOTAL_ORDER: return 2;
case LOCAL_COMMIT: return 3; case LOCAL_COMMIT: return 3;
} }
} }
DBUG_ASSERT(0);
return 0; return 0;
} }

View File

@ -14,7 +14,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
//! @file declares symbols private to wsrep integration layer //! @file some utility functions and classes not directly related to replication
#ifndef _GNU_SOURCE #ifndef _GNU_SOURCE
#define _GNU_SOURCE // POSIX_SPAWN_USEVFORK flag #define _GNU_SOURCE // POSIX_SPAWN_USEVFORK flag

View File

@ -37,7 +37,7 @@ const char* wsrep_node_name = 0;
const char* wsrep_node_address = 0; const char* wsrep_node_address = 0;
const char* wsrep_node_incoming_address = 0; const char* wsrep_node_incoming_address = 0;
const char* wsrep_start_position = 0; const char* wsrep_start_position = 0;
ulong wsrep_OSU_method_options; ulong wsrep_OSU_method_options;
int wsrep_init_vars() int wsrep_init_vars()
{ {

View File

@ -25,6 +25,8 @@ class sys_var;
class set_var; class set_var;
class THD; class THD;
int wsrep_init_vars();
#define CHECK_ARGS (sys_var *self, THD* thd, set_var *var) #define CHECK_ARGS (sys_var *self, THD* thd, set_var *var)
#define UPDATE_ARGS (sys_var *self, THD* thd, enum_var_type type) #define UPDATE_ARGS (sys_var *self, THD* thd, enum_var_type type)
#define DEFAULT_ARGS (THD* thd, enum_var_type var_type) #define DEFAULT_ARGS (THD* thd, enum_var_type var_type)

View File

@ -9403,22 +9403,6 @@ wsrep_append_key(
DBUG_RETURN(0); DBUG_RETURN(0);
} }
ibool
wsrep_is_cascding_foreign_key_parent(
dict_table_t* table, /*!< in: InnoDB table */
dict_index_t* index /*!< in: InnoDB index */
) {
// return referenced_by_foreign_key();
dict_foreign_t* fk = dict_table_get_referenced_constraint(table, index);
if (fk &&
(fk->type & DICT_FOREIGN_ON_UPDATE_CASCADE ||
fk->type & DICT_FOREIGN_ON_UPDATE_SET_NULL)
) {
return TRUE;
}
return FALSE;
}
int int
ha_innobase::wsrep_append_keys( ha_innobase::wsrep_append_keys(
/*==================*/ /*==================*/
@ -9467,19 +9451,30 @@ ha_innobase::wsrep_append_keys(
uint i; uint i;
for (i=0; i<table->s->keys; ++i) { for (i=0; i<table->s->keys; ++i) {
uint len; uint len;
char keyval0[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'}; char keyval0[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'};
char keyval1[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'}; char keyval1[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'};
char *key0 = &keyval0[1]; char* key0 = &keyval0[1];
char *key1 = &keyval1[1]; char* key1 = &keyval1[1];
KEY *key_info = table->key_info + i; KEY* key_info = table->key_info + i;
ibool is_null; ibool is_null;
dict_index_t* idx = innobase_get_index(i);
dict_table_t* tab = (idx) ? idx->table : NULL;
keyval0[0] = (char)i; keyval0[0] = (char)i;
keyval1[0] = (char)i; keyval1[0] = (char)i;
if (!tab) {
WSREP_WARN("MySQL-InnoDB key mismatch %s %s",
table->s->table_name.str,
key_info->name);
}
if (key_info->flags & HA_NOSAME || if (key_info->flags & HA_NOSAME ||
referenced_by_foreign_key()) { ((tab &&
dict_table_get_referenced_constraint(tab, idx)) ||
(!tab && referenced_by_foreign_key()))) {
if (key_info->flags & HA_NOSAME || shared) if (key_info->flags & HA_NOSAME || shared)
key_appended = true; key_appended = true;