Commit 9ce1ea6f authored by Shaohua Wang's avatar Shaohua Wang Committed by Marko Mäkelä

BUG#24009272 SEGFAULT WITH CREATE+SELECT FROM IS+DROP FTS TABLE CONCURRENTLY

Analysis:
When we access fts_internal_tbl_name in i_s_fts_config_fill (),
it can be set to NULL by another session.

Solution:
Define fts_internal_tbl_name2 for global variable innodb_ft_aux_table,
if it's NULL, set fts_internal_tbl_name to "default".
Reviewed-by: default avatarJimmy Yang <jimmy.yang@oracle.com>
RB: 13401
parent 4b5a9d8e
...@@ -93,6 +93,7 @@ static const ulint FTS_DEADLOCK_RETRY_WAIT = 100000; ...@@ -93,6 +93,7 @@ static const ulint FTS_DEADLOCK_RETRY_WAIT = 100000;
/** variable to record innodb_fts_internal_tbl_name for information /** variable to record innodb_fts_internal_tbl_name for information
schema table INNODB_FTS_INSERTED etc. */ schema table INNODB_FTS_INSERTED etc. */
char* fts_internal_tbl_name = NULL; char* fts_internal_tbl_name = NULL;
char* fts_internal_tbl_name2 = NULL;
/** InnoDB default stopword list: /** InnoDB default stopword list:
There are different versions of stopwords, the stop words listed There are different versions of stopwords, the stop words listed
......
...@@ -18773,6 +18773,41 @@ innodb_internal_table_validate( ...@@ -18773,6 +18773,41 @@ innodb_internal_table_validate(
} }
#ifdef BTR_CUR_HASH_ADAPT #ifdef BTR_CUR_HASH_ADAPT
/****************************************************************//**
Update global variable "fts_internal_tbl_name" with the "saved"
stopword table name value. This function is registered as a callback
with MySQL. */
static
void
innodb_internal_table_update(
/*=========================*/
THD* thd, /*!< in: thread handle */
struct st_mysql_sys_var* var, /*!< in: pointer to
system variable */
void* var_ptr,/*!< out: where the
formal string goes */
const void* save) /*!< in: immediate result
from check function */
{
const char* table_name;
char* old;
ut_a(save != NULL);
ut_a(var_ptr != NULL);
table_name = *static_cast<const char*const*>(save);
old = *(char**) var_ptr;
*(char**) var_ptr = table_name ? my_strdup(table_name, MYF(0)) : NULL;
my_free(old);
fts_internal_tbl_name2 = *(char**) var_ptr;
if (fts_internal_tbl_name2 == NULL) {
fts_internal_tbl_name = const_cast<char*>("default");
} else {
fts_internal_tbl_name = fts_internal_tbl_name2;
}
}
/****************************************************************//** /****************************************************************//**
Update the system variable innodb_adaptive_hash_index using the "saved" Update the system variable innodb_adaptive_hash_index using the "saved"
value. This function is registered as a callback with MySQL. */ value. This function is registered as a callback with MySQL. */
...@@ -21226,11 +21261,11 @@ static MYSQL_SYSVAR_BOOL(disable_sort_file_cache, srv_disable_sort_file_cache, ...@@ -21226,11 +21261,11 @@ static MYSQL_SYSVAR_BOOL(disable_sort_file_cache, srv_disable_sort_file_cache,
"Whether to disable OS system file cache for sort I/O", "Whether to disable OS system file cache for sort I/O",
NULL, NULL, FALSE); NULL, NULL, FALSE);
static MYSQL_SYSVAR_STR(ft_aux_table, fts_internal_tbl_name, static MYSQL_SYSVAR_STR(ft_aux_table, fts_internal_tbl_name2,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC, PLUGIN_VAR_RQCMDARG,
"FTS internal auxiliary table to be checked", "FTS internal auxiliary table to be checked",
innodb_internal_table_validate, innodb_internal_table_validate,
NULL, NULL); innodb_internal_table_update, NULL);
static MYSQL_SYSVAR_ULONG(ft_cache_size, fts_max_cache_size, static MYSQL_SYSVAR_ULONG(ft_cache_size, fts_max_cache_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
......
...@@ -3955,6 +3955,8 @@ i_s_fts_config_fill( ...@@ -3955,6 +3955,8 @@ i_s_fts_config_fill(
DBUG_RETURN(0); DBUG_RETURN(0);
} }
DEBUG_SYNC_C("i_s_fts_config_fille_check");
fields = table->field; fields = table->field;
/* Prevent DDL to drop fts aux tables. */ /* Prevent DDL to drop fts aux tables. */
......
...@@ -409,6 +409,7 @@ extern bool fts_need_sync; ...@@ -409,6 +409,7 @@ extern bool fts_need_sync;
/** Variable specifying the table that has Fulltext index to display its /** Variable specifying the table that has Fulltext index to display its
content through information schema table */ content through information schema table */
extern char* fts_internal_tbl_name; extern char* fts_internal_tbl_name;
extern char* fts_internal_tbl_name2;
#define fts_que_graph_free(graph) \ #define fts_que_graph_free(graph) \
do { \ do { \
......
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