From da34c7de5dacac85c4dc1f714bcd7edf3b7fe5f9 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sat, 27 Oct 2018 21:05:16 +0200 Subject: 5.6.42 --- storage/innobase/dict/dict0dict.cc | 7 +++- storage/innobase/fts/fts0fts.cc | 67 +++++++++++++------------------ storage/innobase/handler/ha_innodb.cc | 45 ++++++++++++++++++++- storage/innobase/handler/handler0alter.cc | 35 ++++++++++++---- storage/innobase/include/os0file.h | 6 ++- storage/innobase/row/row0import.cc | 19 ++++++--- storage/innobase/row/row0merge.cc | 17 +++++++- storage/innobase/row/row0mysql.cc | 3 ++ storage/innobase/row/row0sel.cc | 4 +- 9 files changed, 143 insertions(+), 60 deletions(-) (limited to 'storage/innobase') 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(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) { -- cgit v1.2.1