summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2016-09-27 17:56:00 +0200
committerSergei Golubchik <serg@mariadb.org>2016-09-27 17:56:00 +0200
commit094f140c9ae672eb61a27f15c5e99c7114ed0150 (patch)
tree2987735abf082321330effa86687acc3db360eaf /storage/innobase
parentb4f97a1499c8c5de454f0593d9d694057d0a46c9 (diff)
downloadmariadb-git-094f140c9ae672eb61a27f15c5e99c7114ed0150.tar.gz
5.6.33
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/fts/fts0fts.cc31
-rw-r--r--storage/innobase/handler/ha_innodb.cc9
-rw-r--r--storage/innobase/handler/handler0alter.cc9
-rw-r--r--storage/innobase/handler/i_s.cc2
-rw-r--r--storage/innobase/include/fts0fts.h10
-rw-r--r--storage/innobase/row/row0log.cc14
-rw-r--r--storage/innobase/row/row0mysql.cc34
7 files changed, 97 insertions, 12 deletions
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 25059db96b0..a0f0fab5566 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -108,6 +108,7 @@ UNIV_INTERN mysql_pfs_key_t fts_pll_tokenize_mutex_key;
/** 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
@@ -6569,6 +6570,36 @@ fts_check_corrupt_index(
return(0);
}
+/* Get parent table name if it's a fts aux table
+@param[in] aux_table_name aux table name
+@param[in] aux_table_len aux table length
+@return parent table name, or NULL */
+char*
+fts_get_parent_table_name(
+ const char* aux_table_name,
+ ulint aux_table_len)
+{
+ fts_aux_table_t aux_table;
+ char* parent_table_name = NULL;
+
+ if (fts_is_aux_table_name(&aux_table, aux_table_name, aux_table_len)) {
+ dict_table_t* parent_table;
+
+ parent_table = dict_table_open_on_id(
+ aux_table.parent_id, TRUE, DICT_TABLE_OP_NORMAL);
+
+ if (parent_table != NULL) {
+ parent_table_name = mem_strdupl(
+ parent_table->name,
+ strlen(parent_table->name));
+
+ dict_table_close(parent_table, TRUE, FALSE);
+ }
+ }
+
+ return(parent_table_name);
+}
+
/** Check the validity of the parent table.
@param[in] aux_table auxiliary table
@return true if it is a valid table or false if it is not */
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 95a0e08a806..be5e74e1617 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -14505,7 +14505,12 @@ innodb_internal_table_update(
my_free(old);
}
- fts_internal_tbl_name = *(char**) var_ptr;
+ 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;
+ }
}
/****************************************************************//**
@@ -16253,7 +16258,7 @@ 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_name,
+static MYSQL_SYSVAR_STR(ft_aux_table, fts_internal_tbl_name2,
PLUGIN_VAR_NOCMDARG,
"FTS internal auxiliary table to be checked",
innodb_internal_table_validate,
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 961e0818d39..2261754a4f5 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -201,7 +201,10 @@ innobase_need_rebuild(
/*==================*/
const Alter_inplace_info* ha_alter_info)
{
- if (ha_alter_info->handler_flags
+ Alter_inplace_info::HA_ALTER_FLAGS alter_inplace_flags =
+ ha_alter_info->handler_flags & ~(INNOBASE_INPLACE_IGNORE);
+
+ if (alter_inplace_flags
== Alter_inplace_info::CHANGE_CREATE_OPTION
&& !(ha_alter_info->create_info->used_fields
& (HA_CREATE_USED_ROW_FORMAT
@@ -3760,7 +3763,7 @@ err_exit:
}
if (!(ha_alter_info->handler_flags & INNOBASE_ALTER_DATA)
- || (ha_alter_info->handler_flags
+ || ((ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE)
== Alter_inplace_info::CHANGE_CREATE_OPTION
&& !innobase_need_rebuild(ha_alter_info))) {
@@ -3926,7 +3929,7 @@ ok_exit:
DBUG_RETURN(false);
}
- if (ha_alter_info->handler_flags
+ if ((ha_alter_info->handler_flags & ~INNOBASE_INPLACE_IGNORE)
== Alter_inplace_info::CHANGE_CREATE_OPTION
&& !innobase_need_rebuild(ha_alter_info)) {
goto ok_exit;
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 43905f4a32b..a780ee5cd62 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -4038,6 +4038,8 @@ i_s_fts_config_fill(
DBUG_RETURN(0);
}
+ DEBUG_SYNC_C("i_s_fts_config_fille_check");
+
fields = table->field;
/* Prevent DDL to drop fts aux tables. */
diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h
index 87b5787d416..3e2f359bbeb 100644
--- a/storage/innobase/include/fts0fts.h
+++ b/storage/innobase/include/fts0fts.h
@@ -375,6 +375,7 @@ 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 { \
@@ -823,6 +824,15 @@ void
fts_drop_orphaned_tables(void);
/*==========================*/
+/* Get parent table name if it's a fts aux table
+@param[in] aux_table_name aux table name
+@param[in] aux_table_len aux table length
+@return parent table name, or NULL */
+char*
+fts_get_parent_table_name(
+ const char* aux_table_name,
+ ulint aux_table_len);
+
/******************************************************************//**
Since we do a horizontal split on the index table, we need to drop
all the split tables.
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index a6751b208f7..54183759e8d 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -613,7 +613,7 @@ row_log_table_delete(
&old_pk_extra_size);
ut_ad(old_pk_extra_size < 0x100);
- mrec_size = 4 + old_pk_size;
+ mrec_size = 6 + old_pk_size;
/* Log enough prefix of the BLOB unless both the
old and new table are in COMPACT or REDUNDANT format,
@@ -643,8 +643,8 @@ row_log_table_delete(
*b++ = static_cast<byte>(old_pk_extra_size);
/* Log the size of external prefix we saved */
- mach_write_to_2(b, ext_size);
- b += 2;
+ mach_write_to_4(b, ext_size);
+ b += 4;
rec_convert_dtuple_to_temp(
b + old_pk_extra_size, new_index,
@@ -2268,14 +2268,14 @@ row_log_table_apply_op(
break;
case ROW_T_DELETE:
- /* 1 (extra_size) + 2 (ext_size) + at least 1 (payload) */
- if (mrec + 4 >= mrec_end) {
+ /* 1 (extra_size) + 4 (ext_size) + at least 1 (payload) */
+ if (mrec + 6 >= mrec_end) {
return(NULL);
}
extra_size = *mrec++;
- ext_size = mach_read_from_2(mrec);
- mrec += 2;
+ ext_size = mach_read_from_4(mrec);
+ mrec += 4;
ut_ad(mrec < mrec_end);
/* We assume extra_size < 0x100 for the PRIMARY KEY prefix.
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index c3a7e2c2807..11bef1064d6 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -2676,6 +2676,10 @@ loop:
return(n_tables + n_tables_dropped);
}
+ DBUG_EXECUTE_IF("row_drop_tables_in_background_sleep",
+ os_thread_sleep(5000000);
+ );
+
table = dict_table_open_on_name(drop->table_name, FALSE, FALSE,
DICT_ERR_IGNORE_NONE);
@@ -2686,6 +2690,16 @@ loop:
goto already_dropped;
}
+ if (!table->to_be_dropped) {
+ /* There is a scenario: the old table is dropped
+ just after it's added into drop list, and new
+ table with the same name is created, then we try
+ to drop the new table in background. */
+ dict_table_close(table, FALSE, FALSE);
+
+ goto already_dropped;
+ }
+
ut_a(!table->can_be_evicted);
dict_table_close(table, FALSE, FALSE);
@@ -3945,6 +3959,13 @@ row_drop_table_for_mysql(
}
}
+
+ DBUG_EXECUTE_IF("row_drop_table_add_to_background",
+ row_add_table_to_background_drop_list(table->name);
+ err = DB_SUCCESS;
+ goto funct_exit;
+ );
+
/* TODO: could we replace the counter n_foreign_key_checks_running
with lock checks on the table? Acquire here an exclusive lock on the
table, and rewrite lock0lock.cc and the lock wait in srv0srv.cc so that
@@ -4561,6 +4582,19 @@ loop:
row_mysql_lock_data_dictionary(trx);
while ((table_name = dict_get_first_table_name_in_db(name))) {
+ /* Drop parent table if it is a fts aux table, to
+ avoid accessing dropped fts aux tables in information
+ scheam when parent table still exists.
+ Note: Drop parent table will drop fts aux tables. */
+ char* parent_table_name;
+ parent_table_name = fts_get_parent_table_name(
+ table_name, strlen(table_name));
+
+ if (parent_table_name != NULL) {
+ mem_free(table_name);
+ table_name = parent_table_name;
+ }
+
ut_a(memcmp(table_name, name, namelen) == 0);
table = dict_table_open_on_name(