Merge 10.1 into 10.2

This commit is contained in:
Marko Mäkelä 2019-05-13 18:47:30 +03:00
commit 50999738ea
18 changed files with 367 additions and 366 deletions

View file

@ -328,14 +328,24 @@ the
www
select * from information_schema.innodb_ft_deleted;
DOC_ID
Warnings:
Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_ft_deleted but the InnoDB storage engine is not installed
select * from information_schema.innodb_ft_being_deleted;
DOC_ID
Warnings:
Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_ft_being_deleted but the InnoDB storage engine is not installed
select * from information_schema.innodb_ft_index_cache;
WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION
Warnings:
Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_ft_index_cache but the InnoDB storage engine is not installed
select * from information_schema.innodb_ft_index_table;
WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION
Warnings:
Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_ft_index_table but the InnoDB storage engine is not installed
select * from information_schema.innodb_ft_config;
KEY VALUE
Warnings:
Warning 1012 InnoDB: SELECTing from INFORMATION_SCHEMA.innodb_ft_config but the InnoDB storage engine is not installed
select * from information_schema.innodb_buffer_page;
POOL_ID BLOCK_ID SPACE PAGE_NUMBER PAGE_TYPE FLUSH_TYPE FIX_COUNT IS_HASHED NEWEST_MODIFICATION OLDEST_MODIFICATION ACCESS_TIME TABLE_NAME INDEX_NAME NUMBER_RECORDS DATA_SIZE COMPRESSED_SIZE PAGE_STATE IO_FIX IS_OLD FREE_PAGE_CLOCK
Warnings:

View file

@ -0,0 +1,121 @@
CREATE TABLE t1 (v VARCHAR(100), FULLTEXT INDEX (v)) ENGINE=InnoDB;
insert into t1 VALUES('First record'),('Second record'),('Third record');
SET @save_ft_aux_table = @@GLOBAL.innodb_ft_aux_table;
connect con1,localhost,root,,;
SET GLOBAL innodb_ft_aux_table = 'test/t0';
ERROR 42000: Variable 'innodb_ft_aux_table' can't be set to the value of 'test/t0'
connection default;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD;
value
a
about
an
are
as
at
be
by
com
de
en
for
from
how
i
in
is
it
la
of
on
or
that
the
this
to
was
what
when
where
who
will
with
und
the
www
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED;
DOC_ID
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED;
DOC_ID
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE;
WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE;
WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_CONFIG;
KEY VALUE
connection con1;
SET GLOBAL innodb_ft_aux_table = 'test/t1';
disconnect con1;
connection default;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED;
DOC_ID
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED;
DOC_ID
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE;
WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION
first 1 1 1 1 0
record 1 3 3 1 6
record 1 3 3 2 7
record 1 3 3 3 6
second 2 2 1 2 0
third 3 3 1 3 0
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE;
WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_CONFIG;
KEY VALUE
optimize_checkpoint_limit 180
synced_doc_id 0
stopword_table_name
use_stopword 1
SELECT @@GLOBAL.innodb_ft_aux_table;
@@GLOBAL.innodb_ft_aux_table
test/t1
RENAME TABLE t1 TO t2;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED;
DOC_ID
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED;
DOC_ID
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE;
WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION
first 1 1 1 1 0
record 1 3 3 1 6
record 1 3 3 2 7
record 1 3 3 3 6
second 2 2 1 2 0
third 3 3 1 3 0
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE;
WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_CONFIG;
KEY VALUE
optimize_checkpoint_limit 180
synced_doc_id 0
stopword_table_name
use_stopword 1
SELECT @@GLOBAL.innodb_ft_aux_table;
@@GLOBAL.innodb_ft_aux_table
test/t1
DROP TABLE t2;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED;
DOC_ID
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED;
DOC_ID
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE;
WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE;
WORD FIRST_DOC_ID LAST_DOC_ID DOC_COUNT DOC_ID POSITION
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_CONFIG;
KEY VALUE
SELECT @@GLOBAL.innodb_ft_aux_table;
@@GLOBAL.innodb_ft_aux_table
test/t1
SET GLOBAL innodb_ft_aux_table = @save_ft_aux_table;

View file

