1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

Merged changes from lp:codership-mysql up to rev 3743

-r3725..3737
-r3738..3740
-r3741..3743
This commit is contained in:
Seppo Jaakola
2012-04-26 20:18:30 +03:00
parent e001516351
commit 609388fcfd
16 changed files with 351 additions and 192 deletions

View File

@ -8130,19 +8130,20 @@ int Rows_log_event::do_apply_event(Relay_log_info const *rli)
thd->variables.option_bits&= ~OPTION_RELAXED_UNIQUE_CHECKS;
/* A small test to verify that objects have consistent types */
DBUG_ASSERT(sizeof(thd->variables.option_bits) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
if (open_and_lock_tables(thd, rli->tables_to_lock, FALSE, 0))
{
#ifdef WITH_WSREP
uint actual_error= ER_SERVER_SHUTDOWN;
if (WSREP(thd) && !thd->is_fatal_error)
{
sql_print_information("WSREP, BF applier interrupted in log_event.cc");
}
else
actual_error= thd->stmt_da->sql_errno();
#else
uint actual_error= thd->stmt_da->sql_errno();
#ifdef WITH_WSREP
if (WSREP(thd))
{
WSREP_WARN("BF applier failed to open_and_lock_tables: %u, fatal: %d "
"wsrep = (exec_mode: %d conflict_state: %d seqno: %lld)",
thd->stmt_da->sql_errno(),
thd->is_fatal_error,
thd->wsrep_exec_mode,
thd->wsrep_conflict_state,
(long long)thd->wsrep_trx_seqno);
}
#endif
if (thd->is_slave_error || thd->is_fatal_error)
{
@ -10878,6 +10879,8 @@ Format_description_log_event *wsrep_format_desc; // TODO: free them at the end
At the end (*buf) is shitfed to point to the following event or NULL and
(*buf_len) will be changed to account just being read bytes of the 1st event.
*/
#define WSREP_MAX_ALLOWED_PACKET 1024*1024*1024 // current protocol max
Log_event* wsrep_read_log_event(
char **arg_buf, size_t *arg_buf_len,
const Format_description_log_event *description_event)
@ -10889,12 +10892,8 @@ Log_event* wsrep_read_log_event(
char *buf= (*arg_buf);
const char *error= 0;
Log_event *res= 0;
#ifndef max_allowed_packet
THD *thd=current_thd;
uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0;
#endif
if (data_len > max_allowed_packet)
if (data_len > WSREP_MAX_ALLOWED_PACKET)
{
error = "Event too big";
goto err;

View File

@ -100,11 +100,14 @@ bool Alter_table_statement::execute(THD *thd)
thd->enable_slow_log= opt_log_slow_admin_statements;
#ifdef WITH_WSREP
TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl);
TABLE *find_temporary_table(THD *thd, const TABLE_LIST *tl);
if ((!thd->is_current_stmt_binlog_format_row() ||
!find_temporary_table(thd, first_table)) &&
wsrep_to_isolation_begin(thd, first_table->db, first_table->table_name))
wsrep_to_isolation_begin(thd,
lex->name.str ? select_lex->db : NULL,
lex->name.str ? lex->name.str : NULL,
first_table))
{
WSREP_WARN("ALTER TABLE isolation failure");
DBUG_RETURN(TRUE);

View File

@ -62,6 +62,7 @@
#ifdef WITH_WSREP
#include "wsrep_mysqld.h"
#endif // WITH_WSREP
bool
@ -5077,6 +5078,24 @@ restart:
}
}
}
#ifdef WITH_WSREP
#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) \
if (WSREP(thd) && wsrep_to_isolation_begin(thd, db_, table_, table_list_)) goto err;
if ((thd->lex->sql_command== SQLCOM_INSERT ||
thd->lex->sql_command== SQLCOM_INSERT_SELECT ||
thd->lex->sql_command== SQLCOM_REPLACE ||
thd->lex->sql_command== SQLCOM_REPLACE_SELECT ||
thd->lex->sql_command== SQLCOM_UPDATE ||
thd->lex->sql_command== SQLCOM_UPDATE_MULTI ||
thd->lex->sql_command== SQLCOM_LOAD ||
thd->lex->sql_command== SQLCOM_DELETE) &&
wsrep_replicate_myisam &&
(*start)->table && (*start)->table->file->ht->db_type == DB_TYPE_MYISAM)
{
WSREP_TO_ISOLATION_BEGIN(NULL, NULL, (*start));
}
#endif
err:
#ifdef WITH_WSREP

View File

@ -100,9 +100,6 @@ int get_or_create_user_conn(THD *thd, const char *user,
}
thd->user_connect=uc;
uc->connections++;
#ifdef WITH_WSREP
thd->wsrep_client_thread= 1;
#endif /* WITH_WSREP */
end:
mysql_mutex_unlock(&LOCK_user_conn);
return return_val;
@ -1203,6 +1200,9 @@ bool thd_prepare_connection(THD *thd)
(char *) thd->security_ctx->host_or_ip);
prepare_new_connection_state(thd);
#ifdef WITH_WSREP
thd->wsrep_client_thread= 1;
#endif /* WITH_WSREP */
return FALSE;
}

View File

