summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-04-04 10:37:23 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2022-04-04 10:37:23 +0300
commitc6a62eea1f0553f5adb721926c9d54cfa6259cea (patch)
tree82eaf9166723b1f656e8247ed879ec87df00cb7a
parenta23c319436fbf289d59e7064c1f286eb79ea0f1f (diff)
parentaeb679d33e466d9e9f6bcfe806b86e31a6f18fa5 (diff)
downloadmariadb-git-bb-10.6-MDEV-15120_2.tar.gz
-rw-r--r--storage/innobase/dict/dict0dict.cc26
-rw-r--r--storage/innobase/fts/fts0fts.cc37
-rw-r--r--storage/innobase/include/dict0dict.h1
-rw-r--r--storage/innobase/row/row0purge.cc6
4 files changed, 53 insertions, 17 deletions
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index 3ea7cc64fc3..196e674396b 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -68,6 +68,7 @@ Created 1/8/1996 Heikki Tuuri
#include "srv0mon.h"
#include "srv0start.h"
#include "trx0undo.h"
+#include "trx0purge.h"
#include <vector>
#include <algorithm>
@@ -819,12 +820,14 @@ template dict_table_t* dict_acquire_mdl_shared<true>
(dict_table_t*,THD*,MDL_ticket**,dict_table_op_t);
/** Look up a table by numeric identifier.
+@tparam purge_thd Whether the function is called by purge thread
@param[in] table_id table identifier
@param[in] dict_locked data dictionary locked
@param[in] table_op operation to perform when opening
@param[in,out] thd background thread, or NULL to not acquire MDL
@param[out] mdl mdl ticket, or NULL
@return table, NULL if does not exist */
+template <bool purge_thd>
dict_table_t*
dict_table_open_on_id(table_id_t table_id, bool dict_locked,
dict_table_op_t table_op, THD *thd,
@@ -837,6 +840,12 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked,
if (table)
{
+ if (purge_thd && purge_sys.must_wait_FTS())
+ {
+ table= nullptr;
+ goto func_exit;
+ }
+
table->acquire();
if (thd && !dict_locked)
table= dict_acquire_mdl_shared<false>(table, thd, mdl, table_op);
@@ -853,7 +862,14 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked,
? DICT_ERR_IGNORE_RECOVER_LOCK
: DICT_ERR_IGNORE_FK_NOKEY);
if (table)
+ {
+ if (purge_thd && purge_sys.must_wait_FTS())
+ {
+ dict_sys.unlock();
+ return nullptr;
+ }
table->acquire();
+ }
if (!dict_locked)
{
dict_sys.unlock();
@@ -867,12 +883,22 @@ dict_table_open_on_id(table_id_t table_id, bool dict_locked,
}
}
+func_exit:
if (!dict_locked)
dict_sys.unfreeze();
return table;
}
+template dict_table_t* dict_table_open_on_id<false>
+(table_id_t table_id, bool dict_locked,
+ dict_table_op_t table_op, THD *thd,
+ MDL_ticket **mdl);
+template dict_table_t* dict_table_open_on_id<true>
+(table_id_t table_id, bool dict_locked,
+ dict_table_op_t table_op, THD *thd,
+ MDL_ticket **mdl);
+
/********************************************************************//**
Looks for column n position in the clustered index.
@return position in internal representation of the clustered index */
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 964a216cd39..fce0ff7aa1d 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -1555,7 +1555,7 @@ have any other reference count.
static void fts_table_no_ref_count(const char *table_name)
{
dict_table_t *table= dict_table_open_on_name(
- table_name, false, DICT_ERR_IGNORE_TABLESPACE);
+ table_name, true, DICT_ERR_IGNORE_TABLESPACE);
if (!table)
return;
@@ -1572,8 +1572,10 @@ and common table associated with the fts table.
already stopped*/
void purge_sys_t::stop_FTS(const dict_table_t &table, bool already_stopped)
{
+ dict_sys.lock(SRW_LOCK_CALL);
if (!already_stopped)
purge_sys.stop_FTS();
+
fts_table_t fts_table;
char table_name[MAX_FULL_NAME_LEN];
@@ -1582,28 +1584,31 @@ void purge_sys_t::stop_FTS(const dict_table_t &table, bool already_stopped)
for (const char **suffix= fts_common_tables; *suffix; suffix++)
{
fts_table.suffix= *suffix;
- fts_get_table_name(&fts_table, table_name, false);
+ fts_get_table_name(&fts_table, table_name, true);
fts_table_no_ref_count(table_name);
}
- if (!table.fts)
- return;
- auto indexes= table.fts->indexes;
- if (!indexes)
- return;
- for (ulint i= 0;i < ib_vector_size(indexes); ++i)
+ if (table.fts)
{
- const dict_index_t *index= static_cast<const dict_index_t*>(
- ib_vector_getp(indexes, i));
- FTS_INIT_INDEX_TABLE(&fts_table, nullptr, FTS_INDEX_TABLE, index);
- for (const fts_index_selector_t *s= fts_index_selector;
- s->suffix; s++)
+ if (auto indexes= table.fts->indexes)
{
- fts_table.suffix= s->suffix;
- fts_get_table_name(&fts_table, table_name, false);
- fts_table_no_ref_count(table_name);
+ for (ulint i= 0;i < ib_vector_size(indexes); ++i)
+ {
+ const dict_index_t *index= static_cast<const dict_index_t*>(
+ ib_vector_getp(indexes, i));
+ FTS_INIT_INDEX_TABLE(&fts_table, nullptr, FTS_INDEX_TABLE, index);
+ for (const fts_index_selector_t *s= fts_index_selector;
+ s->suffix; s++)
+ {
+ fts_table.suffix= s->suffix;
+ fts_get_table_name(&fts_table, table_name, true);
+ fts_table_no_ref_count(table_name);
+ }
+ }
}
}
+
+ dict_sys.unlock();
}
/** Lock the internal FTS_ tables for table, before fts_drop_tables().
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 07acd0ecb74..a02f4761964 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -146,6 +146,7 @@ dict_acquire_mdl_shared(dict_table_t *table,
@param[in,out] thd background thread, or NULL to not acquire MDL
@param[out] mdl mdl ticket, or NULL
@return table, NULL if does not exist */
+template<bool purge_thd= false>
dict_table_t*
dict_table_open_on_id(table_id_t table_id, bool dict_locked,
dict_table_op_t table_op, THD *thd= nullptr,
diff --git a/storage/innobase/row/row0purge.cc b/storage/innobase/row/row0purge.cc
index 30cbbd03c0f..3ba2e964689 100644
--- a/storage/innobase/row/row0purge.cc
+++ b/storage/innobase/row/row0purge.cc
@@ -974,10 +974,14 @@ row_purge_parse_undo_rec(
try_again:
purge_sys.check_stop_FTS();
- node->table = dict_table_open_on_id(
+ node->table = dict_table_open_on_id<true>(
table_id, false, DICT_TABLE_OP_NORMAL, node->purge_thd,
&node->mdl_ticket);
+ if (!node->table && purge_sys.must_wait_FTS()) {
+ goto try_again;
+ }
+
if (!node->table) {
/* The table has been dropped: no need to do purge and
release mdl happened as a part of open process itself */