summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-05-09 10:41:10 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2019-05-10 07:57:01 +0300
commit542f32649bdaf537723af1e5abae4a63c6ad458a (patch)
tree5f58a22b7bf83e28d41decdc7fcfa853d17424f3 /storage/innobase
parentf3718a112a9b29caca1cba35ddaa6cf62f15ed99 (diff)
downloadmariadb-git-542f32649bdaf537723af1e5abae4a63c6ad458a.tar.gz
MDEV-18220: race condition in fts_get_table_name()
fts_get_table_name(): Add the parameter bool dict_locked=false.
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/fts/fts0config.cc8
-rw-r--r--storage/innobase/fts/fts0fts.cc23
-rw-r--r--storage/innobase/fts/fts0sql.cc13
-rw-r--r--storage/innobase/include/fts0priv.h6
4 files changed, 33 insertions, 17 deletions
diff --git a/storage/innobase/fts/fts0config.cc b/storage/innobase/fts/fts0config.cc
index 889f4a074b9..bcf7d7581da 100644
--- a/storage/innobase/fts/fts0config.cc
+++ b/storage/innobase/fts/fts0config.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, 2019, 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
@@ -223,8 +224,11 @@ fts_config_set_value(
pars_info_bind_varchar_literal(info, "value",
value->f_str, value->f_len);
+ const bool dict_locked = fts_table->table->fts->fts_status
+ & TABLE_DICT_LOCKED;
+
fts_table->suffix = "CONFIG";
- fts_get_table_name(fts_table, table_name);
+ fts_get_table_name(fts_table, table_name, dict_locked);
pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql(
@@ -252,7 +256,7 @@ fts_config_set_value(
pars_info_bind_varchar_literal(
info, "value", value->f_str, value->f_len);
- fts_get_table_name(fts_table, table_name);
+ fts_get_table_name(fts_table, table_name, dict_locked);
pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql(
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 0dea97b6e20..57c232fce9c 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -1593,7 +1593,7 @@ fts_rename_aux_tables(
for (i = 0; fts_common_tables[i] != NULL; ++i) {
fts_table.suffix = fts_common_tables[i];
- fts_get_table_name(&fts_table, old_table_name);
+ fts_get_table_name(&fts_table, old_table_name, true);
err = fts_rename_one_aux_table(new_name, old_table_name, trx);
@@ -1616,7 +1616,7 @@ fts_rename_aux_tables(
for (ulint j = 0; fts_index_selector[j].value; ++j) {
fts_table.suffix = fts_get_suffix(j);
- fts_get_table_name(&fts_table, old_table_name);
+ fts_get_table_name(&fts_table, old_table_name, true);
err = fts_rename_one_aux_table(
new_name, old_table_name, trx);
@@ -1656,7 +1656,7 @@ fts_drop_common_tables(
fts_table->suffix = fts_common_tables[i];
- fts_get_table_name(fts_table, table_name);
+ fts_get_table_name(fts_table, table_name, true);
err = fts_drop_table(trx, table_name);
@@ -1693,7 +1693,7 @@ fts_drop_index_split_tables(
fts_table.suffix = fts_get_suffix(i);
- fts_get_table_name(&fts_table, table_name);
+ fts_get_table_name(&fts_table, table_name, true);
err = fts_drop_table(trx, table_name);
@@ -1741,7 +1741,7 @@ fts_drop_index_tables(
fts_table.suffix = index_tables[i];
- fts_get_table_name(&fts_table, table_name);
+ fts_get_table_name(&fts_table, table_name, true);
err = fts_drop_table(trx, table_name);
@@ -1856,7 +1856,7 @@ fts_create_common_tables(
for (i = 0; fts_common_tables[i] != NULL; ++i) {
fts_table.suffix = fts_common_tables[i];
- fts_get_table_name(&fts_table, full_name[i]);
+ fts_get_table_name(&fts_table, full_name[i], true);
pars_info_bind_id(info, true,
fts_common_tables[i], full_name[i]);
@@ -1878,7 +1878,7 @@ fts_create_common_tables(
info = pars_info_create();
fts_table.suffix = "CONFIG";
- fts_get_table_name(&fts_table, fts_name);
+ fts_get_table_name(&fts_table, fts_name, true);
pars_info_bind_id(info, true, "config_table", fts_name);
graph = fts_parse_sql_no_dict_lock(
@@ -1957,7 +1957,7 @@ fts_create_one_index_table(
ut_ad(index->type & DICT_FTS);
- fts_get_table_name(fts_table, table_name);
+ fts_get_table_name(fts_table, table_name, true);
if (srv_file_per_table) {
flags2 = DICT_TF2_USE_TABLESPACE;
@@ -2039,7 +2039,7 @@ fts_create_index_tables_low(
info = pars_info_create();
fts_table.suffix = "DOC_ID";
- fts_get_table_name(&fts_table, fts_name);
+ fts_get_table_name(&fts_table, fts_name, true);
pars_info_bind_id(info, true, "doc_id_table", fts_name);
@@ -2068,7 +2068,7 @@ fts_create_index_tables_low(
break;
}
- fts_get_table_name(&fts_table, fts_name);
+ fts_get_table_name(&fts_table, fts_name, true);
pars_info_bind_id(info, true, "table", fts_name);
@@ -2835,7 +2835,8 @@ fts_update_sync_doc_id(
pars_info_bind_varchar_literal(info, "doc_id", id, id_len);
- fts_get_table_name(&fts_table, fts_name);
+ fts_get_table_name(&fts_table, fts_name,
+ table->fts->fts_status & TABLE_DICT_LOCKED);
pars_info_bind_id(info, true, "table_name", fts_name);
graph = fts_parse_sql(
diff --git a/storage/innobase/fts/fts0sql.cc b/storage/innobase/fts/fts0sql.cc
index 853312ab2ea..cce21957f1b 100644
--- a/storage/innobase/fts/fts0sql.cc
+++ b/storage/innobase/fts/fts0sql.cc
@@ -121,16 +121,25 @@ UNIV_INTERN char* fts_get_table_name_prefix(const fts_table_t* fts_table)
/** Construct the name of an internal FTS table for the given table.
@param[in] fts_table metadata on fulltext-indexed table
-@param[out] table_name a name up to MAX_FULL_NAME_LEN */
+@param[out] table_name a name up to MAX_FULL_NAME_LEN
+@param[in] dict_locked whether dict_sys->mutex is being held */
UNIV_INTERN
-void fts_get_table_name(const fts_table_t* fts_table, char* table_name)
+void fts_get_table_name(const fts_table_t* fts_table, char* table_name,
+ bool dict_locked)
{
+ if (!dict_locked) {
+ mutex_enter(&dict_sys->mutex);
+ }
+ ut_ad(mutex_own(&dict_sys->mutex));
const char* slash = strchr(fts_table->table->name, '/');
ut_ad(slash);
/* Include the separator as well. */
const size_t dbname_len = (slash - fts_table->table->name) + 1;
ut_ad(dbname_len > 1);
memcpy(table_name, fts_table->table->name, dbname_len);
+ if (!dict_locked) {
+ mutex_exit(&dict_sys->mutex);
+ }
memcpy(table_name += dbname_len, "FTS_", 4);
table_name += 4;
table_name += fts_get_table_id(fts_table, table_name);
diff --git a/storage/innobase/include/fts0priv.h b/storage/innobase/include/fts0priv.h
index 4ae90f59dda..5a4e37556a9 100644
--- a/storage/innobase/include/fts0priv.h
+++ b/storage/innobase/include/fts0priv.h
@@ -136,9 +136,11 @@ fts_eval_sql(
/** Construct the name of an internal FTS table for the given table.
@param[in] fts_table metadata on fulltext-indexed table
-@param[out] table_name a name up to MAX_FULL_NAME_LEN */
+@param[out] table_name a name up to MAX_FULL_NAME_LEN
+@param[in] dict_locked whether dict_sys->mutex is being held */
UNIV_INTERN
-void fts_get_table_name(const fts_table_t* fts_table, char* table_name)
+void fts_get_table_name(const fts_table_t* fts_table, char* table_name,
+ bool dict_locked = false)
MY_ATTRIBUTE((nonnull));
/******************************************************************//**
Construct the column specification part of the SQL string for selecting the