@ -105,19 +105,20 @@
#ifdef WITH_WSREP
#include "wsrep_mysqld.h"
#include "rpl_rli.h"
static void wsrep_client_rollback(THD *thd);
extern Format_description_log_event *wsrep_format_desc;
#define WSREP_MYSQL_DB (char *)"mysql"
#define WSREP_TO_ISOLATION_BEGIN(db_, table_) \
if (WSREP(thd) && wsrep_to_isolation_begin(thd, db_, table_)) goto error;
#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_) \
if (WSREP(thd) && wsrep_to_isolation_begin(thd, db_, table_, table_list_)) goto error;
#define WSREP_TO_ISOLATION_END \
if (WSREP(thd) || (thd && thd->wsrep_exec_mode==TOTAL_ORDER)) \
wsrep_to_isolation_end(thd);
#else
#define WSREP_TO_ISOLATION_BEGIN(db_, table_)
#define WSREP_TO_ISOLATION_BEGIN(db_, table_, table_list_)
#define WSREP_TO_ISOLATION_END
#endif /* WITH_WSREP */
/**
@ -727,15 +728,7 @@ bool do_command(THD *thd)
thd->wsrep_query_state= QUERY_IDLE;
if (thd->wsrep_conflict_state==MUST_ABORT)
{
thd->wsrep_conflict_state= ABORTING;
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
trans_rollback(thd);
thd->locked_tables_list.unlock_locked_tables(thd);
/* Release transactional metadata locks. */
thd->mdl_context.release_transactional_locks();
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
thd->wsrep_conflict_state= ABORTED;
wsrep_client_rollback(thd);
}
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
}
@ -822,16 +815,7 @@ bool do_command(THD *thd)
if (thd->wsrep_conflict_state == MUST_ABORT)
{
DBUG_PRINT("wsrep",("aborted for wsrep rollback: %lu", thd->real_id));
thd->wsrep_conflict_state= ABORTING;
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
trans_rollback(thd);
thd->locked_tables_list.unlock_locked_tables(thd);
/* Release transactional metadata locks. */
thd->mdl_context.release_transactional_locks();
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
thd->wsrep_conflict_state= ABORTED;
wsrep_client_rollback(thd);
}
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
}
@ -1082,14 +1066,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (thd->wsrep_conflict_state== MUST_ABORT)
{
thd->wsrep_conflict_state= ABORTING;
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
trans_rollback(thd);
thd->locked_tables_list.unlock_locked_tables(thd);
/* Release transactional metadata locks. */
thd->mdl_context.release_transactional_locks();
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
thd->wsrep_conflict_state= ABORTED;
wsrep_client_rollback(thd);
}
if (thd->wsrep_conflict_state== ABORTED)
{
@ -1641,43 +1618,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
/* wsrep BF abort in query exec phase */
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
if (thd->wsrep_conflict_state == MUST_ABORT) {
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
ha_rollback_trans(thd, 0);
thd->locked_tables_list.unlock_locked_tables(thd);
/* Release transactional metadata locks. */
thd->mdl_context.release_transactional_locks();
thd->transaction.stmt.reset();
wsrep_client_rollback(thd);
WSREP_DEBUG("abort in exec query state, avoiding autocommit");
goto wsrep_must_abort;
}
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
}
#endif /* WITH_WSREP */
#ifdef WITH_WSREP
wsrep_must_abort:
if (WSREP(thd)) {
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
if (thd->wsrep_conflict_state == MUST_ABORT) {
thd->wsrep_conflict_state= ABORTING;
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
WSREP_DEBUG("in dispatch_command, aborting %s",
(thd->query()) ? thd->query() : "void");
trans_rollback(thd);
thd->locked_tables_list.unlock_locked_tables(thd);
/* Release transactional metadata locks. */
thd->mdl_context.release_transactional_locks();
if (thd->get_binlog_table_maps()) {
thd->clear_binlog_table_maps();
}
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
thd->wsrep_conflict_state= ABORTED;
}
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
/* checking if BF trx must be replayed */
if (thd->wsrep_conflict_state== MUST_REPLAY) {
if (thd->wsrep_exec_mode!= REPL_RECV) {
@ -1692,11 +1637,18 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
mysql_reset_thd_for_next_command(thd, opt_userstat_running);
thd->killed= NOT_KILLED;
close_thread_tables(thd);
if (thd->locked_tables_mode && thd->lock)
{
WSREP_DEBUG("releasing table lock for replaying (%ld)", thd->thread_id);
thd->locked_tables_list.unlock_locked_tables(thd);
thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
}
thd->mdl_context.release_transactional_locks();
thd_proc_info(thd, "wsrep replaying trx");
WSREP_DEBUG("replay trx: %s %lld",
thd->query() ? thd->query() : "void",
(long long)thd->wsrep_trx_seqno);
thd->query() ? thd->query() : "void",
(long long)thd->wsrep_trx_seqno);
struct wsrep_thd_shadow shadow;
wsrep_prepare_bf_thd(thd, &shadow);
int rcode = wsrep->replay_trx(wsrep,
@ -2547,7 +2499,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_SHOW_STATUS_PROC:
case SQLCOM_SHOW_STATUS_FUNC:
#ifdef WITH_WSREP
if (WSREP(thd) && wsrep_causal_wait(thd)) goto error;
if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error;
#endif /* WITH_WSREP */
if ((res= check_table_access(thd, SELECT_ACL, all_tables, FALSE,
UINT_MAX, FALSE)))
@ -2557,7 +2509,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_SHOW_STATUS:
{
#ifdef WITH_WSREP
if (WSREP(thd) && wsrep_causal_wait(thd)) goto error;
if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error;
#endif /* WITH_WSREP */
execute_show_status(thd, all_tables);
break;
@ -2583,7 +2535,7 @@ mysql_execute_command(THD *thd)
case SQLCOM_SHOW_INDEX_STATS:
case SQLCOM_SELECT:
#ifdef WITH_WSREP
if (WSREP(thd) && wsrep_causal_wait(thd)) goto error;
if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error;
case SQLCOM_SHOW_VARIABLES:
case SQLCOM_SHOW_CHARSETS:
case SQLCOM_SHOW_COLLATIONS:
@ -3007,7 +2959,8 @@ case SQLCOM_PREPARE:
#ifdef WITH_WSREP
if (!thd->is_current_stmt_binlog_format_row() ||
!(create_info.options & HA_LEX_CREATE_TMP_TABLE))
WSREP_TO_ISOLATION_BEGIN(create_table->db, create_table->table_name)
WSREP_TO_ISOLATION_BEGIN(create_table->db, create_table->table_name,
NULL)
#endif /* WITH_WSREP */
if (create_info.options & HA_LEX_CREATE_TABLE_LIKE)
{
@ -3050,7 +3003,7 @@ end_with_restore_list:
DBUG_ASSERT(first_table == all_tables && first_table != 0);
if (check_one_table_access(thd, INDEX_ACL, all_tables))
goto error; /* purecov: inspected */
WSREP_TO_ISOLATION_BEGIN(first_table->db, first_table->table_name)
WSREP_TO_ISOLATION_BEGIN(first_table->db, first_table->table_name, NULL)
/*
Currently CREATE INDEX or DROP INDEX cause a full table rebuild
and thus classify as slow administrative statements just like
@ -3108,7 +3061,7 @@ end_with_restore_list:
case SQLCOM_RENAME_TABLE:
{
WSREP_TO_ISOLATION_BEGIN(first_table->db, first_table->table_name)
WSREP_TO_ISOLATION_BEGIN(0, 0, first_table)
if (execute_rename_table(thd, first_table, all_tables))
goto error;
break;
@ -3137,7 +3090,7 @@ end_with_restore_list:
#else
{
#ifdef WITH_WSREP
if (WSREP(thd) && wsrep_causal_wait(thd)) goto error;
if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error;
#endif /* WITH_WSREP */
/*
@ -3196,7 +3149,7 @@ end_with_restore_list:
{
DBUG_ASSERT(first_table == all_tables && first_table != 0);
#ifdef WITH_WSREP
if (WSREP(thd) && wsrep_causal_wait(thd)) goto error;
if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd)) goto error;
#endif /* WITH_WSREP */
if (check_table_access(thd, SELECT_ACL, all_tables,
@ -3397,7 +3350,7 @@ end_with_restore_list:
if (lex->sql_command == SQLCOM_INSERT_SELECT &&
thd->wsrep_consistency_check)
{
WSREP_TO_ISOLATION_BEGIN(first_table->db, first_table->table_name);
WSREP_TO_ISOLATION_BEGIN(first_table->db, first_table->table_name, NULL);
}
#endif
@ -3568,9 +3521,9 @@ end_with_restore_list:
for (TABLE_LIST *table= all_tables; table; table= table->next_global)
{
if (!thd->is_current_stmt_binlog_format_row() ||
!find_temporary_table(thd, table))
!find_temporary_table(thd, table))
{
WSREP_TO_ISOLATION_BEGIN(table->db, table->table_name);
WSREP_TO_ISOLATION_BEGIN(NULL, NULL, all_tables);
break;
}
}
@ -3760,7 +3713,7 @@ end_with_restore_list:
#endif
if (check_access(thd, CREATE_ACL, lex->name.str, NULL, NULL, 1, 0))
break;
WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL)
WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL)
res= mysql_create_db(thd,(lower_case_table_names == 2 ? alias :
lex->name.str), &create_info, 0);
break;
@ -3790,7 +3743,7 @@ end_with_restore_list:
#endif
if (check_access(thd, DROP_ACL, lex->name.str, NULL, NULL, 1, 0))
break;
WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL)
WSREP_TO_ISOLATION_BEGIN(lex->name.str, NULL, NULL)
res= mysql_rm_db(thd, lex->name.str, lex->drop_if_exists, 0);
break;
}
@ -3819,7 +3772,7 @@ end_with_restore_list:
res= 1;
break;
}
WSREP_TO_ISOLATION_BEGIN(db->str, NULL)
WSREP_TO_ISOLATION_BEGIN(db->str, NULL, NULL)
res= mysql_upgrade_db(thd, db);
if (!res)
my_ok(thd);
@ -3852,7 +3805,7 @@ end_with_restore_list:
#endif
if (check_access(thd, ALTER_ACL, db->str, NULL, NULL, 1, 0))
break;
WSREP_TO_ISOLATION_BEGIN(db->str, NULL)
WSREP_TO_ISOLATION_BEGIN(db->str, NULL, NULL)
res= mysql_alter_db(thd, db->str, &create_info);
break;
}
@ -3885,7 +3838,7 @@ end_with_restore_list:
if (res)
break;
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
switch (lex->sql_command) {
case SQLCOM_CREATE_EVENT:
{
@ -3920,7 +3873,7 @@ end_with_restore_list:
lex->spname->m_name);
break;
case SQLCOM_DROP_EVENT:
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
if (!(res= Events::drop_event(thd,
lex->spname->m_db, lex->spname->m_name,
lex->drop_if_exists)))
@ -3935,7 +3888,7 @@ end_with_restore_list:
if (check_access(thd, INSERT_ACL, "mysql", NULL, NULL, 1, 0))
break;
#ifdef HAVE_DLOPEN
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
if (!(res = mysql_create_function(thd, &lex->udf)))
my_ok(thd);
#else
@ -3950,7 +3903,7 @@ end_with_restore_list:
if (check_access(thd, INSERT_ACL, "mysql", NULL, NULL, 1, 1) &&
check_global_access(thd,CREATE_USER_ACL))
break;
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
/* Conditionally writes to binlog */
if (!(res= mysql_create_user(thd, lex->users_list)))
my_ok(thd);
@ -3962,7 +3915,7 @@ end_with_restore_list:
check_global_access(thd,CREATE_USER_ACL))
break;
/* Conditionally writes to binlog */
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
if (!(res= mysql_drop_user(thd, lex->users_list)))
my_ok(thd);
break;
@ -3973,7 +3926,7 @@ end_with_restore_list:
check_global_access(thd,CREATE_USER_ACL))
break;
/* Conditionally writes to binlog */
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
if (!(res= mysql_rename_user(thd, lex->users_list)))
my_ok(thd);
break;
@ -3988,7 +3941,7 @@ end_with_restore_list:
thd->binlog_invoker();
/* Conditionally writes to binlog */
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
if (!(res = mysql_revoke_all(thd, lex->users_list)))
my_ok(thd);
break;
@ -4055,7 +4008,7 @@ end_with_restore_list:
lex->type == TYPE_ENUM_PROCEDURE, 0))
goto error;
/* Conditionally writes to binlog */
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
res= mysql_routine_grant(thd, all_tables,
lex->type == TYPE_ENUM_PROCEDURE,
lex->users_list, grants,
@ -4069,7 +4022,7 @@ end_with_restore_list:
all_tables, FALSE, UINT_MAX, FALSE))
goto error;
/* Conditionally writes to binlog */
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
res= mysql_table_grant(thd, all_tables, lex->users_list,
lex->columns, lex->grant,
lex->sql_command == SQLCOM_REVOKE);
@ -4085,7 +4038,7 @@ end_with_restore_list:
}
else
{
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
/* Conditionally writes to binlog */
res = mysql_grant(thd, select_lex->db, lex->users_list, lex->grant,
lex->sql_command == SQLCOM_REVOKE,
@ -4383,7 +4336,7 @@ end_with_restore_list:
if (sp_process_definer(thd))
goto create_sp_error;
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
res= (sp_result= sp_create_routine(thd, lex->sphead->m_type, lex->sphead));
switch (sp_result) {
case SP_OK: {
@ -4595,7 +4548,7 @@ create_sp_error:
already puts on CREATE FUNCTION.
*/
/* Conditionally writes to binlog */
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
sp_result= sp_update_routine(thd, type, lex->spname, &lex->sp_chistics);
switch (sp_result)
{
@ -4667,7 +4620,7 @@ create_sp_error:
if (check_routine_access(thd, ALTER_PROC_ACL, db, name,
lex->sql_command == SQLCOM_DROP_PROCEDURE, 0))
goto error;
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
/* Conditionally writes to binlog */
sp_result= sp_drop_routine(thd, type, lex->spname);
@ -4785,7 +4738,7 @@ create_sp_error:
Note: SQLCOM_CREATE_VIEW also handles 'ALTER VIEW' commands
as specified through the thd->lex->create_view_mode flag.
*/
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
res= mysql_create_view(thd, first_table, thd->lex->create_view_mode);
break;
}
@ -4794,14 +4747,14 @@ create_sp_error:
if (check_table_access(thd, DROP_ACL, all_tables, FALSE, UINT_MAX, FALSE))
goto error;
/* Conditionally writes to binlog. */
WSREP_TO_ISOLATION_BEGIN(NULL, NULL)
WSREP_TO_ISOLATION_BEGIN(NULL, NULL, NULL)
res= mysql_drop_view(thd, first_table, thd->lex->drop_mode);
break;
}
case SQLCOM_CREATE_TRIGGER:
{
/* Conditionally writes to binlog. */
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
res= mysql_create_or_drop_trigger(thd, all_tables, 1);
break;
@ -4809,7 +4762,7 @@ create_sp_error:
case SQLCOM_DROP_TRIGGER:
{
/* Conditionally writes to binlog. */
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
res= mysql_create_or_drop_trigger(thd, all_tables, 0);
break;
}
@ -4860,13 +4813,13 @@ create_sp_error:
my_ok(thd);
break;
case SQLCOM_INSTALL_PLUGIN:
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
if (! (res= mysql_install_plugin(thd, &thd->lex->comment,
&thd->lex->ident)))
my_ok(thd);
break;
case SQLCOM_UNINSTALL_PLUGIN:
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL)
WSREP_TO_ISOLATION_BEGIN(WSREP_MYSQL_DB, NULL, NULL)
if (! (res= mysql_uninstall_plugin(thd, &thd->lex->comment,
&thd->lex->ident)))
my_ok(thd);
@ -7905,6 +7858,41 @@ LEX_USER *create_definer(THD *thd, LEX_STRING *user_name, LEX_STRING *host_name)
}
#ifdef WITH_WSREP
/* must have (&thd->LOCK_wsrep_thd) */
static void wsrep_client_rollback(THD *thd)
{
WSREP_DEBUG("client rollback due to BF abort for (%ld), query: %s",
thd->thread_id, thd->query());
thd->wsrep_conflict_state= ABORTING;
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
trans_rollback(thd);
if (thd->locked_tables_mode && thd->lock)
{
WSREP_DEBUG("unlocking tables for BF abort (%ld)", thd->thread_id);
thd->locked_tables_list.unlock_locked_tables(thd);
thd->variables.option_bits&= ~(OPTION_TABLE_LOCK);
}
if (thd->global_read_lock.is_acquired())
{
WSREP_DEBUG("unlocking GRL for BF abort (%ld)", thd->thread_id);
thd->global_read_lock.unlock_global_read_lock(thd);
}
/* Release transactional metadata locks. */
thd->mdl_context.release_transactional_locks();
if (thd->get_binlog_table_maps())
{
WSREP_DEBUG("clearing binlog table map for BF abort (%ld)", thd->thread_id);
thd->clear_binlog_table_maps();
}
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
thd->wsrep_conflict_state= ABORTED;
}
static enum wsrep_status wsrep_apply_sql(
THD *thd, const char *sql, size_t sql_len, time_t timeval, uint32 randseed)
{
@ -8008,6 +7996,13 @@ static inline wsrep_status_t wsrep_apply_rbr(
int error = 0;
Log_event* ev= wsrep_read_log_event(&buf, &buf_len, wsrep_format_desc);
if (!ev)
{
WSREP_ERROR("applier could not read binlog event, seqno: %lld, len: %ld",
(long long)thd->wsrep_trx_seqno, buf_len);
rcode= 1;
goto error;
}
switch (ev->get_type_code()) {
case WRITE_ROWS_EVENT:
case UPDATE_ROWS_EVENT:
@ -8378,16 +8373,12 @@ void wsrep_rollback_process(THD *thd)
aborting->store_globals();
trans_rollback(aborting);
aborting->locked_tables_list.unlock_locked_tables(thd);
/* Release transactional metadata locks. */
aborting->mdl_context.release_transactional_locks();
mysql_mutex_lock(&aborting->LOCK_wsrep_thd);
aborting->wsrep_conflict_state= ABORTED;
wsrep_client_rollback(aborting);
WSREP_DEBUG("WSREP rollbacker aborted thd: %llu",
(long long)aborting->real_id);
mysql_mutex_unlock(&aborting->LOCK_wsrep_thd);
mysql_mutex_lock(&LOCK_wsrep_rollback);
}
}

View File

@ -521,7 +521,7 @@ bool Truncate_statement::execute(THD *thd)
#ifdef WITH_WSREP
if (WSREP(thd) && wsrep_to_isolation_begin(thd,
first_table->db,
first_table->table_name))
first_table->table_name, NULL))
DBUG_RETURN(TRUE);
#endif /* WITH_WSREP */
if (! (res= truncate_table(thd, first_table)))

View File

@ -3779,6 +3779,9 @@ static Sys_var_mybool Sys_wsrep_recover_datadir(
READ_ONLY GLOBAL_VAR(wsrep_recovery),
CMD_LINE(OPT_ARG, OPT_WSREP_RECOVER), DEFAULT(FALSE));
static Sys_var_mybool Sys_wsrep_replicate_myisam(
"wsrep_replicate_myisam", "To enable myisam replication",
GLOBAL_VAR(wsrep_replicate_myisam), CMD_LINE(OPT_ARG), DEFAULT(FALSE));
#endif /* WITH_WSREP */

View File

@ -158,7 +158,7 @@ bool trans_begin(THD *thd, uint flags)
#ifdef WITH_WSREP
thd->wsrep_PA_safe= true;
if (thd->wsrep_client_thread && wsrep_causal_wait(thd))
if (WSREP_CLIENT(thd) && wsrep_causal_wait(thd))
DBUG_RETURN(TRUE);
#endif /* WITH_WSREP */

View File

@ -15,6 +15,7 @@
#include <mysqld.h>
#include "sql_base.h"
#include "rpl_filter.h"
#include <sql_class.h>
#include "wsrep_mysqld.h"
#include "wsrep_priv.h"
@ -174,6 +175,7 @@ int wsrep_commit(handlerton *hton, THD *thd, bool all)
DBUG_RETURN(0);
}
extern Rpl_filter* binlog_filter;
extern my_bool opt_log_slave_updates;
enum wsrep_trx_status
wsrep_run_wsrep_commit(
@ -238,7 +240,8 @@ wsrep_run_wsrep_commit(
while (wsrep_replaying > 0 &&
thd->wsrep_conflict_state == NO_CONFLICT &&
thd->killed == NOT_KILLED &&
!shutdown_in_progress) {
!shutdown_in_progress)
{
mysql_mutex_unlock(&LOCK_wsrep_replaying);
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
@ -278,7 +281,8 @@ wsrep_run_wsrep_commit(
WSREP_DEBUG("innobase_commit abort after replaying wait %s",
(thd->query()) ? thd->query() : "void");
DBUG_RETURN(WSREP_TRX_ROLLBACK);
} thd->wsrep_query_state = QUERY_COMMITTING;
}
thd->wsrep_query_state = QUERY_COMMITTING;
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
cache = get_trans_log(thd);
@ -296,8 +300,18 @@ wsrep_run_wsrep_commit(
{
mysql_mutex_lock(&thd->LOCK_wsrep_thd);
thd->wsrep_exec_mode = LOCAL_COMMIT;
WSREP_DEBUG("empty rbr buffer, query: %s", thd->query());
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
if (thd->stmt_da->is_ok() &&
thd->stmt_da->affected_rows() > 0 &&
!binlog_filter->is_on())
{
WSREP_WARN("empty rbr buffer, query: %s, affected rows: %llu",
thd->query(), thd->stmt_da->affected_rows());
}
else
{
WSREP_DEBUG("empty rbr buffer, query: %s", thd->query());
}
DBUG_RETURN(WSREP_TRX_OK);
}
if (!rcode) {

View File

@ -48,6 +48,7 @@ my_bool wsrep_certify_nonPK = 1; // certify, even when no primary key
long wsrep_max_protocol_version = 1; // maximum protocol version to use
ulong wsrep_forced_binlog_format = BINLOG_FORMAT_UNSPEC;
my_bool wsrep_recovery = 0; // recovery
my_bool wsrep_replicate_myisam = 0; // enable myisam replication
/*
* End configuration options
@ -456,9 +457,25 @@ int wsrep_init()
}
}
char node_addr[256] = {0, };
if (!wsrep_node_address || !strcmp(wsrep_node_address, ""))
{
size_t node_addr_max= sizeof(node_addr);
size_t ret= default_ip(node_addr, node_addr_max);
if (!(ret > 0 && ret < node_addr_max))
{
WSREP_WARN("Failed to autoguess base node address");
node_addr[0]= 0;
}
}
else if (wsrep_node_address)
{
strncpy(node_addr, wsrep_node_address, sizeof(node_addr) - 1);
}
wsrep_args.data_dir = wsrep_data_home_dir;
wsrep_args.node_name = (wsrep_node_name) ? wsrep_node_name : "";
wsrep_args.node_address = (wsrep_node_address) ? wsrep_node_address : "";
wsrep_args.node_address = node_addr;
wsrep_args.node_incoming = wsrep_node_incoming_address;
wsrep_args.options = (wsrep_provider_options) ?
wsrep_provider_options : "";
@ -629,7 +646,8 @@ bool
wsrep_causal_wait (THD* thd)
{
if (thd->variables.wsrep_causal_reads && thd->variables.wsrep_on &&
!thd->in_active_multi_stmt_transaction())
!thd->in_active_multi_stmt_transaction() &&
thd->wsrep_conflict_state != REPLAYING)
{
// This allows autocommit SELECTs and a first SELECT after SET AUTOCOMMIT=0
// TODO: modify to check if thd has locked any rows.
@ -667,10 +685,42 @@ wsrep_causal_wait (THD* thd)
return false;
}
bool wsrep_prepare_key_for_isolation(const char* db,
const char* table,
wsrep_key_part_t* key,
size_t* key_len)
/*
* Helpers to deal with TOI key arrays
*/
typedef struct wsrep_key_arr
{
wsrep_key_t* keys;
size_t keys_len;
} wsrep_key_arr_t;
static void wsrep_keys_free(wsrep_key_arr_t* key_arr)
{
for (size_t i= 0; i < key_arr->keys_len; ++i)
{
my_free((wsrep_key_part_t*)key_arr->keys[i].key_parts);
}
my_free(key_arr->keys);
key_arr->keys= 0;
key_arr->keys_len= 0;
}
/*!
* @param db Database string
* @param table Table string
* @param key Array of wsrep_key_t
* @param key_len In: number of elements in key array, Out: number of
* elements populated
*
* @return true if preparation was successful, otherwise false.
*/
static bool wsrep_prepare_key_for_isolation(const char* db,
const char* table,
wsrep_key_part_t* key,
size_t* key_len)
{
if (*key_len < 2) return false;
@ -707,6 +757,89 @@ bool wsrep_prepare_key_for_isolation(const char* db,
return true;
}
/* Prepare key list from db/table and table_list */
static bool wsrep_prepare_keys_for_isolation(THD* thd,
const char* db,
const char* table,
const TABLE_LIST* table_list,
wsrep_key_arr_t* ka)
{
ka->keys= 0;
ka->keys_len= 0;
extern TABLE* find_temporary_table(THD*, const TABLE_LIST*);
if (db || table)
{
TABLE_LIST tmp_table;
bzero((char*) &tmp_table,sizeof(tmp_table));
tmp_table.table_name= (char*)db;
tmp_table.db= (char*)table;
if (!table || !find_temporary_table(thd, &tmp_table))
{
if (!(ka->keys= (wsrep_key_t*)my_malloc(sizeof(wsrep_key_t), MYF(0))))
{
sql_print_error("Can't allocate memory for key_array");
goto err;
}
ka->keys_len= 1;
if (!(ka->keys[0].key_parts= (wsrep_key_part_t*)
my_malloc(sizeof(wsrep_key_part_t)*2, MYF(0))))
{
sql_print_error("Can't allocate memory for key_parts");
goto err;
}
ka->keys[0].key_parts_len= 2;
if (!wsrep_prepare_key_for_isolation(
db, table,
(wsrep_key_part_t*)ka->keys[0].key_parts,
&ka->keys[0].key_parts_len))
{
sql_print_error("Preparing keys for isolation failed");
goto err;
}
}
}
for (const TABLE_LIST* table= table_list; table; table= table->next_global)
{
if (!find_temporary_table(thd, table))
{
wsrep_key_t* tmp;
tmp= (wsrep_key_t*)my_realloc(
ka->keys, (ka->keys_len + 1) * sizeof(wsrep_key_t), MYF(0));
if (!tmp)
{
sql_print_error("Can't allocate memory for key_array");
goto err;
}
ka->keys= tmp;
if (!(ka->keys[ka->keys_len].key_parts= (wsrep_key_part_t*)
my_malloc(sizeof(wsrep_key_part_t)*2, MYF(0))))
{
sql_print_error("Can't allocate memory for key_parts");
goto err;
}
ka->keys[ka->keys_len].key_parts_len= 2;
++ka->keys_len;
if (!wsrep_prepare_key_for_isolation(
table->db, table->table_name,
(wsrep_key_part_t*)ka->keys[ka->keys_len - 1].key_parts,
&ka->keys[ka->keys_len - 1].key_parts_len))
{
sql_print_error("Preparing keys for isolation failed");
goto err;
}
}
}
return true;
err:
wsrep_keys_free(ka);
return false;
}
bool wsrep_prepare_key_for_innodb(const uchar* cache_key,
size_t cache_key_len,
const uchar* row_id,
@ -842,15 +975,14 @@ create_view_query(THD *thd, uchar** buf, uint* buf_len)
return wsrep_to_buf_helper(thd, buff.ptr(), buff.length(), buf, buf_len);
}
static int wsrep_TOI_begin(THD *thd, char *db_, char *table_)
static int wsrep_TOI_begin(THD *thd, char *db_, char *table_,
const TABLE_LIST* table_list)
{
wsrep_status_t ret(WSREP_WARNING);
uchar* buf(0);
uint buf_len(0);
int buf_err;
wsrep_key_part_t wkey_part[2];
wsrep_key_t wkey = {wkey_part, 2};
WSREP_DEBUG("TO BEGIN: %lld, %d : %s", (long long)thd->wsrep_trx_seqno,
thd->wsrep_exec_mode, thd->query() );
switch (thd->lex->sql_command)
@ -874,17 +1006,18 @@ static int wsrep_TOI_begin(THD *thd, char *db_, char *table_)
break;
}
wsrep_key_arr_t key_arr= {0, 0};
if (!buf_err &&
wsrep_prepare_key_for_isolation(db_, table_, wkey_part,
&wkey.key_parts_len) &&
wsrep_prepare_keys_for_isolation(thd, db_, table_, table_list, &key_arr)&&
WSREP_OK == (ret = wsrep->to_execute_start(wsrep, thd->thread_id,
&wkey, 1,
key_arr.keys, key_arr.keys_len,
buf, buf_len,
&thd->wsrep_trx_seqno)))
{
thd->wsrep_exec_mode= TOTAL_ORDER;
wsrep_to_isolation++;
if (buf) my_free(buf);
wsrep_keys_free(&key_arr);
WSREP_DEBUG("TO BEGIN: %lld, %d",(long long)thd->wsrep_trx_seqno,
thd->wsrep_exec_mode);
}
@ -896,6 +1029,7 @@ static int wsrep_TOI_begin(THD *thd, char *db_, char *table_)
my_error(ER_LOCK_DEADLOCK, MYF(0), "WSREP replication failed. Check "
"your wsrep connection state and retry the query.");
if (buf) my_free(buf);
wsrep_keys_free(&key_arr);
return -1;
}
return 0;
@ -959,13 +1093,15 @@ static void wsrep_RSU_end(THD *thd)
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)
{
int ret= 0;
if (thd->variables.wsrep_on && thd->wsrep_exec_mode==LOCAL_STATE)
{
switch (wsrep_OSU_method_options) {
case WSREP_OSU_TOI: ret = wsrep_TOI_begin(thd, db_, table_); break;
case WSREP_OSU_TOI: ret = wsrep_TOI_begin(thd, db_, table_,
table_list); break;
case WSREP_OSU_RSU: ret = wsrep_RSU_begin(thd, db_, table_); break;
}
if (!ret)
@ -1046,7 +1182,7 @@ wsrep_grant_mdl_exception(MDL_context *requestor_ctx,
}
else
{
WSREP_MDL_LOG(INFO, "MDL conflict -> BF abort", request_thd, granted_thd);
WSREP_MDL_LOG(DEBUG, "MDL conflict-> BF abort", request_thd, granted_thd);
mysql_mutex_unlock(&granted_thd->LOCK_wsrep_thd);
wsrep_abort_thd((void*)request_thd, (void*)granted_thd, 1);
return FALSE;

View File

@ -60,6 +60,7 @@ extern long wsrep_protocol_version;
extern ulong wsrep_forced_binlog_format;
extern ulong wsrep_OSU_method_options;
extern my_bool wsrep_recovery;
extern my_bool wsrep_replicate_myisam;
enum enum_wsrep_OSU_method { WSREP_OSU_TOI, WSREP_OSU_RSU };
@ -162,6 +163,9 @@ extern wsrep_seqno_t wsrep_locked_seqno;
#define WSREP(thd) \
(WSREP_ON && (thd && thd->variables.wsrep_on))
#define WSREP_CLIENT(thd) \
(WSREP(thd) && thd->wsrep_client_thread)
#define WSREP_EMULATE_BINLOG(thd) \
(WSREP(thd) && wsrep_emulate_bin_log)
@ -206,20 +210,6 @@ class Ha_trx_info;
struct THD_TRANS;
void wsrep_register_hton(THD* thd, bool all);
/*!
* @param db Database string
* @param table Table string
* @param key Array of wsrep_key_t
* @param key_len In: number of elements in key array, Out: number of
* elements populated
*
* @return true if preparation was successful, otherwise false.
*/
bool wsrep_prepare_key_for_isolation(const char* db,
const char* table,
wsrep_key_part_t* key,
size_t *key_len);
void wsrep_replication_process(THD *thd);
void wsrep_rollback_process(THD *thd);
void wsrep_brute_force_killer(THD *thd);
@ -274,7 +264,9 @@ extern PSI_cond_key key_COND_wsrep_rollback;
extern PSI_mutex_key key_LOCK_wsrep_replaying;
extern PSI_cond_key key_COND_wsrep_replaying;
int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_);
struct TABLE_LIST;
int wsrep_to_isolation_begin(THD *thd, char *db_, char *table_,
const TABLE_LIST* table_list);
void wsrep_to_isolation_end(THD *thd);
void wsrep_prepare_bf_thd(THD *thd, struct wsrep_thd_shadow*);

View File

@ -332,7 +332,7 @@ size_t default_ip (char* buf, size_t buf_len)
"awk '{ print $2 }' | awk -F : '{ print $2 }'";
#elif defined(__sun__)
const char cmd[] = "/sbin/ifconfig -a | "
"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 }'";
#else
char *cmd;
#error "OS not supported"

View File

@ -6945,11 +6945,6 @@ wsrep_append_foreign_key(
byte key[WSREP_MAX_SUPPORTED_KEY_LENGTH+1];
ulint len = WSREP_MAX_SUPPORTED_KEY_LENGTH;
if (!dict_index_is_clust(clust_index)) {
WSREP_ERROR("clustered index not passed for FK append");
return DB_ERROR;
}
key[0] = '\0';
rcode = wsrep_rec_get_primary_key(
&key[1], &len, clust_rec, clust_index);

View File

@ -1790,25 +1790,23 @@ wsrep_rec_get_primary_key(
uint key_parts;
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
const ulint* offsets;
ut_ad(index);
key_parts = dict_index_get_n_unique_in_tree(index);
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
rec_offs_init(offsets_);
offsets = rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap);
ut_ad(rec_offs_validate(rec, NULL, offsets_));
ut_ad(rec_offs_validate(rec, NULL, offsets));
ut_ad(rec);
key_parts = dict_index_get_n_unique_in_tree(index);
for (i = 0; i < key_parts; i++) {
dict_field_t* field = dict_index_get_nth_field(index, i);
dict_field_t* field = dict_index_get_nth_field(index, i);
const dict_col_t* col = dict_field_get_col(field);
data = rec_get_nth_field(rec, offsets_, i, &len);
data = rec_get_nth_field(rec, offsets, i, &len);
if (key_len + len > ((col->prtype & DATA_NOT_NULL) ?
*buf_len : *buf_len - 1)) {
fprintf (stderr,
@ -1836,11 +1834,19 @@ wsrep_rec_get_primary_key(
}
}
rec_validate(rec, offsets_);
rec_validate(rec, offsets);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
*buf_len = key_len;
return DB_SUCCESS;
err_out:
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return DB_ERROR;
}
#endif // WITH_WSREP

View File

@ -7589,11 +7589,6 @@ wsrep_append_foreign_key(
byte key[WSREP_MAX_SUPPORTED_KEY_LENGTH+1];
ulint len = WSREP_MAX_SUPPORTED_KEY_LENGTH;
if (!dict_index_is_clust(clust_index)) {
WSREP_ERROR("clustered index not passed for FK append");
return DB_ERROR;
}
key[0] = '\0';
rcode = wsrep_rec_get_primary_key(
&key[1], &len, clust_rec, clust_index);

View File

@ -1790,25 +1790,23 @@ wsrep_rec_get_primary_key(
uint key_parts;
mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE];
const ulint* offsets;
ut_ad(index);
key_parts = dict_index_get_n_unique_in_tree(index);
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
rec_offs_init(offsets_);
offsets = rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap);
ut_ad(rec_offs_validate(rec, NULL, offsets_));
ut_ad(rec_offs_validate(rec, NULL, offsets));
ut_ad(rec);
key_parts = dict_index_get_n_unique_in_tree(index);
for (i = 0; i < key_parts; i++) {
dict_field_t* field = dict_index_get_nth_field(index, i);
dict_field_t* field = dict_index_get_nth_field(index, i);
const dict_col_t* col = dict_field_get_col(field);
data = rec_get_nth_field(rec, offsets_, i, &len);
data = rec_get_nth_field(rec, offsets, i, &len);
if (key_len + len > ((col->prtype & DATA_NOT_NULL) ?
*buf_len : *buf_len - 1)) {
fprintf (stderr,
@ -1836,11 +1834,19 @@ wsrep_rec_get_primary_key(
}
}
rec_validate(rec, offsets_);
rec_validate(rec, offsets);
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
*buf_len = key_len;
return DB_SUCCESS;
err_out:
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return DB_ERROR;
}
#endif // WITH_WSREP