@ -0,0 +1,6 @@
--innodb_ft_default_stopword
--innodb_ft_deleted
--innodb_ft_being_deleted
--innodb_ft_index_cache
--innodb_ft_index_table
--innodb_ft_config

View file

@ -0,0 +1,43 @@
--source include/have_innodb.inc
CREATE TABLE t1 (v VARCHAR(100), FULLTEXT INDEX (v)) ENGINE=InnoDB;
insert into t1 VALUES('First record'),('Second record'),('Third record');
SET @save_ft_aux_table = @@GLOBAL.innodb_ft_aux_table;
connect (con1,localhost,root,,);
--error ER_WRONG_VALUE_FOR_VAR
SET GLOBAL innodb_ft_aux_table = 'test/t0';
connection default;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_CONFIG;
connection con1;
SET GLOBAL innodb_ft_aux_table = 'test/t1';
disconnect con1;
connection default;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_CONFIG;
SELECT @@GLOBAL.innodb_ft_aux_table;
RENAME TABLE t1 TO t2;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_CONFIG;
SELECT @@GLOBAL.innodb_ft_aux_table;
DROP TABLE t2;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DELETED;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_BEING_DELETED;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_TABLE;
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_CONFIG;
SELECT @@GLOBAL.innodb_ft_aux_table;
SET GLOBAL innodb_ft_aux_table = @save_ft_aux_table;

View file

@ -88,11 +88,6 @@ static const ulint FTS_CACHE_SIZE_UPPER_LIMIT_IN_MB = 1024;
/** Time to sleep after DEADLOCK error before retrying operation. */
static const ulint FTS_DEADLOCK_RETRY_WAIT = 100000;
/** variable to record innodb_fts_internal_tbl_name for information
schema table INNODB_FTS_INSERTED etc. */
char* fts_internal_tbl_name = NULL;
char* fts_internal_tbl_name2 = NULL;
/** InnoDB default stopword list:
There are different versions of stopwords, the stop words listed
below comes from "Google Stopword" list. Reference:
@ -2865,21 +2860,6 @@ fts_doc_ids_create(void)
return(fts_doc_ids);
}
/*********************************************************************//**
Free a fts_doc_ids_t. */
void
fts_doc_ids_free(
/*=============*/
fts_doc_ids_t* fts_doc_ids)
{
mem_heap_t* heap = static_cast<mem_heap_t*>(
fts_doc_ids->self_heap->arg);
memset(fts_doc_ids, 0, sizeof(*fts_doc_ids));
mem_heap_free(heap);
}
/*********************************************************************//**
Do commit-phase steps necessary for the insertion of a new row. */
void

View file

