summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorSeppo Jaakola <seppo.jaakola@codership.com>2012-04-26 20:18:30 +0300
committerSeppo Jaakola <seppo.jaakola@codership.com>2012-04-26 20:18:30 +0300
commit609388fcfd912c9c2cb03a92251469a25a781893 (patch)
tree9135fdc6e31e1e784fbdbcc35ae63003d0600824 /sql
parente0015163515d1fe5d3747c6f859461a30c2ecfd6 (diff)
downloadmariadb-git-609388fcfd912c9c2cb03a92251469a25a781893.tar.gz
Merged changes from lp:codership-mysql up to rev 3743
-r3725..3737 -r3738..3740 -r3741..3743
Diffstat (limited to 'sql')
-rw-r--r--sql/log_event.cc25
-rw-r--r--sql/sql_alter.cc7
-rw-r--r--sql/sql_base.cc19
-rw-r--r--sql/sql_connect.cc6
-rw-r--r--sql/sql_parse.cc203
-rw-r--r--sql/sql_truncate.cc2
-rw-r--r--sql/sys_vars.cc3
-rw-r--r--sql/transaction.cc2
-rw-r--r--sql/wsrep_hton.cc20
-rw-r--r--sql/wsrep_mysqld.cc166
-rw-r--r--sql/wsrep_mysqld.h22
-rw-r--r--sql/wsrep_utils.cc2
12 files changed, 317 insertions, 160 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc
index e02cfc6d20c..1536d9e899b 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -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))
{
+ uint actual_error= thd->stmt_da->sql_errno();
#ifdef WITH_WSREP
- uint actual_error= ER_SERVER_SHUTDOWN;
- if (WSREP(thd) && !thd->is_fatal_error)
+ if (WSREP(thd))
{
- sql_print_information("WSREP, BF applier interrupted in log_event.cc");
+ 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);
}
- else
- actual_error= thd->stmt_da->sql_errno();
-#else
- uint actual_error= thd->stmt_da->sql_errno();
#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;
diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc
index c4468ee8793..00691633aa8 100644
--- a/sql/sql_alter.cc
+++ b/sql/sql_alter.cc
@@ -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);
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index d4aeedeb852..da93cfeb001 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -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
diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc
index 04e46bfa1e6..c0cdddeb561 100644
--- a/sql/sql_connect.cc
+++ b/sql/sql_connect.cc
@@ -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;
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 51d81616c24..b4b7eb0b2cf 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -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_DEBUG("abort in exec query state, avoiding autocommit");
- goto wsrep_must_abort;
- }
- mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
- }
-#endif /* WITH_WSREP */
+ wsrep_client_rollback(thd);
-#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;
+ WSREP_DEBUG("abort in exec query state, avoiding autocommit");
}
- 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);
}
}
diff --git a/sql/sql_truncate.cc b/sql/sql_truncate.cc
index a66b2377fcb..6745d461df5 100644
--- a/sql/sql_truncate.cc
+++ b/sql/sql_truncate.cc
@@ -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)))
diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc
index 8edfa8f2a6e..b8c21f9621e 100644
--- a/sql/sys_vars.cc
+++ b/sql/sys_vars.cc
@@ -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 */
diff --git a/sql/transaction.cc b/sql/transaction.cc
index d5f9436ae53..ef4383df0ea 100644
--- a/sql/transaction.cc
+++ b/sql/transaction.cc
@@ -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 */
diff --git a/sql/wsrep_hton.cc b/sql/wsrep_hton.cc
index 9986d7c79cd..bb5faafc768 100644
--- a/sql/wsrep_hton.cc
+++ b/sql/wsrep_hton.cc
@@ -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) {
diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc
index 5a5250652b8..be2b8d7fa81 100644
--- a/sql/wsrep_mysqld.cc
+++ b/sql/wsrep_mysqld.cc
@@ -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;
diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h
index 90498c266ee..985431e74b9 100644
--- a/sql/wsrep_mysqld.h
+++ b/sql/wsrep_mysqld.h
@@ -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*);
diff --git a/sql/wsrep_utils.cc b/sql/wsrep_utils.cc
index f39353eda44..a6d7dcdbfc8 100644
--- a/sql/wsrep_utils.cc
+++ b/sql/wsrep_utils.cc
@@ -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"