diff options
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 40 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.h | 3 | ||||
-rw-r--r-- | storage/innobase/include/ha_prototypes.h | 2 | ||||
-rw-r--r-- | storage/innobase/lock/lock0lock.c | 59 | ||||
-rw-r--r-- | storage/innobase/rem/rem0rec.c | 4 |
5 files changed, 74 insertions, 34 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index e1f18c84800..a1b7eab5deb 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -927,6 +927,8 @@ innobase_release_temporary_latches( static int wsrep_abort_transaction(handlerton* hton, THD *bf_thd, THD *victim_thd, my_bool signal); +static void +wsrep_fake_trx_id(handlerton* hton, THD *thd); static int innobase_wsrep_set_checkpoint(handlerton* hton, const XID* xid); static int innobase_wsrep_get_checkpoint(handlerton* hton, XID* xid); #endif @@ -2317,6 +2319,7 @@ innobase_init( innobase_hton->wsrep_abort_transaction=wsrep_abort_transaction; innobase_hton->wsrep_set_checkpoint=innobase_wsrep_set_checkpoint; innobase_hton->wsrep_get_checkpoint=innobase_wsrep_get_checkpoint; + innobase_hton->wsrep_fake_trx_id=wsrep_fake_trx_id; #endif /* WITH_WSREP */ ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR); @@ -7004,7 +7007,12 @@ wsrep_append_foreign_key( &key[1], &len, rec, index, wsrep_protocol_version > 1); if (rcode != DB_SUCCESS) { - WSREP_ERROR("FK key set failed: %lu", rcode); + WSREP_ERROR( + "FK key set failed: %lu (%lu %lu), index: %s %s, %s", + rcode, referenced, shared, + (index->name) ? index->name : "void index", + (index->table_name) ? index->table_name : "void table", + wsrep_thd_query(thd)); return rcode; } strncpy(cache_key, @@ -12168,18 +12176,27 @@ wsrep_abort_slave_trx(wsrep_seqno_t bf_seqno, wsrep_seqno_t victim_seqno) abort(); } int -wsrep_innobase_kill_one_trx(trx_t *bf_trx, trx_t *victim_trx, ibool signal) +wsrep_innobase_kill_one_trx(void *bf_thd_ptr, trx_t *bf_trx, trx_t *victim_trx, ibool signal) { DBUG_ENTER("wsrep_innobase_kill_one_trx"); + THD *bf_thd = (THD *)bf_thd_ptr; THD *thd = (THD *) victim_trx->mysql_thd; - THD *bf_thd = (bf_trx) ? (THD *)bf_trx->mysql_thd : NULL; int64_t bf_seqno = (bf_thd) ? wsrep_thd_trx_seqno(bf_thd) : 0; + if (!bf_thd) bf_thd = (bf_trx) ? (THD *)bf_trx->mysql_thd : NULL; + if (!thd) { DBUG_PRINT("wsrep", ("no thd for conflicting lock")); WSREP_WARN("no THD for trx: %llu", victim_trx->id); DBUG_RETURN(1); } + if (!bf_thd) { + DBUG_PRINT("wsrep", ("no BF thd for conflicting lock")); + WSREP_WARN("no BF THD for trx: %llu", (bf_trx) ? bf_trx->id : 0); + DBUG_RETURN(1); + } + + WSREP_LOG_CONFLICT(bf_thd, thd, TRUE); WSREP_DEBUG("BF kill (%lu, seqno: %lld), victim: (%lu) trx: %llu", signal, (long long)bf_seqno, @@ -12368,8 +12385,8 @@ wsrep_abort_transaction(handlerton* hton, THD *bf_thd, THD *victim_thd, if (victim_trx) { mutex_enter(&kernel_mutex); - int rcode = wsrep_innobase_kill_one_trx(bf_trx, victim_trx, - signal); + int rcode = wsrep_innobase_kill_one_trx( + bf_thd, bf_trx, victim_trx, signal); mutex_exit(&kernel_mutex); DBUG_RETURN(rcode); } else { @@ -12403,6 +12420,19 @@ static int innobase_wsrep_get_checkpoint(handlerton* hton, XID* xid) return 0; } +static void +wsrep_fake_trx_id( +/*==================*/ + handlerton *hton, + THD *thd) /*!< in: user thread handle */ +{ + mutex_enter(&kernel_mutex); + trx_id_t trx_id = trx_sys_get_new_trx_id(); + mutex_exit(&kernel_mutex); + + (void *)wsrep_trx_handle_for_id(wsrep_thd_trx_handle(thd), trx_id); +} + #endif /* WITH_WSREP */ /* plugin options */ static MYSQL_SYSVAR_BOOL(checksums, innobase_use_checksums, diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 8f211d6e38c..aa653adcabf 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -304,6 +304,9 @@ extern "C" bool wsrep_thd_is_wsrep_on(THD *thd); extern "C" enum wsrep_exec_mode wsrep_thd_exec_mode(THD *thd); extern "C" enum wsrep_conflict_state wsrep_thd_conflict_state(THD *thd); extern "C" enum wsrep_query_state wsrep_thd_query_state(THD *thd); +extern "C" const char * wsrep_thd_exec_mode_str(THD *thd); +extern "C" const char * wsrep_thd_conflict_state_str(THD *thd); +extern "C" const char * wsrep_thd_query_state_str(THD *thd); extern "C" wsrep_trx_handle_t* wsrep_thd_trx_handle(THD *thd); extern "C" void wsrep_thd_set_exec_mode(THD *thd, enum wsrep_exec_mode mode); diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 4ac365d5c40..664e18c52a8 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -288,7 +288,7 @@ thd_set_lock_wait_time( #ifdef WITH_WSREP UNIV_INTERN int -wsrep_innobase_kill_one_trx(trx_t *bf_trx, trx_t *victim_trx, ibool signal); +wsrep_innobase_kill_one_trx(void *bf_thd, trx_t *bf_trx, trx_t *victim_trx, ibool signal); int wsrep_thd_is_brute_force(void *thd_ptr); int wsrep_trx_order_before(void *thd1, void *thd2); void wsrep_innobase_mysql_sort(int mysql_type, uint charset_number, diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index b24bd05e0b3..bb864937751 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -42,6 +42,7 @@ Created 5/7/1996 Heikki Tuuri #ifdef WITH_WSREP extern my_bool wsrep_debug; +extern my_bool wsrep_log_conflicts; #endif /* Restricts the length of search we will do in the waits-for graph of transactions */ @@ -1528,7 +1529,34 @@ wsrep_kill_victim(trx_t *trx, lock_t *lock) { /* cannot release lock, until our lock is in the queue*/ } else if (lock->trx != trx) { - wsrep_innobase_kill_one_trx(trx, lock->trx, TRUE); + if (wsrep_log_conflicts) { + if (bf_this) + fputs("\n*** Priority TRANSACTION:\n", + stderr); + else + fputs("\n*** Victim TRANSACTION:\n", + stderr); + trx_print(stderr, trx, 3000); + + if (bf_other) + fputs("\n*** Priority TRANSACTION:\n", + stderr); + else + fputs("\n*** Victim TRANSACTION:\n", + stderr); + trx_print(stderr, lock->trx, 3000); + + fputs("*** WAITING FOR THIS LOCK TO BE GRANTED:\n", + stderr); + + if (lock_get_type(lock) == LOCK_REC) { + lock_rec_print(stderr, lock); + } else { + lock_table_print(stderr, lock); + } + } + wsrep_innobase_kill_one_trx( + trx->mysql_thd, trx, lock->trx, TRUE); } } } @@ -4091,33 +4119,12 @@ lock_table_other_has_incompatible( if ((lock->trx != trx) && (!lock_mode_compatible(lock_get_mode(lock), mode)) && (wait || !(lock_get_wait(lock)))) { - #ifdef WITH_WSREP - int bf_this = wsrep_thd_is_brute_force(trx->mysql_thd); - int bf_other = wsrep_thd_is_brute_force( - lock->trx->mysql_thd); - if ((bf_this && !bf_other) || - (bf_this && bf_other && - wsrep_trx_order_before( - trx->mysql_thd, lock->trx->mysql_thd) - ) - ) { - if (lock->trx->que_state == TRX_QUE_LOCK_WAIT) { - if (wsrep_debug) fprintf(stderr, - "WSREP: BF victim waiting"); - return(lock); - } else { - if (bf_this && bf_other) - wsrep_innobase_kill_one_trx( - (trx_t *)trx, lock->trx, TRUE); - return(lock); - } - } else { - return(lock); - } -#else - return(lock); + if (wsrep_debug) + fprintf(stderr, "WSREP: table lock abort"); + wsrep_kill_victim((trx_t *)trx, (lock_t *)lock); #endif + return(lock); } lock = UT_LIST_GET_PREV(un_member.tab_lock.locks, lock); diff --git a/storage/innobase/rem/rem0rec.c b/storage/innobase/rem/rem0rec.c index 0cee1ffb3c8..44249c3a87e 100644 --- a/storage/innobase/rem/rem0rec.c +++ b/storage/innobase/rem/rem0rec.c @@ -1811,8 +1811,8 @@ wsrep_rec_get_primary_key( const dict_col_t* col = dict_field_get_col(field); data = rec_get_nth_field(rec, offsets, i, &len); - if (key_len + len > ((col->prtype & DATA_NOT_NULL) ? - *buf_len : *buf_len - 1)) { + if (key_len + ((len != UNIV_SQL_NULL) ? len + 1 : 1) > + *buf_len) { fprintf (stderr, "WSREP: FK key len exceeded %lu %lu %lu\n", key_len, len, *buf_len); |