|
|
@ -40,7 +40,7 @@ this program; if not, write to the Free Software Foundation, Inc., |
|
|
|
#include <my_base.h> // HA_OPTION_*
|
|
|
|
#include <mysys_err.h>
|
|
|
|
#include <mysql/innodb_priv.h>
|
|
|
|
|
|
|
|
#include <my_check_opt.h>
|
|
|
|
/** @file ha_innodb.cc */ |
|
|
|
|
|
|
|
/* Include necessary InnoDB headers */ |
|
|
@ -188,8 +188,6 @@ static char* internal_innobase_data_file_path = NULL; |
|
|
|
|
|
|
|
static char* innodb_version_str = (char*) INNODB_VERSION_STR; |
|
|
|
|
|
|
|
static char* fts_server_stopword_table = NULL; |
|
|
|
|
|
|
|
/** Possible values for system variable "innodb_stats_method". The values
|
|
|
|
are defined the same as its corresponding MyISAM system variable |
|
|
|
"myisam_stats_method"(see "myisam_stats_method_names"), for better usability */ |
|
|
@ -299,6 +297,7 @@ static PSI_mutex_info all_innodb_mutexes[] = { |
|
|
|
{&fts_delete_mutex_key, "fts_delete_mutex", 0}, |
|
|
|
{&fts_optimize_mutex_key, "fts_optimize_mutex", 0}, |
|
|
|
{&fts_doc_id_mutex_key, "fts_doc_id_mutex", 0}, |
|
|
|
{&fts_pll_tokenize_mutex_key, "fts_pll_tokenize_mutex", 0}, |
|
|
|
{&log_flush_order_mutex_key, "log_flush_order_mutex", 0}, |
|
|
|
{&hash_table_mutex_key, "hash_table_mutex", 0}, |
|
|
|
{&ibuf_bitmap_mutex_key, "ibuf_bitmap_mutex", 0}, |
|
|
@ -481,7 +480,8 @@ ib_cb_t innodb_api_cb[] = { |
|
|
|
(ib_cb_t) ib_cursor_clear_trx, |
|
|
|
(ib_cb_t) ib_get_idx_field_name, |
|
|
|
(ib_cb_t) ib_trx_get_start_time, |
|
|
|
(ib_cb_t) ib_cfg_bk_commit_interval |
|
|
|
(ib_cb_t) ib_cfg_bk_commit_interval, |
|
|
|
(ib_cb_t) ib_cursor_stmt_begin |
|
|
|
}; |
|
|
|
|
|
|
|
/*************************************************************//**
|
|
|
@ -1443,6 +1443,9 @@ convert_error_code_to_mysql( |
|
|
|
case DB_OUT_OF_FILE_SPACE: |
|
|
|
return(HA_ERR_RECORD_FILE_FULL); |
|
|
|
|
|
|
|
case DB_TEMP_FILE_WRITE_FAILURE: |
|
|
|
return(HA_ERR_TEMP_FILE_WRITE_FAILURE); |
|
|
|
|
|
|
|
case DB_TABLE_IN_FK_CHECK: |
|
|
|
return(HA_ERR_TABLE_IN_FK_CHECK); |
|
|
|
|
|
|
@ -2990,12 +2993,6 @@ mem_free_and_error: |
|
|
|
goto mem_free_and_error; |
|
|
|
} |
|
|
|
|
|
|
|
/* Remember stopword table name supplied at startup */ |
|
|
|
if (innobase_server_stopword_table) { |
|
|
|
fts_server_stopword_table = |
|
|
|
my_strdup(innobase_server_stopword_table, MYF(0)); |
|
|
|
} |
|
|
|
|
|
|
|
if (innobase_change_buffering) { |
|
|
|
ulint use; |
|
|
|
|
|
|
@ -5413,6 +5410,7 @@ innobase_mysql_fts_get_token( |
|
|
|
ut_a(cs); |
|
|
|
|
|
|
|
token->f_n_char = token->f_len = 0; |
|
|
|
token->f_str = NULL; |
|
|
|
|
|
|
|
for (;;) { |
|
|
|
|
|
|
@ -8012,7 +8010,7 @@ ha_innobase::ft_init_ext( |
|
|
|
String* key) /* in: */ |
|
|
|
{ |
|
|
|
trx_t* trx; |
|
|
|
dict_table_t* table; |
|
|
|
dict_table_t* ft_table; |
|
|
|
dberr_t error; |
|
|
|
byte* query = (byte*) key->ptr(); |
|
|
|
ulint query_len = key->length(); |
|
|
@ -8062,17 +8060,24 @@ ha_innobase::ft_init_ext( |
|
|
|
++trx->will_lock; |
|
|
|
} |
|
|
|
|
|
|
|
table = prebuilt->table; |
|
|
|
ft_table = prebuilt->table; |
|
|
|
|
|
|
|
/* Table does not have an FTS index */ |
|
|
|
if (!table->fts || ib_vector_is_empty(table->fts->indexes)) { |
|
|
|
if (!ft_table->fts || ib_vector_is_empty(ft_table->fts->indexes)) { |
|
|
|
my_error(ER_TABLE_HAS_NO_FT, MYF(0)); |
|
|
|
return(NULL); |
|
|
|
} |
|
|
|
|
|
|
|
/* If tablespace is discarded, we should return here */ |
|
|
|
if (dict_table_is_discarded(ft_table)) { |
|
|
|
my_error(ER_NO_SUCH_TABLE, MYF(0), table->s->db.str, |
|
|
|
table->s->table_name.str); |
|
|
|
return(NULL); |
|
|
|
} |
|
|
|
|
|
|
|
if (keynr == NO_SUCH_KEY) { |
|
|
|
/* FIXME: Investigate the NO_SUCH_KEY usage */ |
|
|
|
index = (dict_index_t*) ib_vector_getp(table->fts->indexes, 0); |
|
|
|
index = (dict_index_t*) ib_vector_getp(ft_table->fts->indexes, 0); |
|
|
|
} else { |
|
|
|
index = innobase_get_index(keynr); |
|
|
|
} |
|
|
@ -8082,10 +8087,10 @@ ha_innobase::ft_init_ext( |
|
|
|
return(NULL); |
|
|
|
} |
|
|
|
|
|
|
|
if (!(table->fts->fts_status & ADDED_TABLE_SYNCED)) { |
|
|
|
fts_init_index(table, FALSE); |
|
|
|
if (!(ft_table->fts->fts_status & ADDED_TABLE_SYNCED)) { |
|
|
|
fts_init_index(ft_table, FALSE); |
|
|
|
|
|
|
|
table->fts->fts_status |= ADDED_TABLE_SYNCED; |
|
|
|
ft_table->fts->fts_status |= ADDED_TABLE_SYNCED; |
|
|
|
} |
|
|
|
|
|
|
|
error = fts_query(trx, index, flags, query, query_len, &result); |
|
|
@ -9065,7 +9070,7 @@ innobase_fts_load_stopword( |
|
|
|
THD* thd) /*!< in: current thread */ |
|
|
|
{ |
|
|
|
return(fts_load_stopword(table, trx, |
|
|
|
fts_server_stopword_table, |
|
|
|
innobase_server_stopword_table, |
|
|
|
THDVAR(thd, ft_user_stopword_table), |
|
|
|
THDVAR(thd, ft_enable_stopword), FALSE)); |
|
|
|
} |
|
|
@ -10341,6 +10346,10 @@ ha_innobase::records_in_range( |
|
|
|
/* There exists possibility of not being able to find requested
|
|
|
|
index due to inconsistency between MySQL and InoDB dictionary info. |
|
|
|
Necessary message should have been printed in innobase_get_index() */ |
|
|
|
if (dict_table_is_discarded(prebuilt->table)) { |
|
|
|
n_rows = HA_POS_ERROR; |
|
|
|
goto func_exit; |
|
|
|
} |
|
|
|
if (UNIV_UNLIKELY(!index)) { |
|
|
|
n_rows = HA_POS_ERROR; |
|
|
|
goto func_exit; |
|
|
@ -11182,13 +11191,12 @@ int |
|
|
|
ha_innobase::check( |
|
|
|
/*===============*/ |
|
|
|
THD* thd, /*!< in: user thread handle */ |
|
|
|
HA_CHECK_OPT* check_opt) /*!< in: check options, currently
|
|
|
|
ignored */ |
|
|
|
HA_CHECK_OPT* check_opt) /*!< in: check options */ |
|
|
|
{ |
|
|
|
dict_index_t* index; |
|
|
|
ulint n_rows; |
|
|
|
ulint n_rows_in_table = ULINT_UNDEFINED; |
|
|
|
ibool is_ok = TRUE; |
|
|
|
bool is_ok = true; |
|
|
|
ulint old_isolation_level; |
|
|
|
ibool table_corrupted; |
|
|
|
|
|
|
@ -11244,35 +11252,49 @@ ha_innobase::check( |
|
|
|
do additional check */ |
|
|
|
prebuilt->table->corrupted = FALSE; |
|
|
|
|
|
|
|
/* Enlarge the fatal lock wait timeout during CHECK TABLE. */ |
|
|
|
os_increment_counter_by_amount( |
|
|
|
server_mutex, |
|
|
|
srv_fatal_semaphore_wait_threshold, |
|
|
|
SRV_SEMAPHORE_WAIT_EXTENSION); |
|
|
|
|
|
|
|
for (index = dict_table_get_first_index(prebuilt->table); |
|
|
|
index != NULL; |
|
|
|
index = dict_table_get_next_index(index)) { |
|
|
|
char index_name[MAX_FULL_NAME_LEN + 1]; |
|
|
|
|
|
|
|
/* If this is an index being created or dropped, break */ |
|
|
|
/* If this is an index being created or dropped, skip */ |
|
|
|
if (*index->name == TEMP_INDEX_PREFIX) { |
|
|
|
break; |
|
|
|
} else if (!btr_validate_index(index, prebuilt->trx)) { |
|
|
|
is_ok = FALSE; |
|
|
|
|
|
|
|
innobase_format_name( |
|
|
|
index_name, sizeof index_name, |
|
|
|
index->name, TRUE); |
|
|
|
|
|
|
|
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, |
|
|
|
ER_NOT_KEYFILE, |
|
|
|
"InnoDB: The B-tree of" |
|
|
|
" index %s is corrupted.", |
|
|
|
index_name); |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
if (!(check_opt->flags & T_QUICK)) { |
|
|
|
/* Enlarge the fatal lock wait timeout during
|
|
|
|
CHECK TABLE. */ |
|
|
|
os_increment_counter_by_amount( |
|
|
|
server_mutex, |
|
|
|
srv_fatal_semaphore_wait_threshold, |
|
|
|
SRV_SEMAPHORE_WAIT_EXTENSION); |
|
|
|
bool valid = btr_validate_index(index, prebuilt->trx); |
|
|
|
|
|
|
|
/* Restore the fatal lock wait timeout after
|
|
|
|
CHECK TABLE. */ |
|
|
|
os_decrement_counter_by_amount( |
|
|
|
server_mutex, |
|
|
|
srv_fatal_semaphore_wait_threshold, |
|
|
|
SRV_SEMAPHORE_WAIT_EXTENSION); |
|
|
|
|
|
|
|
if (!valid) { |
|
|
|
is_ok = false; |
|
|
|
|
|
|
|
innobase_format_name( |
|
|
|
index_name, sizeof index_name, |
|
|
|
index->name, TRUE); |
|
|
|
push_warning_printf( |
|
|
|
thd, |
|
|
|
Sql_condition::WARN_LEVEL_WARN, |
|
|
|
ER_NOT_KEYFILE, |
|
|
|
"InnoDB: The B-tree of" |
|
|
|
" index %s is corrupted.", |
|
|
|
index_name); |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/* Instead of invoking change_active_index(), set up
|
|
|
|
a dummy template for non-locking reads, disabling |
|
|
|
access to the clustered index. */ |
|
|
@ -11294,7 +11316,7 @@ ha_innobase::check( |
|
|
|
"InnoDB: Index %s is marked as" |
|
|
|
" corrupted", |
|
|
|
index_name); |
|
|
|
is_ok = FALSE; |
|
|
|
is_ok = false; |
|
|
|
} else { |
|
|
|
push_warning_printf( |
|
|
|
thd, |
|
|
@ -11327,7 +11349,7 @@ ha_innobase::check( |
|
|
|
"InnoDB: The B-tree of" |
|
|
|
" index %s is corrupted.", |
|
|
|
index_name); |
|
|
|
is_ok = FALSE; |
|
|
|
is_ok = false; |
|
|
|
dict_set_corrupted( |
|
|
|
index, prebuilt->trx, "CHECK TABLE-check index"); |
|
|
|
} |
|
|
@ -11353,7 +11375,7 @@ ha_innobase::check( |
|
|
|
index->name, |
|
|
|
(ulong) n_rows, |
|
|
|
(ulong) n_rows_in_table); |
|
|
|
is_ok = FALSE; |
|
|
|
is_ok = false; |
|
|
|
dict_set_corrupted( |
|
|
|
index, prebuilt->trx, |
|
|
|
"CHECK TABLE; Wrong count"); |
|
|
@ -11376,21 +11398,17 @@ ha_innobase::check( |
|
|
|
/* Restore the original isolation level */ |
|
|
|
prebuilt->trx->isolation_level = old_isolation_level; |
|
|
|
|
|
|
|
/* We validate also the whole adaptive hash index for all tables
|
|
|
|
at every CHECK TABLE */ |
|
|
|
/* We validate the whole adaptive hash index for all tables
|
|
|
|
at every CHECK TABLE only when QUICK flag is not present. */ |
|
|
|
|
|
|
|
if (!btr_search_validate()) { |
|
|
|
#if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG
|
|
|
|
if (!(check_opt->flags & T_QUICK) && !btr_search_validate()) { |
|
|
|
push_warning(thd, Sql_condition::WARN_LEVEL_WARN, |
|
|
|
ER_NOT_KEYFILE, |
|
|
|
"InnoDB: The adaptive hash index is corrupted."); |
|
|
|
is_ok = FALSE; |
|
|
|
is_ok = false; |
|
|
|
} |
|
|
|
|
|
|
|
/* Restore the fatal lock wait timeout after CHECK TABLE. */ |
|
|
|
os_decrement_counter_by_amount( |
|
|
|
server_mutex, |
|
|
|
srv_fatal_semaphore_wait_threshold, |
|
|
|
SRV_SEMAPHORE_WAIT_EXTENSION); |
|
|
|
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
|
|
|
|
|
|
|
|
prebuilt->trx->op_info = ""; |
|
|
|
if (thd_killed(user_thd)) { |
|
|
@ -12353,6 +12371,7 @@ innodb_show_status( |
|
|
|
const long MAX_STATUS_SIZE = 1048576; |
|
|
|
ulint trx_list_start = ULINT_UNDEFINED; |
|
|
|
ulint trx_list_end = ULINT_UNDEFINED; |
|
|
|
bool ret_val; |
|
|
|
|
|
|
|
DBUG_ENTER("innodb_show_status"); |
|
|
|
DBUG_ASSERT(hton == innodb_hton_ptr); |
|
|
@ -12429,12 +12448,13 @@ innodb_show_status( |
|
|
|
|
|
|
|
mutex_exit(&srv_monitor_file_mutex); |
|
|
|
|
|
|
|
stat_print(thd, innobase_hton_name, (uint) strlen(innobase_hton_name), |
|
|
|
STRING_WITH_LEN(""), str, flen); |
|
|
|
ret_val= stat_print(thd, innobase_hton_name, |
|
|
|
(uint) strlen(innobase_hton_name), |
|
|
|
STRING_WITH_LEN(""), str, flen); |
|
|
|
|
|
|
|
my_free(str); |
|
|
|
|
|
|
|
DBUG_RETURN(0); |
|
|
|
DBUG_RETURN(ret_val); |
|
|
|
} |
|
|
|
|
|
|
|
/************************************************************************//**
|
|
|
@ -14126,44 +14146,6 @@ innodb_stopword_table_validate( |
|
|
|
return(ret); |
|
|
|
} |
|
|
|
|
|
|
|
/****************************************************************//**
|
|
|
|
Update global variable fts_server_stopword_table with the "saved" |
|
|
|
stopword table name value. This function is registered as a callback |
|
|
|
with MySQL. */ |
|
|
|
static |
|
|
|
void |
|
|
|
innodb_stopword_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* stopword_table_name; |
|
|
|
char* old; |
|
|
|
|
|
|
|
ut_a(save != NULL); |
|
|
|
ut_a(var_ptr != NULL); |
|
|
|
|
|
|
|
stopword_table_name = *static_cast<const char*const*>(save); |
|
|
|
old = *(char**) var_ptr; |
|
|
|
|
|
|
|
if (stopword_table_name) { |
|
|
|
*(char**) var_ptr = my_strdup(stopword_table_name, MYF(0)); |
|
|
|
} else { |
|
|
|
*(char**) var_ptr = NULL; |
|
|
|
} |
|
|
|
|
|
|
|
if (old) { |
|
|
|
my_free(old); |
|
|
|
} |
|
|
|
|
|
|
|
fts_server_stopword_table = *(char**) var_ptr; |
|
|
|
} |
|
|
|
|
|
|
|
/*************************************************************//**
|
|
|
|
Check whether valid argument given to "innodb_fts_internal_tbl_name" |
|
|
|
This function is registered as a callback with MySQL. |
|
|
@ -15605,10 +15587,10 @@ static MYSQL_SYSVAR_STR(file_format_max, innobase_file_format_max, |
|
|
|
innodb_file_format_max_update, "Antelope"); |
|
|
|
|
|
|
|
static MYSQL_SYSVAR_STR(ft_server_stopword_table, innobase_server_stopword_table, |
|
|
|
PLUGIN_VAR_OPCMDARG, |
|
|
|
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_MEMALLOC, |
|
|
|
"The user supplied stopword table name.", |
|
|
|
innodb_stopword_table_validate, |
|
|
|
innodb_stopword_table_update, |
|
|
|
NULL, |
|
|
|
NULL); |
|
|
|
|
|
|
|
static MYSQL_SYSVAR_UINT(flush_log_at_timeout, srv_flush_log_at_timeout, |
|
|
|