diff options
author | Daniel Black <daniel@mariadb.org> | 2022-03-25 15:06:56 +1100 |
---|---|---|
committer | Daniel Black <daniel@mariadb.org> | 2022-03-25 15:06:56 +1100 |
commit | 88ce8a3d8be0346b325bc4da75894cd15e255857 (patch) | |
tree | 1e827eb908eaa737225017627beafa2b6d8e9959 /storage/innobase | |
parent | f6fcf827b379fc069563d1896850fbfcebaa983e (diff) | |
parent | 13b97880bd8f6901225a1f8d6ff2eb6ba9303ceb (diff) | |
download | mariadb-git-88ce8a3d8be0346b325bc4da75894cd15e255857.tar.gz |
Merge 10.7 into 10.8
Diffstat (limited to 'storage/innobase')
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 41 | ||||
-rw-r--r-- | storage/innobase/buf/buf0rea.cc | 57 | ||||
-rw-r--r-- | storage/innobase/dict/dict0load.cc | 84 | ||||
-rw-r--r-- | storage/innobase/fts/fts0fts.cc | 9 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 32 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 4 | ||||
-rw-r--r-- | storage/innobase/include/buf0buf.h | 7 | ||||
-rw-r--r-- | storage/innobase/include/dict0load.h | 7 | ||||
-rw-r--r-- | storage/innobase/include/lock0lock.h | 18 | ||||
-rw-r--r-- | storage/innobase/include/trx0purge.h | 6 | ||||
-rw-r--r-- | storage/innobase/lock/lock0lock.cc | 82 | ||||
-rw-r--r-- | storage/innobase/row/row0import.cc | 6 | ||||
-rw-r--r-- | storage/innobase/row/row0merge.cc | 18 | ||||
-rw-r--r-- | storage/innobase/srv/srv0start.cc | 2 | ||||
-rw-r--r-- | storage/innobase/trx/trx0rec.cc | 3 |
15 files changed, 184 insertions, 192 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 688be3722bf..f0cde7a4055 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -2259,29 +2259,66 @@ buf_page_t* buf_page_get_zip(const page_id_t page_id, ulint zip_size) lookup: for (bool discard_attempted= false;;) { +#ifndef NO_ELISION + if (xbegin()) { - transactional_shared_lock_guard<page_hash_latch> g{hash_lock}; + if (hash_lock.is_locked()) + xabort(); bpage= buf_pool.page_hash.get(page_id, chain); if (!bpage || buf_pool.watch_is_sentinel(*bpage)) + { + xend(); goto must_read_page; + } + if (!bpage->zip.data) + { + /* There is no ROW_FORMAT=COMPRESSED page. */ + xend(); + return nullptr; + } + if (discard_attempted || !bpage->frame) + { + if (!bpage->lock.s_lock_try()) + xabort(); + xend(); + break; + } + xend(); + } + else +#endif + { + hash_lock.lock_shared(); + bpage= buf_pool.page_hash.get(page_id, chain); + if (!bpage || buf_pool.watch_is_sentinel(*bpage)) + { + hash_lock.unlock_shared(); + goto must_read_page; + } ut_ad(bpage->in_file()); ut_ad(page_id == bpage->id()); if (!bpage->zip.data) + { /* There is no ROW_FORMAT=COMPRESSED page. */ + hash_lock.unlock_shared(); return nullptr; + } if (discard_attempted || !bpage->frame) { - /* Even when we are holding a page_hash latch, it should be + /* Even when we are holding a hash_lock, it should be acceptable to wait for a page S-latch here, because buf_page_t::read_complete() will not wait for buf_pool.mutex, and because S-latch would not conflict with a U-latch that would be protecting buf_page_t::write_complete(). */ bpage->lock.s_lock(); + hash_lock.unlock_shared(); break; } + + hash_lock.unlock_shared(); } discard_attempted= true; diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc index f1cb34dd5f3..d3a221814ad 100644 --- a/storage/innobase/buf/buf0rea.cc +++ b/storage/innobase/buf/buf0rea.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2021, MariaDB Corporation. +Copyright (c) 2015, 2022, 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 @@ -50,19 +50,30 @@ i/o-fixed buffer blocks */ /** Remove the sentinel block for the watch before replacing it with a real block. watch_unset() or watch_occurred() will notice that the block has been replaced with the real block. -@param watch sentinel -@param chain locked hash table chain */ -inline void buf_pool_t::watch_remove(buf_page_t *watch, - buf_pool_t::hash_chain &chain) +@param w sentinel +@param chain locked hash table chain +@return w->state() */ +inline uint32_t buf_pool_t::watch_remove(buf_page_t *w, + buf_pool_t::hash_chain &chain) { mysql_mutex_assert_owner(&buf_pool.mutex); - ut_ad(page_hash.lock_get(chain).is_write_locked()); - ut_a(watch_is_sentinel(*watch)); - if (watch->buf_fix_count()) - page_hash.remove(chain, watch); - ut_ad(!watch->in_page_hash); - watch->set_state(buf_page_t::NOT_USED); - watch->id_= page_id_t(~0ULL); + ut_ad(xtest() || page_hash.lock_get(chain).is_write_locked()); + ut_ad(w >= &watch[0]); + ut_ad(w < &watch[array_elements(watch)]); + ut_ad(!w->in_zip_hash); + ut_ad(!w->zip.data); + + uint32_t s{w->state()}; + w->set_state(buf_page_t::NOT_USED); + ut_ad(s >= buf_page_t::UNFIXED); + ut_ad(s < buf_page_t::READ_FIX); + + if (~buf_page_t::LRU_MASK & s) + page_hash.remove(chain, w); + + ut_ad(!w->in_page_hash); + w->id_= page_id_t(~0ULL); + return s; } /** Initialize a page for read to the buffer buf_pool. If the page is @@ -139,14 +150,8 @@ static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id, {buf_pool.page_hash.lock_get(chain)}; if (hash_page) - { - /* Preserve the reference count. */ - uint32_t buf_fix_count= hash_page->state(); - ut_a(buf_fix_count >= buf_page_t::UNFIXED); - ut_a(buf_fix_count < buf_page_t::READ_FIX); - buf_pool.watch_remove(hash_page, chain); - block->page.fix(buf_fix_count - buf_page_t::UNFIXED); - } + bpage->set_state(buf_pool.watch_remove(hash_page, chain) + + (buf_page_t::READ_FIX - buf_page_t::UNFIXED)); buf_pool.page_hash.append(chain, &block->page); } @@ -209,16 +214,8 @@ static buf_page_t* buf_page_init_for_read(ulint mode, const page_id_t page_id, {buf_pool.page_hash.lock_get(chain)}; if (hash_page) - { - /* Preserve the reference count. It can be 0 if - buf_pool_t::watch_unset() is executing concurrently, - waiting for buf_pool.mutex, which we are holding. */ - uint32_t buf_fix_count= hash_page->state(); - ut_a(buf_fix_count >= buf_page_t::UNFIXED); - ut_a(buf_fix_count < buf_page_t::READ_FIX); - bpage->fix(buf_fix_count - buf_page_t::UNFIXED); - buf_pool.watch_remove(hash_page, chain); - } + bpage->set_state(buf_pool.watch_remove(hash_page, chain) + + (buf_page_t::READ_FIX - buf_page_t::UNFIXED)); buf_pool.page_hash.append(chain, bpage); } diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index bcc63a5e38a..58b219b452a 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -2076,74 +2076,26 @@ const char *dict_load_table_low(const span<const char> &name, return(NULL); } -/********************************************************************//** -Using the table->heap, copy the null-terminated filepath into -table->data_dir_path and replace the 'databasename/tablename.ibd' -portion with 'tablename'. -This allows SHOW CREATE TABLE to return the correct DATA DIRECTORY path. -Make this data directory path only if it has not yet been saved. */ -static -void -dict_save_data_dir_path( -/*====================*/ - dict_table_t* table, /*!< in/out: table */ - const char* filepath) /*!< in: filepath of tablespace */ -{ - ut_ad(dict_sys.frozen()); - ut_a(DICT_TF_HAS_DATA_DIR(table->flags)); - - ut_a(!table->data_dir_path); - ut_a(filepath); - - /* Be sure this filepath is not the default filepath. */ - if (char* default_filepath = fil_make_filepath(nullptr, table->name, - IBD, false)) { - if (0 != strcmp(filepath, default_filepath)) { - ulint pathlen = strlen(filepath); - ut_a(pathlen < OS_FILE_MAX_PATH); - ut_a(0 == strcmp(filepath + pathlen - 4, DOT_IBD)); - - table->data_dir_path = mem_heap_strdup( - table->heap, filepath); - os_file_make_data_dir_path(table->data_dir_path); - } - - ut_free(default_filepath); - } -} - /** Make sure the data_file_name is saved in dict_table_t if needed. -@param[in,out] table Table object -@param[in] dict_locked dict_sys.frozen() */ -void dict_get_and_save_data_dir_path(dict_table_t* table, bool dict_locked) +@param[in,out] table Table object */ +void dict_get_and_save_data_dir_path(dict_table_t *table) { - ut_ad(!table->is_temporary()); - ut_ad(!table->space || table->space->id == table->space_id); - - if (!table->data_dir_path && table->space_id && table->space) { - if (!dict_locked) { - dict_sys.freeze(SRW_LOCK_CALL); - } - - table->flags |= 1 << DICT_TF_POS_DATA_DIR - & ((1U << DICT_TF_BITS) - 1); - dict_save_data_dir_path(table, - table->space->chain.start->name); - - if (table->data_dir_path == NULL) { - /* Since we did not set the table data_dir_path, - unset the flag. This does not change - SYS_TABLES or FSP_SPACE_FLAGS on the header page - of the tablespace, but it makes dict_table_t - consistent. */ - table->flags &= ~DICT_TF_MASK_DATA_DIR - & ((1U << DICT_TF_BITS) - 1); - } + ut_ad(!table->is_temporary()); + ut_ad(!table->space || table->space->id == table->space_id); - if (!dict_locked) { - dict_sys.unfreeze(); - } - } + if (!table->data_dir_path && table->space_id && table->space) + { + const char *filepath= table->space->chain.start->name; + if (strncmp(fil_path_to_mysql_datadir, filepath, + strlen(fil_path_to_mysql_datadir))) + { + table->lock_mutex_lock(); + table->flags|= 1 << DICT_TF_POS_DATA_DIR & ((1U << DICT_TF_BITS) - 1); + table->data_dir_path= mem_heap_strdup(table->heap, filepath); + os_file_make_data_dir_path(table->data_dir_path); + table->lock_mutex_unlock(); + } + } } /** Opens a tablespace for dict_load_table_one() @@ -2197,7 +2149,7 @@ dict_load_tablespace( char* filepath = NULL; if (DICT_TF_HAS_DATA_DIR(table->flags)) { /* This will set table->data_dir_path from fil_system */ - dict_get_and_save_data_dir_path(table, true); + dict_get_and_save_data_dir_path(table); if (table->data_dir_path) { filepath = fil_make_filepath( diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index c7004e0c8e8..b77623bc5e1 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1567,10 +1567,13 @@ static void fts_table_no_ref_count(const char *table_name) /** Stop the purge thread and check n_ref_count of all auxiliary and common table associated with the fts table. -@param table parent FTS table */ -void purge_sys_t::stop_FTS(const dict_table_t &table) +@param table parent FTS table +@param already_stopped True indicates purge threads were + already stopped*/ +void purge_sys_t::stop_FTS(const dict_table_t &table, bool already_stopped) { - purge_sys.stop_FTS(); + if (!already_stopped) + purge_sys.stop_FTS(); fts_table_t fts_table; char table_name[MAX_FULL_NAME_LEN]; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 5190e90fb9a..c9e67bde430 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -11361,7 +11361,7 @@ ha_innobase::update_create_info( return; } - dict_get_and_save_data_dir_path(m_prebuilt->table, false); + dict_get_and_save_data_dir_path(m_prebuilt->table); if (m_prebuilt->table->data_dir_path) { create_info->data_file_name = m_prebuilt->table->data_dir_path; @@ -13483,29 +13483,26 @@ int ha_innobase::delete_table(const char *name) dict_sys.unfreeze(); } - auto &timeout= THDVAR(thd, lock_wait_timeout); - const auto save_timeout= timeout; - if (table->name.is_temporary()) - timeout= 0; + const bool skip_wait{table->name.is_temporary()}; if (table_stats && index_stats && !strcmp(table_stats->name.m_name, TABLE_STATS_NAME) && !strcmp(index_stats->name.m_name, INDEX_STATS_NAME) && - !(err= lock_table_for_trx(table_stats, trx, LOCK_X))) - err= lock_table_for_trx(index_stats, trx, LOCK_X); + !(err= lock_table_for_trx(table_stats, trx, LOCK_X, skip_wait))) + err= lock_table_for_trx(index_stats, trx, LOCK_X, skip_wait); - if (err != DB_SUCCESS && !timeout) + if (err != DB_SUCCESS && skip_wait) { /* We may skip deleting statistics if we cannot lock the tables, when the table carries a temporary name. */ + ut_ad(err == DB_LOCK_WAIT); + ut_ad(trx->error_state == DB_SUCCESS); err= DB_SUCCESS; dict_table_close(table_stats, false, thd, mdl_table); dict_table_close(index_stats, false, thd, mdl_index); table_stats= nullptr; index_stats= nullptr; } - - timeout= save_timeout; } if (err == DB_SUCCESS) @@ -13778,7 +13775,7 @@ int ha_innobase::truncate() mem_heap_t* heap = mem_heap_create(1000); - dict_get_and_save_data_dir_path(ib_table, false); + dict_get_and_save_data_dir_path(ib_table); info.data_file_name = ib_table->data_dir_path; const char* temp_name = dict_mem_create_temporary_tablename( heap, ib_table->name.m_name, ib_table->id); @@ -14011,17 +14008,15 @@ ha_innobase::rename_table( if (error == DB_SUCCESS && table_stats && index_stats && !strcmp(table_stats->name.m_name, TABLE_STATS_NAME) && !strcmp(index_stats->name.m_name, INDEX_STATS_NAME)) { - auto &timeout = THDVAR(thd, lock_wait_timeout); - const auto save_timeout = timeout; - if (from_temp) { - timeout = 0; - } - error = lock_table_for_trx(table_stats, trx, LOCK_X); + error = lock_table_for_trx(table_stats, trx, LOCK_X, + from_temp); if (error == DB_SUCCESS) { error = lock_table_for_trx(index_stats, trx, - LOCK_X); + LOCK_X, from_temp); } if (error != DB_SUCCESS && from_temp) { + ut_ad(error == DB_LOCK_WAIT); + ut_ad(trx->error_state == DB_SUCCESS); error = DB_SUCCESS; /* We may skip renaming statistics if we cannot lock the tables, when the @@ -14034,7 +14029,6 @@ ha_innobase::rename_table( table_stats = nullptr; index_stats = nullptr; } - timeout = save_timeout; } } diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 703e4379d8c..d4c31f06616 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -10922,12 +10922,14 @@ ha_innobase::commit_inplace_alter_table( } } + bool already_stopped= false; for (inplace_alter_handler_ctx** pctx = ctx_array; *pctx; pctx++) { auto ctx = static_cast<ha_innobase_inplace_ctx*>(*pctx); dberr_t error = DB_SUCCESS; if (fts_exist) { - purge_sys.stop_FTS(*ctx->old_table); + purge_sys.stop_FTS(*ctx->old_table, already_stopped); + already_stopped = true; } if (new_clustered && ctx->old_table->fts) { diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index e2b226b9e5c..f8b960910af 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -1526,9 +1526,10 @@ public: /** Remove the sentinel block for the watch before replacing it with a real block. watch_unset() or watch_occurred() will notice that the block has been replaced with the real block. - @param watch sentinel - @param chain locked hash table chain */ - inline void watch_remove(buf_page_t *watch, hash_chain &chain); + @param w sentinel + @param chain locked hash table chain + @return w->state() */ + inline uint32_t watch_remove(buf_page_t *w, hash_chain &chain); /** @return whether less than 1/4 of the buffer pool is available */ TPOOL_SUPPRESS_TSAN diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h index 072773694a9..43e732263fd 100644 --- a/storage/innobase/include/dict0load.h +++ b/storage/innobase/include/dict0load.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2021, MariaDB Corporation. +Copyright (c) 2017, 2022, 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 @@ -53,9 +53,8 @@ We also scan the biggest space id, and store it to fil_system. */ void dict_check_tablespaces_and_store_max_id(); /** Make sure the data_file_name is saved in dict_table_t if needed. -@param[in,out] table Table object -@param[in] dict_locked dict_sys.frozen() */ -void dict_get_and_save_data_dir_path(dict_table_t* table, bool dict_locked); +@param[in,out] table Table object */ +void dict_get_and_save_data_dir_path(dict_table_t* table); /***********************************************************************//** Loads a table object based on the table id. diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index 28d75517d45..e4ceff6dec2 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -394,15 +394,13 @@ lock_table( void lock_table_resurrect(dict_table_t *table, trx_t *trx, lock_mode mode); /** Sets a lock on a table based on the given mode. -@param[in] table table to lock -@param[in,out] trx transaction -@param[in] mode LOCK_X or LOCK_S -@return error code or DB_SUCCESS. */ -dberr_t -lock_table_for_trx( - dict_table_t* table, - trx_t* trx, - enum lock_mode mode) +@param table table to lock +@param trx transaction +@param mode LOCK_X or LOCK_S +@param no_wait whether to skip handling DB_LOCK_WAIT +@return error code */ +dberr_t lock_table_for_trx(dict_table_t *table, trx_t *trx, lock_mode mode, + bool no_wait= false) MY_ATTRIBUTE((nonnull, warn_unused_result)); /** Exclusively lock the data dictionary tables. @@ -915,10 +913,8 @@ public: @param page whether to discard also from lock_sys.prdt_hash */ void prdt_page_free_from_discard(const page_id_t id, bool all= false); -#ifdef WITH_WSREP /** Cancel possible lock waiting for a transaction */ static void cancel_lock_wait_for_trx(trx_t *trx); -#endif /* WITH_WSREP */ }; /** The lock system */ diff --git a/storage/innobase/include/trx0purge.h b/storage/innobase/include/trx0purge.h index dc032cdf73a..b3f2fbeedf3 100644 --- a/storage/innobase/include/trx0purge.h +++ b/storage/innobase/include/trx0purge.h @@ -286,8 +286,10 @@ public: /** Stop the purge thread and check n_ref_count of all auxiliary and common table associated with the fts table. - @param table parent FTS table */ - void stop_FTS(const dict_table_t &table); + @param table parent FTS table + @param already_stopped True indicates purge threads were + already stopped */ + void stop_FTS(const dict_table_t &table, bool already_stopped=false); }; /** The global data structure coordinating a purge */ diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index fa1ea357fe6..f920ac1ac95 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -3627,52 +3627,50 @@ static void lock_table_dequeue(lock_t *in_lock, bool owns_wait_mutex) } } -/** Sets a lock on a table based on the given mode. -@param[in] table table to lock -@param[in,out] trx transaction -@param[in] mode LOCK_X or LOCK_S -@return error code or DB_SUCCESS. */ -dberr_t -lock_table_for_trx( - dict_table_t* table, - trx_t* trx, - enum lock_mode mode) -{ - mem_heap_t* heap; - que_thr_t* thr; - dberr_t err; - sel_node_t* node; - heap = mem_heap_create(512); - - node = sel_node_create(heap); - thr = pars_complete_graph_for_exec(node, trx, heap, NULL); - thr->graph->state = QUE_FORK_ACTIVE; - - /* We use the select query graph as the dummy graph needed - in the lock module call */ - thr = static_cast<que_thr_t*>( - que_fork_get_first_thr( - static_cast<que_fork_t*>(que_node_get_parent(thr)))); +/** Sets a lock on a table based on the given mode. +@param table table to lock +@param trx transaction +@param mode LOCK_X or LOCK_S +@param no_wait whether to skip handling DB_LOCK_WAIT +@return error code */ +dberr_t lock_table_for_trx(dict_table_t *table, trx_t *trx, lock_mode mode, + bool no_wait) +{ + mem_heap_t *heap= mem_heap_create(512); + sel_node_t *node= sel_node_create(heap); + que_thr_t *thr= pars_complete_graph_for_exec(node, trx, heap, nullptr); + thr->graph->state= QUE_FORK_ACTIVE; + + thr= static_cast<que_thr_t*> + (que_fork_get_first_thr(static_cast<que_fork_t*> + (que_node_get_parent(thr)))); run_again: - thr->run_node = thr; - thr->prev_node = thr->common.parent; - - err = lock_table(table, mode, thr); + thr->run_node= thr; + thr->prev_node= thr->common.parent; + dberr_t err= lock_table(table, mode, thr); - trx->error_state = err; - - if (UNIV_UNLIKELY(err != DB_SUCCESS)) { - if (row_mysql_handle_errors(&err, trx, thr, NULL)) { - goto run_again; - } - } + switch (err) { + case DB_SUCCESS: + break; + case DB_LOCK_WAIT: + if (no_wait) + { + lock_sys.cancel_lock_wait_for_trx(trx); + break; + } + /* fall through */ + default: + trx->error_state= err; + if (row_mysql_handle_errors(&err, trx, thr, nullptr)) + goto run_again; + } - que_graph_free(thr->graph); - trx->op_info = ""; + que_graph_free(thr->graph); + trx->op_info= ""; - return(err); + return err; } /** Exclusively lock the data dictionary tables. @@ -5639,8 +5637,7 @@ static void lock_cancel_waiting_and_release(lock_t *lock) lock_wait_end(trx); trx->mutex_unlock(); } -#ifdef WITH_WSREP -TRANSACTIONAL_TARGET + void lock_sys_t::cancel_lock_wait_for_trx(trx_t *trx) { lock_sys.wr_lock(SRW_LOCK_CALL); @@ -5654,7 +5651,6 @@ void lock_sys_t::cancel_lock_wait_for_trx(trx_t *trx) lock_sys.wr_unlock(); mysql_mutex_unlock(&lock_sys.wait_mutex); } -#endif /* WITH_WSREP */ /** Cancel a waiting lock request. @tparam check_victim whether to check for DB_DEADLOCK diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 6cf099e204e..a45cc3946b4 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -3114,7 +3114,7 @@ and apply it to dict_table_t static dberr_t handle_instant_metadata(dict_table_t *table, const row_import &cfg) { - dict_get_and_save_data_dir_path(table, false); + dict_get_and_save_data_dir_path(table); char *filepath; if (DICT_TF_HAS_DATA_DIR(table->flags)) @@ -4149,7 +4149,7 @@ fil_tablespace_iterate( return(DB_CORRUPTION);); /* Make sure the data_dir_path is set. */ - dict_get_and_save_data_dir_path(table, false); + dict_get_and_save_data_dir_path(table); ut_ad(!DICT_TF_HAS_DATA_DIR(table->flags) || table->data_dir_path); @@ -4470,7 +4470,7 @@ row_import_for_mysql( /* If the table is stored in a remote tablespace, we need to determine that filepath from the link file and system tables. Find the space ID in SYS_TABLES since this is an ALTER TABLE. */ - dict_get_and_save_data_dir_path(table, true); + dict_get_and_save_data_dir_path(table); ut_ad(!DICT_TF_HAS_DATA_DIR(table->flags) || table->data_dir_path); const char *data_dir_path = DICT_TF_HAS_DATA_DIR(table->flags) diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 785b7b6070d..e3947403232 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -5205,7 +5205,11 @@ add_to_buf: row_merge_dup_t dup{index, nullptr, nullptr, 0}; row_merge_buf_sort(buf, &dup); if (dup.n_dup) - return DB_DUPLICATE_KEY; + { + trx->error_info= index; + err= DB_DUPLICATE_KEY; + goto func_exit; + } } else row_merge_buf_sort(buf, NULL); @@ -5214,7 +5218,10 @@ add_to_buf: file->n_rec+= buf->n_tuples; err= write_to_tmp_file(i); if (err != DB_SUCCESS) - return err; + { + trx->error_info= index; + goto func_exit; + } clean_bulk_buffer(i); buf= &m_merge_buf[i]; goto add_to_buf; @@ -5243,7 +5250,10 @@ dberr_t row_merge_bulk_t::write_to_index(ulint index_no, trx_t *trx) { row_merge_buf_sort(&buf, &dup); if (dup.n_dup) - return DB_DUPLICATE_KEY; + { + err= DB_DUPLICATE_KEY; + goto func_exit; + } } else row_merge_buf_sort(&buf, NULL); if (file && file->fd != OS_FILE_CLOSED) @@ -5276,6 +5286,8 @@ dberr_t row_merge_bulk_t::write_to_index(ulint index_no, trx_t *trx) nullptr, &m_blob_file); func_exit: + if (err != DB_SUCCESS) + trx->error_info= index; err= btr_bulk.finish(err); return err; } diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index f915fb09769..cb908c9de35 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1791,7 +1791,7 @@ srv_get_meta_data_filename( char* path; /* Make sure the data_dir_path is set. */ - dict_get_and_save_data_dir_path(table, false); + dict_get_and_save_data_dir_path(table); const char* data_dir_path = DICT_TF_HAS_DATA_DIR(table->flags) ? table->data_dir_path : nullptr; diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index bfad53e691b..05333652a25 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -2055,7 +2055,8 @@ trx_undo_report_row_operation( } else if (!m.second || !trx->bulk_insert) { bulk = false; } else if (index->table->is_temporary()) { - } else if (trx_has_lock_x(*trx, *index->table)) { + } else if (trx_has_lock_x(*trx, *index->table) + && index->table->bulk_trx_id == trx->id) { m.first->second.start_bulk_insert(index->table); if (dberr_t err = m.first->second.bulk_insert_buffered( |