summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--storage/innobase/dict/dict0dict.cc7
-rw-r--r--storage/innobase/fts/fts0fts.cc67
-rw-r--r--storage/innobase/handler/ha_innodb.cc45
-rw-r--r--storage/innobase/handler/handler0alter.cc35
-rw-r--r--storage/innobase/include/os0file.h6
-rw-r--r--storage/innobase/row/row0import.cc19
-rw-r--r--storage/innobase/row/row0merge.cc17
-rw-r--r--storage/innobase/row/row0mysql.cc3
-rw-r--r--storage/innobase/row/row0sel.cc4
9 files changed, 143 insertions, 60 deletions
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index b2def1edffe..1bbf50791f2 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
This program is free software; you can redistribute it and/or modify it under
@@ -3378,7 +3378,10 @@ dict_foreign_find_index(
&& dict_foreign_qualify_index(
table, col_names, columns, n_cols,
index, types_idx,
- check_charsets, check_null)) {
+ check_charsets, check_null)
+ && (!(index->online_status ==
+ ONLINE_INDEX_ABORTED_DROPPED
+ ||index->online_status == ONLINE_INDEX_ABORTED))) {
return(index);
}
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index f3fa6e52d0d..a1f56671fc8 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -868,37 +868,28 @@ fts_drop_index(
err = fts_drop_index_tables(trx, index);
- for(;;) {
- bool retry = false;
- if (index->index_fts_syncing) {
- retry = true;
- }
- if (!retry){
- fts_free(table);
- break;
- }
- DICT_BG_YIELD(trx);
- }
+ while (index->index_fts_syncing
+ && !trx_is_interrupted(trx)) {
+ DICT_BG_YIELD(trx);
+ }
+
+ fts_free(table);
+
return(err);
}
- for(;;) {
- bool retry = false;
- if (index->index_fts_syncing) {
- retry = true;
- }
- if (!retry){
- current_doc_id = table->fts->cache->next_doc_id;
- first_doc_id = table->fts->cache->first_doc_id;
- fts_cache_clear(table->fts->cache);
- fts_cache_destroy(table->fts->cache);
- table->fts->cache = fts_cache_create(table);
- table->fts->cache->next_doc_id = current_doc_id;
- table->fts->cache->first_doc_id = first_doc_id;
- break;
- }
- DICT_BG_YIELD(trx);
- }
+ while (index->index_fts_syncing
+ && !trx_is_interrupted(trx)) {
+ DICT_BG_YIELD(trx);
+ }
+
+ current_doc_id = table->fts->cache->next_doc_id;
+ first_doc_id = table->fts->cache->first_doc_id;
+ fts_cache_clear(table->fts->cache);
+ fts_cache_destroy(table->fts->cache);
+ table->fts->cache = fts_cache_create(table);
+ table->fts->cache->next_doc_id = current_doc_id;
+ table->fts->cache->first_doc_id = first_doc_id;
} else {
fts_cache_t* cache = table->fts->cache;
fts_index_cache_t* index_cache;
@@ -908,17 +899,13 @@ fts_drop_index(
index_cache = fts_find_index_cache(cache, index);
if (index_cache != NULL) {
- for(;;) {
- bool retry = false;
- if (index->index_fts_syncing) {
- retry = true;
- }
- if (!retry && index_cache->words) {
- fts_words_free(index_cache->words);
- rbt_free(index_cache->words);
- break;
- }
- DICT_BG_YIELD(trx);
+ while (index->index_fts_syncing
+ && !trx_is_interrupted(trx)) {
+ DICT_BG_YIELD(trx);
+ }
+ if (index_cache->words) {
+ fts_words_free(index_cache->words);
+ rbt_free(index_cache->words);
}
ib_vector_remove(cache->indexes, *(void**) index_cache);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index eb7fdaaddf4..accebb3f3f4 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -1919,6 +1919,11 @@ innobase_get_lower_case_table_names(void)
{
return(lower_case_table_names);
}
+/** return one of the tmpdir path
+@return tmpdir path*/
+UNIV_INTERN
+char*
+innobase_mysql_tmpdir(void) { return (mysql_tmpdir); }
/** Create a temporary file in the location specified by the parameter
path. If the path is null, then it will be created in tmpdir.
@@ -10364,6 +10369,7 @@ static MY_ATTRIBUTE((nonnull, warn_unused_result))
dberr_t
innobase_rename_table(
/*==================*/
+ THD* thd, /*!< Connection thread handle */
trx_t* trx, /*!< in: transaction */
const char* from, /*!< in: old name of the table */
const char* to) /*!< in: new name of the table */
@@ -10389,6 +10395,37 @@ innobase_rename_table(
row_mysql_lock_data_dictionary(trx);
+ dict_table_t* table = NULL;
+ table = dict_table_open_on_name(norm_from, TRUE, FALSE,
+ DICT_ERR_IGNORE_NONE);
+
+ /* Since DICT_BG_YIELD has sleep for 250 milliseconds,
+ Convert lock_wait_timeout unit from second to 250 milliseconds */
+ long int lock_wait_timeout = thd_lock_wait_timeout(thd) * 4;
+ if (table != NULL) {
+ for (dict_index_t* index = dict_table_get_first_index(table);
+ index != NULL;
+ index = dict_table_get_next_index(index)) {
+
+ if (index->type & DICT_FTS) {
+ /* Found */
+ while (index->index_fts_syncing
+ && !trx_is_interrupted(trx)
+ && (lock_wait_timeout--) > 0) {
+ DICT_BG_YIELD(trx);
+ }
+ }
+ }
+ dict_table_close(table, TRUE, FALSE);
+ }
+
+ /* FTS sync is in progress. We shall timeout this operation */
+ if (lock_wait_timeout < 0) {
+ error = DB_LOCK_WAIT_TIMEOUT;
+ row_mysql_unlock_data_dictionary(trx);
+ DBUG_RETURN(error);
+ }
+
/* Transaction must be flagged as a locking transaction or it hasn't
been started yet. */
@@ -10498,7 +10535,7 @@ ha_innobase::rename_table(
++trx->will_lock;
trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
- error = innobase_rename_table(trx, from, to);
+ error = innobase_rename_table(thd, trx, from, to);
DEBUG_SYNC(thd, "after_innobase_rename_table");
@@ -10544,6 +10581,12 @@ ha_innobase::rename_table(
error = DB_ERROR;
}
+ else if (error == DB_LOCK_WAIT_TIMEOUT) {
+ my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0), to);
+
+ error = DB_LOCK_WAIT;
+ }
+
DBUG_RETURN(convert_error_code_to_mysql(error, 0, NULL));
}
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index f945f40fc40..c6f4ea57f71 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -4013,11 +4013,23 @@ oom:
table. Either way, we should be seeing and
reporting a bogus duplicate key error. */
dup_key = NULL;
- } else {
- DBUG_ASSERT(prebuilt->trx->error_key_num
- < ha_alter_info->key_count);
+ } else if (prebuilt->trx->error_key_num == 0) {
dup_key = &ha_alter_info->key_info_buffer[
prebuilt->trx->error_key_num];
+ } else {
+ /* Check if there is generated cluster index column */
+ if (ctx->num_to_add_index > ha_alter_info->key_count) {
+ DBUG_ASSERT(prebuilt->trx->error_key_num
+ <= ha_alter_info->key_count);
+ dup_key = &ha_alter_info->key_info_buffer[
+ prebuilt->trx->error_key_num - 1];
+ }
+ else {
+ DBUG_ASSERT(prebuilt->trx->error_key_num
+ < ha_alter_info->key_count);
+ dup_key = &ha_alter_info->key_info_buffer[
+ prebuilt->trx->error_key_num];
+ }
}
print_keydup_error(altered_table, dup_key, MYF(0));
break;
@@ -4938,11 +4950,20 @@ commit_try_rebuild(
FTS_DOC_ID. */
dup_key = NULL;
} else {
- DBUG_ASSERT(err_key <
- ha_alter_info->key_count);
- dup_key = &ha_alter_info
- ->key_info_buffer[err_key];
+ if (ctx->num_to_add_index > ha_alter_info->key_count) {
+ DBUG_ASSERT(err_key <=
+ ha_alter_info->key_count);
+ dup_key = &ha_alter_info
+ ->key_info_buffer[err_key - 1];
+ }
+ else {
+ DBUG_ASSERT(err_key <
+ ha_alter_info->key_count);
+ dup_key = &ha_alter_info
+ ->key_info_buffer[err_key];
+ }
}
+
print_keydup_error(altered_table, dup_key, MYF(0));
DBUG_RETURN(true);
case DB_ONLINE_LOG_TOO_BIG:
diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
index 76a389f9051..338fa30204c 100644
--- a/storage/innobase/include/os0file.h
+++ b/storage/innobase/include/os0file.h
@@ -1,6 +1,6 @@
/***********************************************************************
-Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Percona Inc.
Portions of this file contain modifications contributed and copyrighted
@@ -1319,6 +1319,10 @@ os_file_get_status(
file can be opened in RW mode */
#if !defined(UNIV_HOTBACKUP)
+
+/** return one of the tmpdir path
+ @return tmpdir path*/
+char *innobase_mysql_tmpdir(void);
/** Create a temporary file in the location specified by the parameter
path. If the path is null, then it will be created in tmpdir.
@param[in] path location for creating temporary file
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index cd3f88c240e..c4f6eed4aad 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -1337,11 +1337,20 @@ row_import::match_schema(
/* Do some simple checks. */
if (m_flags != m_table->flags) {
- ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH,
- "Table flags don't match, server table has 0x%lx "
- "and the meta-data file has 0x%lx",
- (ulong) m_table->n_cols, (ulong) m_flags);
-
+ if (dict_tf_to_row_format_string(m_flags) !=
+ dict_tf_to_row_format_string(m_table->flags)) {
+ ib_errf(thd, IB_LOG_LEVEL_ERROR,
+ ER_TABLE_SCHEMA_MISMATCH,
+ "Table flags don't match,"
+ "server table has %s "
+ "and the meta-data file has %s",
+ dict_tf_to_row_format_string(m_table->flags),
+ dict_tf_to_row_format_string(m_flags));
+ } else {
+ ib_errf(thd, IB_LOG_LEVEL_ERROR,
+ ER_TABLE_SCHEMA_MISMATCH,
+ "Table flags don't match");
+ }
return(DB_ERROR);
} else if (m_table->n_cols != m_n_cols) {
ib_errf(thd, IB_LOG_LEVEL_ERROR, ER_TABLE_SCHEMA_MISMATCH,
diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc
index 4a6fb763da6..002700a592c 100644
--- a/storage/innobase/row/row0merge.cc
+++ b/storage/innobase/row/row0merge.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2005, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2005, 2018, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -3116,15 +3116,27 @@ row_merge_file_create_low(
const char* path)
{
int fd;
+ char filename[] = "Innodb Merge Temp File\0";
+ char* filepath = NULL;
+ int path_len;
+ if (path == NULL) {
+ path = innobase_mysql_tmpdir();
+ }
#ifdef UNIV_PFS_IO
/* This temp file open does not go through normal
file APIs, add instrumentation to register with
performance schema */
+ path_len = strlen(path) + sizeof "/" + strlen(filename)+1;
+ filepath = static_cast<char*>(mem_alloc(path_len));
+ memcpy(filepath,path,strlen(path));
+ ut_snprintf(filepath + strlen(path),path_len - strlen(path),
+ "%c%s",'/',filename);
struct PSI_file_locker* locker = NULL;
+
PSI_file_locker_state state;
locker = PSI_FILE_CALL(get_thread_file_name_locker)(
&state, innodb_file_temp_key, PSI_FILE_OPEN,
- "Innodb Merge Temp File", &locker);
+ filepath, &locker);
if (locker != NULL) {
PSI_FILE_CALL(start_file_open_wait)(locker,
__FILE__,
@@ -3137,6 +3149,7 @@ row_merge_file_create_low(
PSI_FILE_CALL(end_file_open_wait_and_bind_to_descriptor)(
locker, fd);
}
+ mem_free(filepath);
#endif
if (fd < 0) {
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index cfd640ed4d5..3782d815e9e 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -5066,6 +5066,9 @@ row_rename_table_for_mysql(
" = TO_BINARY(:old_table_name);\n"
"END;\n"
, FALSE, trx);
+ if (err != DB_SUCCESS) {
+ goto end;
+ }
} else if (n_constraints_to_drop > 0) {
/* Drop some constraints of tmp tables. */
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 706b5436981..8c61e959a4d 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1997, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -4368,7 +4368,7 @@ rec_loop:
passed to InnoDB when there is no ICP and number of loops
in row_search_for_mysql for rows found but not
reporting due to search views etc. */
- if (prev_rec != NULL
+ if (prev_rec != NULL && !prebuilt->innodb_api
&& prebuilt->mysql_handler->end_range != NULL
&& prebuilt->idx_cond == NULL
&& end_loop >= 100) {