Commit 9b506d4b authored by Jan Lindström's avatar Jan Lindström

MDEV-6602: rpl.rpl_mdev6020 fails sporadically with SIGABRT

Analysis: Problem is that we execute galera code when we are actually
executing asyncronoush replication.

Fix: Do not execute galera code if wsrep provider is not set.
parent de38fcfb
...@@ -503,17 +503,35 @@ int wsrep_thd_conflict_state(void *thd_ptr, my_bool sync) ...@@ -503,17 +503,35 @@ int wsrep_thd_conflict_state(void *thd_ptr, my_bool sync)
return state; return state;
} }
my_bool wsrep_thd_is_wsrep(void *thd_ptr)
{
my_bool status = FALSE;
if (thd_ptr)
{
THD* thd = (THD*)thd_ptr;
status = (WSREP(thd) && WSREP_PROVIDER_EXISTS);
}
return status;
}
my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync) my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync)
{ {
my_bool status = FALSE; my_bool status = FALSE;
if (thd_ptr) if (thd_ptr)
{ {
THD* thd = (THD*)thd_ptr; THD* thd = (THD*)thd_ptr;
if (sync) mysql_mutex_lock(&thd->LOCK_wsrep_thd); // THD can be BF only if provider exists
if (wsrep_thd_is_wsrep(thd_ptr))
status = ((thd->wsrep_exec_mode == REPL_RECV) || {
(thd->wsrep_exec_mode == TOTAL_ORDER)); if (sync)
if (sync) mysql_mutex_unlock(&thd->LOCK_wsrep_thd); mysql_mutex_lock(&thd->LOCK_wsrep_thd);
status = ((thd->wsrep_exec_mode == REPL_RECV) ||
(thd->wsrep_exec_mode == TOTAL_ORDER));
if (sync)
mysql_mutex_unlock(&thd->LOCK_wsrep_thd);
}
} }
return status; return status;
} }
......
...@@ -29,6 +29,8 @@ int wsrep_abort_thd(void *bf_thd_ptr, void *victim_thd_ptr, ...@@ -29,6 +29,8 @@ int wsrep_abort_thd(void *bf_thd_ptr, void *victim_thd_ptr,
extern void wsrep_thd_set_PA_safe(void *thd_ptr, my_bool safe); extern void wsrep_thd_set_PA_safe(void *thd_ptr, my_bool safe);
extern my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync); extern my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync);
extern my_bool wsrep_thd_is_wsrep(void *thd_ptr);
extern int wsrep_thd_conflict_state(void *thd_ptr, my_bool sync); extern int wsrep_thd_conflict_state(void *thd_ptr, my_bool sync);
//extern "C" my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync); //extern "C" my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync);
extern "C" my_bool wsrep_thd_is_BF_or_commit(void *thd_ptr, my_bool sync); extern "C" my_bool wsrep_thd_is_BF_or_commit(void *thd_ptr, my_bool sync);
......
...@@ -294,6 +294,7 @@ wsrep_innobase_kill_one_trx(void *thd_ptr, ...@@ -294,6 +294,7 @@ wsrep_innobase_kill_one_trx(void *thd_ptr,
my_bool wsrep_thd_set_PA_safe(void *thd_ptr, my_bool safe); my_bool wsrep_thd_set_PA_safe(void *thd_ptr, my_bool safe);
int wsrep_thd_conflict_state(void *thd_ptr, my_bool sync); int wsrep_thd_conflict_state(void *thd_ptr, my_bool sync);
my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync); my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync);
my_bool wsrep_thd_is_wsrep(void *thd_ptr);
int wsrep_trx_order_before(void *thd1, void *thd2); int wsrep_trx_order_before(void *thd1, void *thd2);
int wsrep_innobase_mysql_sort(int mysql_type, uint charset_number, int wsrep_innobase_mysql_sort(int mysql_type, uint charset_number,
unsigned char* str, unsigned int str_length, unsigned char* str, unsigned int str_length,
......
This diff is collapsed.
...@@ -10371,11 +10371,10 @@ ha_innobase::wsrep_append_keys( ...@@ -10371,11 +10371,10 @@ ha_innobase::wsrep_append_keys(
uint len; uint len;
char keyval[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'}; char keyval[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'};
char *key = &keyval[0]; char *key = &keyval[0];
KEY *key_info = table->key_info;
ibool is_null; ibool is_null;
len = wsrep_store_key_val_for_row( len = wsrep_store_key_val_for_row(
thd, table, 0, key, WSREP_MAX_SUPPORTED_KEY_LENGTH, thd, table, 0, key, WSREP_MAX_SUPPORTED_KEY_LENGTH,
record0, &is_null); record0, &is_null);
if (!is_null) { if (!is_null) {
...@@ -18218,34 +18217,34 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, ...@@ -18218,34 +18217,34 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
if (!thd) { if (!thd) {
DBUG_PRINT("wsrep", ("no thd for conflicting lock")); DBUG_PRINT("wsrep", ("no thd for conflicting lock"));
WSREP_WARN("no THD for trx: %llu", victim_trx->id); WSREP_WARN("no THD for trx: %lu", victim_trx->id);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
if (!bf_thd) { if (!bf_thd) {
DBUG_PRINT("wsrep", ("no BF thd for conflicting lock")); DBUG_PRINT("wsrep", ("no BF thd for conflicting lock"));
WSREP_WARN("no BF THD for trx: %llu", (bf_trx) ? bf_trx->id : 0); WSREP_WARN("no BF THD for trx: %lu", (bf_trx) ? bf_trx->id : 0);
DBUG_RETURN(1); DBUG_RETURN(1);
} }
WSREP_LOG_CONFLICT(bf_thd, thd, TRUE); WSREP_LOG_CONFLICT(bf_thd, thd, TRUE);
WSREP_DEBUG("BF kill (%lu, seqno: %lld), victim: (%lu) trx: %llu", WSREP_DEBUG("BF kill (%lu, seqno: %lld), victim: (%lu) trx: %lu",
signal, (long long)bf_seqno, signal, (long long)bf_seqno,
wsrep_thd_thread_id(thd), wsrep_thd_thread_id(thd),
victim_trx->id); victim_trx->id);
WSREP_DEBUG("Aborting query: %s", WSREP_DEBUG("Aborting query: %s",
(thd && wsrep_thd_query(thd)) ? wsrep_thd_query(thd) : "void"); (thd && wsrep_thd_query(thd)) ? wsrep_thd_query(thd) : "void");
wsrep_thd_LOCK(thd); wsrep_thd_LOCK(thd);
if (wsrep_thd_query_state(thd) == QUERY_EXITING) { if (wsrep_thd_query_state(thd) == QUERY_EXITING) {
WSREP_DEBUG("kill trx EXITING for %llu", victim_trx->id); WSREP_DEBUG("kill trx EXITING for %lu", victim_trx->id);
wsrep_thd_UNLOCK(thd); wsrep_thd_UNLOCK(thd);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
if(wsrep_thd_exec_mode(thd) != LOCAL_STATE) { if(wsrep_thd_exec_mode(thd) != LOCAL_STATE) {
WSREP_DEBUG("withdraw for BF trx: %llu, state: %d", WSREP_DEBUG("withdraw for BF trx: %lu, state: %d",
victim_trx->id, victim_trx->id,
wsrep_thd_conflict_state(thd)); wsrep_thd_conflict_state(thd));
} }
...@@ -18255,7 +18254,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, ...@@ -18255,7 +18254,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
wsrep_thd_set_conflict_state(thd, MUST_ABORT); wsrep_thd_set_conflict_state(thd, MUST_ABORT);
break; break;
case MUST_ABORT: case MUST_ABORT:
WSREP_DEBUG("victim %llu in MUST ABORT state", WSREP_DEBUG("victim %lu in MUST ABORT state",
victim_trx->id); victim_trx->id);
wsrep_thd_UNLOCK(thd); wsrep_thd_UNLOCK(thd);
wsrep_thd_awake(thd, signal); wsrep_thd_awake(thd, signal);
...@@ -18264,7 +18263,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, ...@@ -18264,7 +18263,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
case ABORTED: case ABORTED:
case ABORTING: // fall through case ABORTING: // fall through
default: default:
WSREP_DEBUG("victim %llu in state %d", WSREP_DEBUG("victim %lu in state %d",
victim_trx->id, wsrep_thd_conflict_state(thd)); victim_trx->id, wsrep_thd_conflict_state(thd));
wsrep_thd_UNLOCK(thd); wsrep_thd_UNLOCK(thd);
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -18277,7 +18276,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, ...@@ -18277,7 +18276,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
WSREP_DEBUG("kill query for: %ld", WSREP_DEBUG("kill query for: %ld",
wsrep_thd_thread_id(thd)); wsrep_thd_thread_id(thd));
WSREP_DEBUG("kill trx QUERY_COMMITTING for %llu", WSREP_DEBUG("kill trx QUERY_COMMITTING for %lu",
victim_trx->id); victim_trx->id);
if (wsrep_thd_exec_mode(thd) == REPL_RECV) { if (wsrep_thd_exec_mode(thd) == REPL_RECV) {
...@@ -18291,7 +18290,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, ...@@ -18291,7 +18290,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
switch (rcode) { switch (rcode) {
case WSREP_WARNING: case WSREP_WARNING:
WSREP_DEBUG("cancel commit warning: %llu", WSREP_DEBUG("cancel commit warning: %lu",
victim_trx->id); victim_trx->id);
wsrep_thd_UNLOCK(thd); wsrep_thd_UNLOCK(thd);
wsrep_thd_awake(thd, signal); wsrep_thd_awake(thd, signal);
...@@ -18301,8 +18300,8 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, ...@@ -18301,8 +18300,8 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
break; break;
default: default:
WSREP_ERROR( WSREP_ERROR(
"cancel commit bad exit: %d %llu", "cancel commit bad exit: %d %lu",
rcode, rcode,
victim_trx->id); victim_trx->id);
/* unable to interrupt, must abort */ /* unable to interrupt, must abort */
/* note: kill_mysql() will block, if we cannot. /* note: kill_mysql() will block, if we cannot.
...@@ -18316,10 +18315,10 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, ...@@ -18316,10 +18315,10 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
wsrep_thd_awake(thd, signal); wsrep_thd_awake(thd, signal);
break; break;
case QUERY_EXEC: case QUERY_EXEC:
/* it is possible that victim trx is itself waiting for some /* it is possible that victim trx is itself waiting for some
* other lock. We need to cancel this waiting * other lock. We need to cancel this waiting
*/ */
WSREP_DEBUG("kill trx QUERY_EXEC for %llu", victim_trx->id); WSREP_DEBUG("kill trx QUERY_EXEC for %lu", victim_trx->id);
victim_trx->lock.was_chosen_as_deadlock_victim= TRUE; victim_trx->lock.was_chosen_as_deadlock_victim= TRUE;
if (victim_trx->lock.wait_lock) { if (victim_trx->lock.wait_lock) {
...@@ -18336,7 +18335,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, ...@@ -18336,7 +18335,7 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
wsrep_thd_awake(thd, signal); wsrep_thd_awake(thd, signal);
} else { } else {
/* abort currently executing query */ /* abort currently executing query */
DBUG_PRINT("wsrep",("sending KILL_QUERY to: %ld", DBUG_PRINT("wsrep",("sending KILL_QUERY to: %ld",
wsrep_thd_thread_id(thd))); wsrep_thd_thread_id(thd)));
WSREP_DEBUG("kill query for: %ld", WSREP_DEBUG("kill query for: %ld",
wsrep_thd_thread_id(thd)); wsrep_thd_thread_id(thd));
...@@ -18356,8 +18355,8 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, ...@@ -18356,8 +18355,8 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
{ {
bool skip_abort= false; bool skip_abort= false;
wsrep_aborting_thd_t abortees; wsrep_aborting_thd_t abortees;
WSREP_DEBUG("kill IDLE for %llu", victim_trx->id); WSREP_DEBUG("kill IDLE for %lu", victim_trx->id);
if (wsrep_thd_exec_mode(thd) == REPL_RECV) { if (wsrep_thd_exec_mode(thd) == REPL_RECV) {
WSREP_DEBUG("kill BF IDLE, seqno: %lld", WSREP_DEBUG("kill BF IDLE, seqno: %lld",
...@@ -18377,14 +18376,14 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, ...@@ -18377,14 +18376,14 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
/* check if we have a kill message for this already */ /* check if we have a kill message for this already */
if (abortees->aborting_thd == thd) { if (abortees->aborting_thd == thd) {
skip_abort = true; skip_abort = true;
WSREP_WARN("duplicate thd aborter %lu", WSREP_WARN("duplicate thd aborter %lu",
wsrep_thd_thread_id(thd)); wsrep_thd_thread_id(thd));
} }
abortees = abortees->next; abortees = abortees->next;
} }
if (!skip_abort) { if (!skip_abort) {
wsrep_aborting_thd_t aborting = (wsrep_aborting_thd_t) wsrep_aborting_thd_t aborting = (wsrep_aborting_thd_t)
my_malloc(sizeof(struct wsrep_aborting_thd), my_malloc(sizeof(struct wsrep_aborting_thd),
MYF(0)); MYF(0));
aborting->aborting_thd = thd; aborting->aborting_thd = thd;
aborting->next = wsrep_aborting_thd; aborting->next = wsrep_aborting_thd;
...@@ -18404,22 +18403,22 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr, ...@@ -18404,22 +18403,22 @@ wsrep_innobase_kill_one_trx(void * const bf_thd_ptr,
break; break;
} }
default: default:
WSREP_WARN("bad wsrep query state: %d", WSREP_WARN("bad wsrep query state: %d",
wsrep_thd_query_state(thd)); wsrep_thd_query_state(thd));
wsrep_thd_UNLOCK(thd); wsrep_thd_UNLOCK(thd);
break; break;
} }
DBUG_RETURN(0); DBUG_RETURN(0);
} }
static int static int
wsrep_abort_transaction(handlerton* hton, THD *bf_thd, THD *victim_thd, wsrep_abort_transaction(handlerton* hton, THD *bf_thd, THD *victim_thd,
my_bool signal) my_bool signal)
{ {
DBUG_ENTER("wsrep_innobase_abort_thd"); DBUG_ENTER("wsrep_innobase_abort_thd");
trx_t* victim_trx = thd_to_trx(victim_thd); trx_t* victim_trx = thd_to_trx(victim_thd);
trx_t* bf_trx = (bf_thd) ? thd_to_trx(bf_thd) : NULL; trx_t* bf_trx = (bf_thd) ? thd_to_trx(bf_thd) : NULL;
WSREP_DEBUG("abort transaction: BF: %s victim: %s", WSREP_DEBUG("abort transaction: BF: %s victim: %s",
wsrep_thd_query(bf_thd), wsrep_thd_query(bf_thd),
wsrep_thd_query(victim_thd)); wsrep_thd_query(victim_thd));
...@@ -18439,7 +18438,7 @@ wsrep_abort_transaction(handlerton* hton, THD *bf_thd, THD *victim_thd, ...@@ -18439,7 +18438,7 @@ wsrep_abort_transaction(handlerton* hton, THD *bf_thd, THD *victim_thd,
wsrep_thd_LOCK(victim_thd); wsrep_thd_LOCK(victim_thd);
wsrep_thd_set_conflict_state(victim_thd, MUST_ABORT); wsrep_thd_set_conflict_state(victim_thd, MUST_ABORT);
wsrep_thd_UNLOCK(victim_thd); wsrep_thd_UNLOCK(victim_thd);
wsrep_thd_awake(victim_thd, signal); wsrep_thd_awake(victim_thd, signal);
} }
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
......
...@@ -293,6 +293,7 @@ wsrep_innobase_kill_one_trx(void *thd_ptr, ...@@ -293,6 +293,7 @@ wsrep_innobase_kill_one_trx(void *thd_ptr,
my_bool wsrep_thd_set_PA_safe(void *thd_ptr, my_bool safe); my_bool wsrep_thd_set_PA_safe(void *thd_ptr, my_bool safe);
int wsrep_thd_conflict_state(void *thd_ptr, my_bool sync); int wsrep_thd_conflict_state(void *thd_ptr, my_bool sync);
my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync); my_bool wsrep_thd_is_BF(void *thd_ptr, my_bool sync);
my_bool wsrep_thd_is_wsrep(void *thd_ptr);
int wsrep_trx_order_before(void *thd1, void *thd2); int wsrep_trx_order_before(void *thd1, void *thd2);
int wsrep_innobase_mysql_sort(int mysql_type, uint charset_number, int wsrep_innobase_mysql_sort(int mysql_type, uint charset_number,
unsigned char* str, unsigned int str_length, unsigned char* str, unsigned int str_length,
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment