Commit 542f3264 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-18220: race condition in fts_get_table_name()

fts_get_table_name(): Add the parameter bool dict_locked=false.
parent f3718a11
/***************************************************************************** /*****************************************************************************
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -223,8 +224,11 @@ fts_config_set_value( ...@@ -223,8 +224,11 @@ fts_config_set_value(
pars_info_bind_varchar_literal(info, "value", pars_info_bind_varchar_literal(info, "value",
value->f_str, value->f_len); value->f_str, value->f_len);
const bool dict_locked = fts_table->table->fts->fts_status
& TABLE_DICT_LOCKED;
fts_table->suffix = "CONFIG"; 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); pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql( graph = fts_parse_sql(
...@@ -252,7 +256,7 @@ fts_config_set_value( ...@@ -252,7 +256,7 @@ fts_config_set_value(
pars_info_bind_varchar_literal( pars_info_bind_varchar_literal(
info, "value", value->f_str, value->f_len); 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); pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql( graph = fts_parse_sql(
......
...@@ -1593,7 +1593,7 @@ fts_rename_aux_tables( ...@@ -1593,7 +1593,7 @@ fts_rename_aux_tables(
for (i = 0; fts_common_tables[i] != NULL; ++i) { for (i = 0; fts_common_tables[i] != NULL; ++i) {
fts_table.suffix = fts_common_tables[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); err = fts_rename_one_aux_table(new_name, old_table_name, trx);
...@@ -1616,7 +1616,7 @@ fts_rename_aux_tables( ...@@ -1616,7 +1616,7 @@ fts_rename_aux_tables(
for (ulint j = 0; fts_index_selector[j].value; ++j) { for (ulint j = 0; fts_index_selector[j].value; ++j) {
fts_table.suffix = fts_get_suffix(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( err = fts_rename_one_aux_table(
new_name, old_table_name, trx); new_name, old_table_name, trx);
...@@ -1656,7 +1656,7 @@ fts_drop_common_tables( ...@@ -1656,7 +1656,7 @@ fts_drop_common_tables(
fts_table->suffix = fts_common_tables[i]; 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); err = fts_drop_table(trx, table_name);
...@@ -1693,7 +1693,7 @@ fts_drop_index_split_tables( ...@@ -1693,7 +1693,7 @@ fts_drop_index_split_tables(
fts_table.suffix = fts_get_suffix(i); 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); err = fts_drop_table(trx, table_name);
...@@ -1741,7 +1741,7 @@ fts_drop_index_tables( ...@@ -1741,7 +1741,7 @@ fts_drop_index_tables(
fts_table.suffix = index_tables[i]; 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); err = fts_drop_table(trx, table_name);
...@@ -1856,7 +1856,7 @@ fts_create_common_tables( ...@@ -1856,7 +1856,7 @@ fts_create_common_tables(
for (i = 0; fts_common_tables[i] != NULL; ++i) { for (i = 0; fts_common_tables[i] != NULL; ++i) {
fts_table.suffix = fts_common_tables[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, pars_info_bind_id(info, true,
fts_common_tables[i], full_name[i]); fts_common_tables[i], full_name[i]);
...@@ -1878,7 +1878,7 @@ fts_create_common_tables( ...@@ -1878,7 +1878,7 @@ fts_create_common_tables(
info = pars_info_create(); info = pars_info_create();
fts_table.suffix = "CONFIG"; 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); pars_info_bind_id(info, true, "config_table", fts_name);
graph = fts_parse_sql_no_dict_lock( graph = fts_parse_sql_no_dict_lock(
...@@ -1957,7 +1957,7 @@ fts_create_one_index_table( ...@@ -1957,7 +1957,7 @@ fts_create_one_index_table(
ut_ad(index->type & DICT_FTS); 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) { if (srv_file_per_table) {
flags2 = DICT_TF2_USE_TABLESPACE; flags2 = DICT_TF2_USE_TABLESPACE;
...@@ -2039,7 +2039,7 @@ fts_create_index_tables_low( ...@@ -2039,7 +2039,7 @@ fts_create_index_tables_low(
info = pars_info_create(); info = pars_info_create();
fts_table.suffix = "DOC_ID"; 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); pars_info_bind_id(info, true, "doc_id_table", fts_name);
...@@ -2068,7 +2068,7 @@ fts_create_index_tables_low( ...@@ -2068,7 +2068,7 @@ fts_create_index_tables_low(
break; 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); pars_info_bind_id(info, true, "table", fts_name);
...@@ -2835,7 +2835,8 @@ fts_update_sync_doc_id( ...@@ -2835,7 +2835,8 @@ fts_update_sync_doc_id(
pars_info_bind_varchar_literal(info, "doc_id", id, id_len); 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); pars_info_bind_id(info, true, "table_name", fts_name);
graph = fts_parse_sql( graph = fts_parse_sql(
......
...@@ -121,16 +121,25 @@ UNIV_INTERN char* fts_get_table_name_prefix(const fts_table_t* fts_table) ...@@ -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. /** Construct the name of an internal FTS table for the given table.
@param[in] fts_table metadata on fulltext-indexed 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 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, '/'); const char* slash = strchr(fts_table->table->name, '/');
ut_ad(slash); ut_ad(slash);
/* Include the separator as well. */ /* Include the separator as well. */
const size_t dbname_len = (slash - fts_table->table->name) + 1; const size_t dbname_len = (slash - fts_table->table->name) + 1;
ut_ad(dbname_len > 1); ut_ad(dbname_len > 1);
memcpy(table_name, fts_table->table->name, dbname_len); memcpy(table_name, fts_table->table->name, dbname_len);
if (!dict_locked) {
mutex_exit(&dict_sys->mutex);
}
memcpy(table_name += dbname_len, "FTS_", 4); memcpy(table_name += dbname_len, "FTS_", 4);
table_name += 4; table_name += 4;
table_name += fts_get_table_id(fts_table, table_name); table_name += fts_get_table_id(fts_table, table_name);
......
...@@ -136,9 +136,11 @@ fts_eval_sql( ...@@ -136,9 +136,11 @@ fts_eval_sql(
/** Construct the name of an internal FTS table for the given table. /** Construct the name of an internal FTS table for the given table.
@param[in] fts_table metadata on fulltext-indexed 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 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)); MY_ATTRIBUTE((nonnull));
/******************************************************************//** /******************************************************************//**
Construct the column specification part of the SQL string for selecting the Construct the column specification part of the SQL string for selecting the
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -223,8 +224,11 @@ fts_config_set_value( ...@@ -223,8 +224,11 @@ fts_config_set_value(
pars_info_bind_varchar_literal(info, "value", pars_info_bind_varchar_literal(info, "value",
value->f_str, value->f_len); value->f_str, value->f_len);
const bool dict_locked = fts_table->table->fts->fts_status
& TABLE_DICT_LOCKED;
fts_table->suffix = "CONFIG"; 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); pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql( graph = fts_parse_sql(
...@@ -252,7 +256,7 @@ fts_config_set_value( ...@@ -252,7 +256,7 @@ fts_config_set_value(
pars_info_bind_varchar_literal( pars_info_bind_varchar_literal(
info, "value", value->f_str, value->f_len); 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); pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql( graph = fts_parse_sql(
......
...@@ -1593,7 +1593,7 @@ fts_rename_aux_tables( ...@@ -1593,7 +1593,7 @@ fts_rename_aux_tables(
for (i = 0; fts_common_tables[i] != NULL; ++i) { for (i = 0; fts_common_tables[i] != NULL; ++i) {
fts_table.suffix = fts_common_tables[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); err = fts_rename_one_aux_table(new_name, old_table_name, trx);
...@@ -1616,7 +1616,7 @@ fts_rename_aux_tables( ...@@ -1616,7 +1616,7 @@ fts_rename_aux_tables(
for (ulint j = 0; fts_index_selector[j].value; ++j) { for (ulint j = 0; fts_index_selector[j].value; ++j) {
fts_table.suffix = fts_get_suffix(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( err = fts_rename_one_aux_table(
new_name, old_table_name, trx); new_name, old_table_name, trx);
...@@ -1656,7 +1656,7 @@ fts_drop_common_tables( ...@@ -1656,7 +1656,7 @@ fts_drop_common_tables(
fts_table->suffix = fts_common_tables[i]; 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); err = fts_drop_table(trx, table_name);
...@@ -1693,7 +1693,7 @@ fts_drop_index_split_tables( ...@@ -1693,7 +1693,7 @@ fts_drop_index_split_tables(
fts_table.suffix = fts_get_suffix(i); 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); err = fts_drop_table(trx, table_name);
...@@ -1741,7 +1741,7 @@ fts_drop_index_tables( ...@@ -1741,7 +1741,7 @@ fts_drop_index_tables(
fts_table.suffix = index_tables[i]; 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); err = fts_drop_table(trx, table_name);
...@@ -1856,7 +1856,7 @@ fts_create_common_tables( ...@@ -1856,7 +1856,7 @@ fts_create_common_tables(
for (i = 0; fts_common_tables[i] != NULL; ++i) { for (i = 0; fts_common_tables[i] != NULL; ++i) {
fts_table.suffix = fts_common_tables[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, pars_info_bind_id(info, true,
fts_common_tables[i], full_name[i]); fts_common_tables[i], full_name[i]);
...@@ -1878,7 +1878,7 @@ fts_create_common_tables( ...@@ -1878,7 +1878,7 @@ fts_create_common_tables(
info = pars_info_create(); info = pars_info_create();
fts_table.suffix = "CONFIG"; 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); pars_info_bind_id(info, true, "config_table", fts_name);
graph = fts_parse_sql_no_dict_lock( graph = fts_parse_sql_no_dict_lock(
...@@ -1957,7 +1957,7 @@ fts_create_one_index_table( ...@@ -1957,7 +1957,7 @@ fts_create_one_index_table(
ut_ad(index->type & DICT_FTS); 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) { if (srv_file_per_table) {
flags2 = DICT_TF2_USE_TABLESPACE; flags2 = DICT_TF2_USE_TABLESPACE;
...@@ -2039,7 +2039,7 @@ fts_create_index_tables_low( ...@@ -2039,7 +2039,7 @@ fts_create_index_tables_low(
info = pars_info_create(); info = pars_info_create();
fts_table.suffix = "DOC_ID"; 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); pars_info_bind_id(info, true, "doc_id_table", fts_name);
...@@ -2068,7 +2068,7 @@ fts_create_index_tables_low( ...@@ -2068,7 +2068,7 @@ fts_create_index_tables_low(
break; 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); pars_info_bind_id(info, true, "table", fts_name);
...@@ -2835,7 +2835,8 @@ fts_update_sync_doc_id( ...@@ -2835,7 +2835,8 @@ fts_update_sync_doc_id(
pars_info_bind_varchar_literal(info, "doc_id", id, id_len); 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); pars_info_bind_id(info, true, "table_name", fts_name);
graph = fts_parse_sql( graph = fts_parse_sql(
......
...@@ -121,16 +121,25 @@ UNIV_INTERN char* fts_get_table_name_prefix(const fts_table_t* fts_table) ...@@ -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. /** Construct the name of an internal FTS table for the given table.
@param[in] fts_table metadata on fulltext-indexed 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 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, '/'); const char* slash = strchr(fts_table->table->name, '/');
ut_ad(slash); ut_ad(slash);
/* Include the separator as well. */ /* Include the separator as well. */
const size_t dbname_len = (slash - fts_table->table->name) + 1; const size_t dbname_len = (slash - fts_table->table->name) + 1;
ut_ad(dbname_len > 1); ut_ad(dbname_len > 1);
memcpy(table_name, fts_table->table->name, dbname_len); memcpy(table_name, fts_table->table->name, dbname_len);
if (!dict_locked) {
mutex_exit(&dict_sys->mutex);
}
memcpy(table_name += dbname_len, "FTS_", 4); memcpy(table_name += dbname_len, "FTS_", 4);
table_name += 4; table_name += 4;
table_name += fts_get_table_id(fts_table, table_name); table_name += fts_get_table_id(fts_table, table_name);
......
...@@ -136,9 +136,11 @@ fts_eval_sql( ...@@ -136,9 +136,11 @@ fts_eval_sql(
/** Construct the name of an internal FTS table for the given table. /** Construct the name of an internal FTS table for the given table.
@param[in] fts_table metadata on fulltext-indexed 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 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)); MY_ATTRIBUTE((nonnull));
/******************************************************************//** /******************************************************************//**
Construct the column specification part of the SQL string for selecting the Construct the column specification part of the SQL string for selecting the
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment