summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorDaniel Black <daniel@mariadb.org>2022-03-25 15:06:56 +1100
committerDaniel Black <daniel@mariadb.org>2022-03-25 15:06:56 +1100
commit88ce8a3d8be0346b325bc4da75894cd15e255857 (patch)
tree1e827eb908eaa737225017627beafa2b6d8e9959 /storage/innobase
parentf6fcf827b379fc069563d1896850fbfcebaa983e (diff)
parent13b97880bd8f6901225a1f8d6ff2eb6ba9303ceb (diff)
downloadmariadb-git-88ce8a3d8be0346b325bc4da75894cd15e255857.tar.gz
Merge 10.7 into 10.8
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/buf/buf0buf.cc41
-rw-r--r--storage/innobase/buf/buf0rea.cc57
-rw-r--r--storage/innobase/dict/dict0load.cc84
-rw-r--r--storage/innobase/fts/fts0fts.cc9
-rw-r--r--storage/innobase/handler/ha_innodb.cc32
-rw-r--r--storage/innobase/handler/handler0alter.cc4
-rw-r--r--storage/innobase/include/buf0buf.h7
-rw-r--r--storage/innobase/include/dict0load.h7
-rw-r--r--storage/innobase/include/lock0lock.h18
-rw-r--r--storage/innobase/include/trx0purge.h6
-rw-r--r--storage/innobase/lock/lock0lock.cc82
-rw-r--r--storage/innobase/row/row0import.cc6
-rw-r--r--storage/innobase/row/row0merge.cc18
-rw-r--r--storage/innobase/srv/srv0start.cc2
-rw-r--r--storage/innobase/trx/trx0rec.cc3
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(