diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-05-26 11:54:55 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-05-26 11:54:55 +0300 |
commit | ca38b6e42791a6edbd3cc0b626a8d06b7776e76b (patch) | |
tree | f0b9f34521554ce94ef9a5bd6c7e5f595459240f /storage | |
parent | ea7830eef48333e28f98a9b91f05a95735b465a3 (diff) | |
parent | 7476e8c7cdd73d60294126a2840baee97e7644b6 (diff) | |
download | mariadb-git-ca38b6e42791a6edbd3cc0b626a8d06b7776e76b.tar.gz |
Merge 10.3 into 10.4
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 30 | ||||
-rw-r--r-- | storage/innobase/include/ut0pool.h | 10 | ||||
-rw-r--r-- | storage/innobase/row/row0log.cc | 18 | ||||
-rw-r--r-- | storage/innobase/trx/trx0trx.cc | 22 |
4 files changed, 63 insertions, 17 deletions
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 4c2b4fb2693..e9c555e3ffc 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -3395,7 +3395,7 @@ ha_innobase::reset_template(void) /* Force table to be freed in close_thread_table(). */ DBUG_EXECUTE_IF("free_table_in_fts_query", if (m_prebuilt->in_fts_query) { - table->m_needs_reopen = true; + table->mark_table_for_reopen(); } ); @@ -5093,9 +5093,8 @@ static void innobase_kill_query(handlerton*, THD *thd, enum thd_kill_levels) { DBUG_ENTER("innobase_kill_query"); - if (trx_t *trx= thd_to_trx(thd)) + if (trx_t* trx= thd_to_trx(thd)) { - ut_ad(trx->mysql_thd == thd); #ifdef WITH_WSREP if (trx->is_wsrep() && wsrep_thd_is_aborting(thd)) /* if victim has been signaled by BF thread and/or aborting is already @@ -5103,8 +5102,29 @@ static void innobase_kill_query(handlerton*, THD *thd, enum thd_kill_levels) Also, BF thread should own trx mutex for the victim. */ DBUG_VOID_RETURN; #endif /* WITH_WSREP */ - /* Cancel a pending lock request if there are any */ - lock_trx_handle_wait(trx); + lock_mutex_enter(); + mutex_enter(&trx_sys.mutex); + trx_mutex_enter(trx); + /* It is possible that innobase_close_connection() is concurrently + being executed on our victim. Even if the trx object is later + reused for another client connection or a background transaction, + its trx->mysql_thd will differ from our thd. + + trx_t::state changes are protected by trx_t::mutex, and + trx_sys.trx_list is protected by trx_sys.mutex, in + both trx_create() and trx_free(). + + At this point, trx may have been reallocated for another client + connection, or for a background operation. In that case, either + trx_t::state or trx_t::mysql_thd should not match our expectations. */ + bool cancel= trx->mysql_thd == thd && trx->state == TRX_STATE_ACTIVE && + !trx->lock.was_chosen_as_deadlock_victim; + mutex_exit(&trx_sys.mutex); + if (!cancel); + else if (lock_t *lock= trx->lock.wait_lock) + lock_cancel_waiting_and_release(lock); + lock_mutex_exit(); + trx_mutex_exit(trx); } DBUG_VOID_RETURN; diff --git a/storage/innobase/include/ut0pool.h b/storage/innobase/include/ut0pool.h index 02a4e16bb70..f6006144dc4 100644 --- a/storage/innobase/include/ut0pool.h +++ b/storage/innobase/include/ut0pool.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2013, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2018, 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -86,11 +87,15 @@ struct Pool { for (Element* elem = m_start; elem != m_last; ++elem) { ut_ad(elem->m_pool == this); +#ifdef __SANITIZE_ADDRESS__ /* Unpoison the memory for AddressSanitizer */ MEM_UNDEFINED(&elem->m_type, sizeof elem->m_type); +#endif +#ifdef HAVE_valgrind /* Declare the contents as initialized for Valgrind; we checked this in mem_free(). */ UNIV_MEM_VALID(&elem->m_type, sizeof elem->m_type); +#endif Factory::destroy(&elem->m_type); } @@ -127,13 +132,18 @@ struct Pool { #if defined HAVE_valgrind || defined __SANITIZE_ADDRESS__ if (elem) { +# ifdef __SANITIZE_ADDRESS__ /* Unpoison the memory for AddressSanitizer */ MEM_UNDEFINED(&elem->m_type, sizeof elem->m_type); +# endif +# ifdef HAVE_valgrind + /* Declare the memory initialized for Valgrind. The trx_t that are released to the pool are actually initialized; we checked that by UNIV_MEM_ASSERT_RW() in mem_free() below. */ UNIV_MEM_VALID(&elem->m_type, sizeof elem->m_type); +# endif } #endif diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 60b8fdf06b2..eece00fc267 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -1177,19 +1177,15 @@ row_log_table_get_pk_col( return(DB_INVALID_NULL); } - ulint new_i = dict_col_get_clust_pos(ifield->col, index); - - if (UNIV_UNLIKELY(new_i >= log->defaults->n_fields)) { - ut_ad(0); - return DB_INVALID_NULL; - } + unsigned col_no= ifield->col->ind; + ut_ad(col_no < log->defaults->n_fields); field = static_cast<const byte*>( - log->defaults->fields[new_i].data); + log->defaults->fields[col_no].data); if (!field) { return(DB_INVALID_NULL); } - len = log->defaults->fields[new_i].len; + len = log->defaults->fields[col_no].len; } if (rec_offs_nth_extern(offsets, i)) { @@ -1671,10 +1667,12 @@ blob_done: const dfield_t& default_field = log->defaults->fields[col_no]; - Field* field = log->old_table->field[col_no]; + + Field* field = log->old_table->field[col->ind]; field->set_warning(Sql_condition::WARN_LEVEL_WARN, - WARN_DATA_TRUNCATED, 1, ulong(log->n_rows)); + WARN_DATA_TRUNCATED, 1, + ulong(log->n_rows)); if (!log->allow_not_null) { /* We got a NULL value for a NOT NULL column. */ diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index 276a78d00bf..d78cbcac521 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -455,12 +455,30 @@ void trx_free(trx_t*& trx) ut_ad(trx->will_lock == 0); trx_pools->mem_free(trx); +#ifdef __SANITIZE_ADDRESS__ /* Unpoison the memory for innodb_monitor_set_option; it is operating also on the freed transaction objects. */ MEM_UNDEFINED(&trx->mutex, sizeof trx->mutex); - /* Declare the contents as initialized for Valgrind; - we checked that it was initialized in trx_pools->mem_free(trx). */ + /* For innobase_kill_connection() */ +# ifdef WITH_WSREP + MEM_UNDEFINED(&trx->wsrep, sizeof trx->wsrep); +# endif + MEM_UNDEFINED(&trx->state, sizeof trx->state); + MEM_UNDEFINED(&trx->mysql_thd, sizeof trx->mysql_thd); +#endif +#ifdef HAVE_valgrind + /* Unpoison the memory for innodb_monitor_set_option; + it is operating also on the freed transaction objects. + We checked that these were initialized in + trx_pools->mem_free(trx). */ UNIV_MEM_VALID(&trx->mutex, sizeof trx->mutex); + /* For innobase_kill_connection() */ +# ifdef WITH_WSREP + UNIV_MEM_VALID(&trx->wsrep, sizeof trx->wsrep); +# endif + UNIV_MEM_VALID(&trx->state, sizeof trx->state); + UNIV_MEM_VALID(&trx->mysql_thd, sizeof trx->mysql_thd); +#endif trx = NULL; } |