@ -1778,8 +1778,6 @@ fts_optimize_words(
fetch.read_arg = optim->words;
fetch.read_record = fts_optimize_index_fetch_node;
ib::info().write(word->f_str, word->f_len);
while (!optim->done) {
dberr_t error;
trx_t* trx = optim->trx;

View file

@ -14107,7 +14107,7 @@ innodb_rec_per_key(
}
/* If the number of NULL values is the same as or
large than that of the distinct values, we could
larger than that of the distinct values, we could
consider that the table consists mostly of NULL value.
Set rec_per_key to 1. */
if (n_diff <= n_null) {
@ -17897,90 +17897,36 @@ innodb_buffer_pool_size_update(
<< " (new size: " << in_val << " bytes)";
}
/*************************************************************//**
Check whether valid argument given to "innodb_fts_internal_tbl_name"
This function is registered as a callback with MySQL.
@return 0 for valid stopword table */
static
int
innodb_internal_table_validate(
/*===========================*/
THD* thd, /*!< in: thread handle */
struct st_mysql_sys_var* var, /*!< in: pointer to system
variable */
void* save, /*!< out: immediate result
for update function */
struct st_mysql_value* value) /*!< in: incoming string */
/** The latest assigned innodb_ft_aux_table name */
static char* innodb_ft_aux_table;
/** Update innodb_ft_aux_table_id on SET GLOBAL innodb_ft_aux_table.
@param[out] save new value of innodb_ft_aux_table
@param[in] value user-specified value */
static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*,
void* save, st_mysql_value* value)
{
const char* table_name;
char buff[STRING_BUFFER_USUAL_SIZE];
int len = sizeof(buff);
int ret = 1;
dict_table_t* user_table;
char buf[STRING_BUFFER_USUAL_SIZE];
int len = sizeof buf;
ut_a(save != NULL);
ut_a(value != NULL);
table_name = value->val_str(value, buff, &len);
if (!table_name) {
*static_cast<const char**>(save) = NULL;
return(0);
}
user_table = dict_table_open_on_name(
table_name, FALSE, TRUE, DICT_ERR_IGNORE_NONE);
if (user_table) {
if (dict_table_has_fts_index(user_table)) {
*static_cast<const char**>(save) = table_name;
ret = 0;
if (const char* table_name = value->val_str(value, buf, &len)) {
if (dict_table_t* table = dict_table_open_on_name(
table_name, FALSE, TRUE, DICT_ERR_IGNORE_NONE)) {
const table_id_t id = dict_table_has_fts_index(table)
? table->id : 0;
dict_table_close(table, FALSE, FALSE);
if (id) {
innodb_ft_aux_table_id = id;
*static_cast<const char**>(save) = table_name;
return 0;
}
}
dict_table_close(user_table, FALSE, TRUE);
DBUG_EXECUTE_IF("innodb_evict_autoinc_table",
mutex_enter(&dict_sys->mutex);
dict_table_remove_from_cache_low(user_table, TRUE);
mutex_exit(&dict_sys->mutex);
);
}
return(ret);
}
/****************************************************************//**
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");
return 1;
} else {
fts_internal_tbl_name = fts_internal_tbl_name2;
*static_cast<char**>(save) = NULL;
innodb_ft_aux_table_id = 0;
return 0;
}
}
@ -20403,11 +20349,10 @@ static MYSQL_SYSVAR_BOOL(disable_sort_file_cache, srv_disable_sort_file_cache,
"Whether to disable OS system file cache for sort I/O",
NULL, NULL, FALSE);
static MYSQL_SYSVAR_STR(ft_aux_table, fts_internal_tbl_name2,
PLUGIN_VAR_RQCMDARG,
static MYSQL_SYSVAR_STR(ft_aux_table, innodb_ft_aux_table,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_MEMALLOC,
"FTS internal auxiliary table to be checked",
innodb_internal_table_validate,
innodb_internal_table_update, NULL);
innodb_ft_aux_table_validate, NULL, NULL);
static MYSQL_SYSVAR_ULONG(ft_cache_size, fts_max_cache_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,

View file

@ -59,6 +59,9 @@ Modified Dec 29, 2014 Jan Lindström (Added sys_semaphore_waits)
#include "fil0crypt.h"
#include "dict0crea.h"
/** The latest successfully looked up innodb_fts_aux_table */
UNIV_INTERN table_id_t innodb_ft_aux_table_id;
/** structure associates a name string with a file page type and/or buffer
page state. */
struct buf_page_desc_t{
@ -2885,15 +2888,14 @@ i_s_fts_deleted_generic_fill(
DBUG_RETURN(0);
}
if (!fts_internal_tbl_name) {
DBUG_RETURN(0);
}
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
/* Prevent DDL to drop fts aux tables. */
/* Prevent DROP of the internal tables for fulltext indexes.
FIXME: acquire DDL-blocking MDL on the user table name! */
rw_lock_s_lock(&dict_operation_lock);
user_table = dict_table_open_on_name(
fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
user_table = dict_table_open_on_id(
innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL);
if (!user_table) {
rw_lock_s_unlock(&dict_operation_lock);
@ -2915,6 +2917,12 @@ i_s_fts_deleted_generic_fill(
fts_table_fetch_doc_ids(trx, &fts_table, deleted);
dict_table_close(user_table, FALSE, FALSE);
rw_lock_s_unlock(&dict_operation_lock);
trx_free_for_background(trx);
fields = table->field;
int ret = 0;
@ -2929,14 +2937,8 @@ i_s_fts_deleted_generic_fill(
BREAK_IF(ret = schema_table_store_record(thd, table));
}
trx_free_for_background(trx);
fts_doc_ids_free(deleted);
dict_table_close(user_table, FALSE, FALSE);
rw_lock_s_unlock(&dict_operation_lock);
DBUG_RETURN(ret);
}
@ -3296,32 +3298,33 @@ i_s_fts_index_cache_fill(
DBUG_RETURN(0);
}
if (!fts_internal_tbl_name) {
DBUG_RETURN(0);
}
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
user_table = dict_table_open_on_name(
fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
/* Prevent DROP of the internal tables for fulltext indexes.
FIXME: acquire DDL-blocking MDL on the user table name! */
rw_lock_s_lock(&dict_operation_lock);
user_table = dict_table_open_on_id(
innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL);
if (!user_table) {
no_fts:
rw_lock_s_unlock(&dict_operation_lock);
DBUG_RETURN(0);
}
if (user_table->fts == NULL || user_table->fts->cache == NULL) {
if (!user_table->fts || !user_table->fts->cache) {
dict_table_close(user_table, FALSE, FALSE);
DBUG_RETURN(0);
goto no_fts;
}
cache = user_table->fts->cache;
ut_a(cache);
int ret = 0;
fts_string_t conv_str;
conv_str.f_len = system_charset_info->mbmaxlen
* FTS_MAX_WORD_LEN_IN_CHAR;
conv_str.f_str = static_cast<byte*>(ut_malloc_nokey(conv_str.f_len));
byte word[HA_FT_MAXBYTELEN + 1];
conv_str.f_len = sizeof word;
conv_str.f_str = word;
for (ulint i = 0; i < ib_vector_size(cache->indexes); i++) {
fts_index_cache_t* index_cache;
@ -3333,9 +3336,8 @@ i_s_fts_index_cache_fill(
index_cache, thd, &conv_str, tables));
}
ut_free(conv_str.f_str);
dict_table_close(user_table, FALSE, FALSE);
rw_lock_s_unlock(&dict_operation_lock);
DBUG_RETURN(ret);
}
@ -3743,15 +3745,14 @@ i_s_fts_index_table_fill(
DBUG_RETURN(0);
}
if (!fts_internal_tbl_name) {
DBUG_RETURN(0);
}
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
/* Prevent DDL to drop fts aux tables. */
/* Prevent DROP of the internal tables for fulltext indexes.
FIXME: acquire DDL-blocking MDL on the user table name! */
rw_lock_s_lock(&dict_operation_lock);
user_table = dict_table_open_on_name(
fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
user_table = dict_table_open_on_id(
innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL);
if (!user_table) {
rw_lock_s_unlock(&dict_operation_lock);
@ -3907,32 +3908,28 @@ i_s_fts_config_fill(
DBUG_RETURN(0);
}
if (!fts_internal_tbl_name) {
DBUG_RETURN(0);
}
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
DEBUG_SYNC_C("i_s_fts_config_fille_check");
fields = table->field;
/* Prevent DDL to drop fts aux tables. */
/* Prevent DROP of the internal tables for fulltext indexes.
FIXME: acquire DDL-blocking MDL on the user table name! */
rw_lock_s_lock(&dict_operation_lock);
user_table = dict_table_open_on_name(
fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
user_table = dict_table_open_on_id(
innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL);
if (!user_table) {
no_fts:
rw_lock_s_unlock(&dict_operation_lock);
DBUG_RETURN(0);
} else if (!dict_table_has_fts_index(user_table)) {
dict_table_close(user_table, FALSE, FALSE);
rw_lock_s_unlock(&dict_operation_lock);
DBUG_RETURN(0);
}
if (!dict_table_has_fts_index(user_table)) {
dict_table_close(user_table, FALSE, FALSE);
goto no_fts;
}
fields = table->field;
trx = trx_allocate_for_background();
trx->op_info = "Select for FTS CONFIG TABLE";
@ -3984,12 +3981,12 @@ i_s_fts_config_fill(
fts_sql_commit(trx);
trx_free_for_background(trx);
dict_table_close(user_table, FALSE, FALSE);
rw_lock_s_unlock(&dict_operation_lock);
trx_free_for_background(trx);
DBUG_RETURN(ret);
}

View file

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2014, 2017, MariaDB Corporation.
Copyright (c) 2014, 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
@ -27,6 +27,7 @@ Modified Dec 29, 2014 Jan Lindström
#ifndef i_s_h
#define i_s_h
#include "dict0types.h"
const char plugin_author[] = "Oracle Corporation";
const char maria_plugin_author[] = "MariaDB Corporation";
@ -65,6 +66,9 @@ extern struct st_maria_plugin i_s_innodb_tablespaces_encryption;
extern struct st_maria_plugin i_s_innodb_tablespaces_scrubbing;
extern struct st_maria_plugin i_s_innodb_sys_semaphore_waits;
/** The latest successfully looked up innodb_fts_aux_table */
extern table_id_t innodb_ft_aux_table_id;
/** maximum number of buffer page info we would cache. */
#define MAX_BUF_INFO_CACHED 10000

View file

@ -396,11 +396,6 @@ extern ulong fts_min_token_size;
need a sync to free some memory */
extern bool fts_need_sync;
/** Variable specifying the table that has Fulltext index to display its
content through information schema table */
extern char* fts_internal_tbl_name;
extern char* fts_internal_tbl_name2;
#define fts_que_graph_free(graph) \
do { \
mutex_enter(&dict_sys->mutex); \
@ -452,12 +447,11 @@ fts_doc_ids_t*
fts_doc_ids_create(void);
/*=====================*/
/******************************************************************//**
Free a fts_doc_ids_t. */
void
fts_doc_ids_free(
/*=============*/
fts_doc_ids_t* doc_ids); /*!< in: doc_ids to free */
/** Free fts_doc_ids_t */
inline void fts_doc_ids_free(fts_doc_ids_t* doc_ids)
{
mem_heap_free(static_cast<mem_heap_t*>(doc_ids->self_heap->arg));
}
/******************************************************************//**
Notify the FTS system about an operation on an FTS-indexed table. */

View file

@ -1454,7 +1454,8 @@ error_exit:
doc_id = fts_get_doc_id_from_row(table, node->row);
if (doc_id <= 0) {
ib::error() << "FTS Doc ID must be large than 0";
ib::error() << "FTS_DOC_ID must be larger than 0 for table "
<< table->name;
err = DB_FTS_INVALID_DOCID;
trx->error_state = DB_FTS_INVALID_DOCID;
goto error_exit;
@ -1465,8 +1466,7 @@ error_exit:
= table->fts->cache->next_doc_id;
if (doc_id < next_doc_id) {
ib::error() << "FTS Doc ID must be large than "
ib::error() << "FTS_DOC_ID must be larger than "
<< next_doc_id - 1 << " for table "
<< table->name;

View file

@ -107,11 +107,6 @@ UNIV_INTERN mysql_pfs_key_t fts_doc_id_mutex_key;
UNIV_INTERN mysql_pfs_key_t fts_pll_tokenize_mutex_key;
#endif /* UNIV_PFS_MUTEX */
/** variable to record innodb_fts_internal_tbl_name for information
schema table INNODB_FTS_INSERTED etc. */
UNIV_INTERN char* fts_internal_tbl_name = NULL;
UNIV_INTERN char* fts_internal_tbl_name2 = NULL;
/** InnoDB default stopword list:
There are different versions of stopwords, the stop words listed
below comes from "Google Stopword" list. Reference:
@ -2889,22 +2884,6 @@ fts_doc_ids_create(void)
return(fts_doc_ids);
}
/*********************************************************************//**
Free a fts_doc_ids_t. */
void
fts_doc_ids_free(
/*=============*/
fts_doc_ids_t* fts_doc_ids)
{
mem_heap_t* heap = static_cast<mem_heap_t*>(
fts_doc_ids->self_heap->arg);
memset(fts_doc_ids, 0, sizeof(*fts_doc_ids));
mem_heap_free(heap);
}
/*********************************************************************//**
Do commit-phase steps necessary for the insertion of a new row. */
void

View file

@ -1799,8 +1799,6 @@ fts_optimize_words(
fetch.read_arg = optim->words;
fetch.read_record = fts_optimize_index_fetch_node;
fprintf(stderr, "%.*s\n", (int) word->f_len, word->f_str);
while(!optim->done) {
dberr_t error;
trx_t* trx = optim->trx;

View file

@ -14034,7 +14034,7 @@ innodb_rec_per_key(
}
/* If the number of NULL values is the same as or
large than that of the distinct values, we could
larger than that of the distinct values, we could
consider that the table consists mostly of NULL value.
Set rec_per_key to 1. */
if (n_diff <= n_null) {
@ -17767,98 +17767,36 @@ innodb_stopword_table_validate(
return(ret);
}
/*************************************************************//**
Check whether valid argument given to "innodb_fts_internal_tbl_name"
This function is registered as a callback with MySQL.
@return 0 for valid stopword table */
static
int
innodb_internal_table_validate(
/*===========================*/
THD* thd, /*!< in: thread handle */
struct st_mysql_sys_var* var, /*!< in: pointer to system
variable */
void* save, /*!< out: immediate result
for update function */
struct st_mysql_value* value) /*!< in: incoming string */
/** The latest assigned innodb_ft_aux_table name */
static char* innodb_ft_aux_table;
/** Update innodb_ft_aux_table_id on SET GLOBAL innodb_ft_aux_table.
@param[out] save new value of innodb_ft_aux_table
@param[in] value user-specified value */
static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*,
void* save, st_mysql_value* value)
{
const char* table_name;
char buff[STRING_BUFFER_USUAL_SIZE];
int len = sizeof(buff);
int ret = 1;
dict_table_t* user_table;
char buf[STRING_BUFFER_USUAL_SIZE];
int len = sizeof buf;
ut_a(save != NULL);
ut_a(value != NULL);
table_name = value->val_str(value, buff, &len);
if (!table_name) {
*static_cast<const char**>(save) = NULL;
return(0);
}
user_table = dict_table_open_on_name(
table_name, FALSE, TRUE, DICT_ERR_IGNORE_NONE);
if (user_table) {
if (dict_table_has_fts_index(user_table)) {
*static_cast<const char**>(save) = table_name;
ret = 0;
if (const char* table_name = value->val_str(value, buf, &len)) {
if (dict_table_t* table = dict_table_open_on_name(
table_name, FALSE, TRUE, DICT_ERR_IGNORE_NONE)) {
const table_id_t id = dict_table_has_fts_index(table)
? table->id : 0;
dict_table_close(table, FALSE, FALSE);
if (id) {
innodb_ft_aux_table_id = id;
*static_cast<const char**>(save) = table_name;
return 0;
}
}
dict_table_close(user_table, FALSE, TRUE);
DBUG_EXECUTE_IF("innodb_evict_autoinc_table",
mutex_enter(&dict_sys->mutex);
dict_table_remove_from_cache_low(user_table, TRUE);
mutex_exit(&dict_sys->mutex);
);
}
return(ret);
}
/****************************************************************//**
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;
if (table_name) {
*(char**) var_ptr = my_strdup(table_name, MYF(0));
return 1;
} else {
*(char**) var_ptr = NULL;
}
if (old) {
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;
*static_cast<char**>(save) = NULL;
innodb_ft_aux_table_id = 0;
return 0;
}
}
@ -20621,11 +20559,10 @@ static MYSQL_SYSVAR_BOOL(disable_sort_file_cache, srv_disable_sort_file_cache,
"Whether to disable OS system file cache for sort I/O",
NULL, NULL, FALSE);
static MYSQL_SYSVAR_STR(ft_aux_table, fts_internal_tbl_name2,
PLUGIN_VAR_NOCMDARG,
static MYSQL_SYSVAR_STR(ft_aux_table, innodb_ft_aux_table,
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_MEMALLOC,
"FTS internal auxiliary table to be checked",
innodb_internal_table_validate,
innodb_internal_table_update, NULL);
innodb_ft_aux_table_validate, NULL, NULL);
static MYSQL_SYSVAR_ULONG(ft_cache_size, fts_max_cache_size,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,

View file

@ -75,6 +75,9 @@ Modified Dec 29, 2014 Jan Lindström (Added sys_semaphore_waits)
#include "fil0fil.h"
#include "fil0crypt.h"
/** The latest successfully looked up innodb_fts_aux_table */
UNIV_INTERN table_id_t innodb_ft_aux_table_id;
/** structure associates a name string with a file page type and/or buffer
page state. */
struct buf_page_desc_t{
@ -2928,25 +2931,21 @@ i_s_fts_deleted_generic_fill(
DBUG_RETURN(0);
}
if (!fts_internal_tbl_name) {
DBUG_RETURN(0);
}
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
/* Prevent DDL to drop fts aux tables. */
/* Prevent DROP of the internal tables for fulltext indexes.
FIXME: acquire DDL-blocking MDL on the user table name! */
rw_lock_s_lock(&dict_operation_lock);
user_table = dict_table_open_on_name(
fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
user_table = dict_table_open_on_id(
innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL);
if (!user_table) {
rw_lock_s_unlock(&dict_operation_lock);
DBUG_RETURN(0);
} else if (!dict_table_has_fts_index(user_table)) {
dict_table_close(user_table, FALSE, FALSE);
rw_lock_s_unlock(&dict_operation_lock);
DBUG_RETURN(0);
}
@ -2961,6 +2960,12 @@ i_s_fts_deleted_generic_fill(
fts_table_fetch_doc_ids(trx, &fts_table, deleted);
dict_table_close(user_table, FALSE, FALSE);
rw_lock_s_unlock(&dict_operation_lock);
trx_free_for_background(trx);
fields = table->field;
int ret = 0;
@ -2975,14 +2980,8 @@ i_s_fts_deleted_generic_fill(
BREAK_IF(ret = schema_table_store_record(thd, table));
}
trx_free_for_background(trx);
fts_doc_ids_free(deleted);
dict_table_close(user_table, FALSE, FALSE);
rw_lock_s_unlock(&dict_operation_lock);
DBUG_RETURN(ret);
}
@ -3340,32 +3339,33 @@ i_s_fts_index_cache_fill(
DBUG_RETURN(0);
}
if (!fts_internal_tbl_name) {
DBUG_RETURN(0);
}
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
user_table = dict_table_open_on_name(
fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
/* Prevent DROP of the internal tables for fulltext indexes.
FIXME: acquire DDL-blocking MDL on the user table name! */
rw_lock_s_lock(&dict_operation_lock);
user_table = dict_table_open_on_id(
innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL);
if (!user_table) {
no_fts:
rw_lock_s_unlock(&dict_operation_lock);
DBUG_RETURN(0);
}
if (user_table->fts == NULL || user_table->fts->cache == NULL) {
if (!user_table->fts || !user_table->fts->cache) {
dict_table_close(user_table, FALSE, FALSE);
DBUG_RETURN(0);
goto no_fts;
}
cache = user_table->fts->cache;
ut_a(cache);
int ret = 0;
fts_string_t conv_str;
conv_str.f_len = system_charset_info->mbmaxlen
* FTS_MAX_WORD_LEN_IN_CHAR;
conv_str.f_str = static_cast<byte*>(ut_malloc(conv_str.f_len));
byte word[HA_FT_MAXBYTELEN + 1];
conv_str.f_len = sizeof word;
conv_str.f_str = word;
for (ulint i = 0; i < ib_vector_size(cache->indexes); i++) {
fts_index_cache_t* index_cache;
@ -3377,9 +3377,8 @@ i_s_fts_index_cache_fill(
index_cache, thd, &conv_str, tables));
}
ut_free(conv_str.f_str);
dict_table_close(user_table, FALSE, FALSE);
rw_lock_s_unlock(&dict_operation_lock);
DBUG_RETURN(ret);
}
@ -3792,19 +3791,17 @@ i_s_fts_index_table_fill(
DBUG_RETURN(0);
}
if (!fts_internal_tbl_name) {
DBUG_RETURN(0);
}
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
/* Prevent DDL to drop fts aux tables. */
/* Prevent DROP of the internal tables for fulltext indexes.
FIXME: acquire DDL-blocking MDL on the user table name! */
rw_lock_s_lock(&dict_operation_lock);
user_table = dict_table_open_on_name(
fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
user_table = dict_table_open_on_id(
innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL);
if (!user_table) {
rw_lock_s_unlock(&dict_operation_lock);
DBUG_RETURN(0);
}
@ -3956,32 +3953,28 @@ i_s_fts_config_fill(
DBUG_RETURN(0);
}
if (!fts_internal_tbl_name) {
DBUG_RETURN(0);
}
RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name);
DEBUG_SYNC_C("i_s_fts_config_fille_check");
fields = table->field;
/* Prevent DDL to drop fts aux tables. */
/* Prevent DROP of the internal tables for fulltext indexes.
FIXME: acquire DDL-blocking MDL on the user table name! */
rw_lock_s_lock(&dict_operation_lock);
user_table = dict_table_open_on_name(
fts_internal_tbl_name, FALSE, FALSE, DICT_ERR_IGNORE_NONE);
user_table = dict_table_open_on_id(
innodb_ft_aux_table_id, FALSE, DICT_TABLE_OP_NORMAL);
if (!user_table) {
no_fts:
rw_lock_s_unlock(&dict_operation_lock);
DBUG_RETURN(0);
} else if (!dict_table_has_fts_index(user_table)) {
dict_table_close(user_table, FALSE, FALSE);
rw_lock_s_unlock(&dict_operation_lock);
DBUG_RETURN(0);
}
if (!dict_table_has_fts_index(user_table)) {
dict_table_close(user_table, FALSE, FALSE);
goto no_fts;
}
fields = table->field;
trx = trx_allocate_for_background();
trx->op_info = "Select for FTS CONFIG TABLE";
@ -4033,12 +4026,12 @@ i_s_fts_config_fill(
fts_sql_commit(trx);
trx_free_for_background(trx);
dict_table_close(user_table, FALSE, FALSE);
rw_lock_s_unlock(&dict_operation_lock);
trx_free_for_background(trx);
DBUG_RETURN(ret);
}

View file

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyrigth (c) 2014, 2017, MariaDB Corporation.
Copyrigth (c) 2014, 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
@ -27,6 +27,7 @@ Modified Dec 29, 2014 Jan Lindström
#ifndef i_s_h
#define i_s_h
#include "dict0types.h"
const char plugin_author[] = "Oracle Corporation";
const char maria_plugin_author[] = "MariaDB Corporation";
@ -69,6 +70,9 @@ extern struct st_maria_plugin i_s_innodb_tablespaces_scrubbing;
extern struct st_mysql_plugin i_s_innodb_sys_semaphore_waits;
extern struct st_mysql_plugin i_s_innodb_changed_page_bitmaps;
/** The latest successfully looked up innodb_fts_aux_table */
extern table_id_t innodb_ft_aux_table_id;
/** maximum number of buffer page info we would cache. */
#define MAX_BUF_INFO_CACHED 10000

View file

@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, 2017, MariaDB Corporation.
Copyright (c) 2016, 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
@ -367,11 +367,6 @@ extern bool fts_need_sync;
/** Maximum possible Fulltext word length (in characters) */
#define FTS_MAX_WORD_LEN_IN_CHAR HA_FT_MAXCHARLEN
/** Variable specifying the table that has Fulltext index to display its
content through information schema table */
extern char* fts_internal_tbl_name;
extern char* fts_internal_tbl_name2;
#define fts_que_graph_free(graph) \
do { \
mutex_enter(&dict_sys->mutex); \
@ -429,13 +424,11 @@ fts_doc_ids_t*
fts_doc_ids_create(void);
/*=====================*/
/******************************************************************//**
Free a fts_doc_ids_t. */
UNIV_INTERN
void
fts_doc_ids_free(
/*=============*/
fts_doc_ids_t* doc_ids); /*!< in: doc_ids to free */
/** Free fts_doc_ids_t */
inline void fts_doc_ids_free(fts_doc_ids_t* doc_ids)
{
mem_heap_free(static_cast<mem_heap_t*>(doc_ids->self_heap->arg));
}
/******************************************************************//**
Notify the FTS system about an operation on an FTS-indexed table. */

View file

@ -1476,8 +1476,9 @@ error_exit:
doc_id = fts_get_doc_id_from_row(table, node->row);
if (doc_id <= 0) {
fprintf(stderr,
"InnoDB: FTS Doc ID must be large than 0 \n");
ib_logf(IB_LOG_LEVEL_ERROR,
"FTS_DOC_ID must be larger than 0"
" for table %s", table->name);
err = DB_FTS_INVALID_DOCID;
trx->error_state = DB_FTS_INVALID_DOCID;
goto error_exit;
@ -1488,12 +1489,10 @@ error_exit:
= table->fts->cache->next_doc_id;
if (doc_id < next_doc_id) {
fprintf(stderr,
"InnoDB: FTS Doc ID must be large than"
" " UINT64PF " for table",
next_doc_id - 1);
ut_print_name(stderr, trx, TRUE, table->name);
putc('\n', stderr);
ib_logf(IB_LOG_LEVEL_ERROR,
"FTS_DOC_ID must be larger than "
UINT64PF " for table %s",
next_doc_id - 1, table->name);
err = DB_FTS_INVALID_DOCID;
trx->error_state = DB_FTS_INVALID_DOCID;