diff options
Diffstat (limited to 'innobase')
-rw-r--r-- | innobase/row/row0mysql.c | 24 | ||||
-rw-r--r-- | innobase/row/row0sel.c | 33 |
2 files changed, 36 insertions, 21 deletions
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 35305b037c6..e94998f165f 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -2203,6 +2203,9 @@ row_rename_table_for_mysql( mem_heap_t* heap = NULL; char** constraints_to_drop = NULL; ulint n_constraints_to_drop = 0; + ibool recovering_temp_table = FALSE; + ulint namelen; + ulint keywordlen; ulint len; ulint i; char buf[10000]; @@ -2239,10 +2242,23 @@ row_rename_table_for_mysql( trx->op_info = (char *) "renaming table"; trx_start_if_not_started(trx); + namelen = ut_strlen(new_name); + + keywordlen = ut_strlen("_recover_innodb_tmp_table"); + + if (namelen >= keywordlen + && 0 == ut_memcmp(new_name + namelen - keywordlen, + (char*)"_recover_innodb_tmp_table", keywordlen)) { + + recovering_temp_table = TRUE; + } + /* Serialize data dictionary operations with dictionary mutex: no deadlocks can occur then in these operations */ - row_mysql_lock_data_dictionary(trx); + if (!recovering_temp_table) { + row_mysql_lock_data_dictionary(trx); + } table = dict_table_get_low(old_name); @@ -2409,8 +2425,10 @@ row_rename_table_for_mysql( } } } -funct_exit: - row_mysql_unlock_data_dictionary(trx); +funct_exit: + if (!recovering_temp_table) { + row_mysql_unlock_data_dictionary(trx); + } if (graph) { que_graph_free(graph); diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index d0f6965f94e..4ff632805b3 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2827,23 +2827,6 @@ row_search_for_mysql( mode = pcur->search_mode; } - if ((direction == ROW_SEL_NEXT || direction == ROW_SEL_PREV) - && pcur->old_stored != BTR_PCUR_OLD_STORED) { - - /* MySQL sometimes seems to do fetch next or fetch prev even - if the search condition is unique; this can, for example, - happen with the HANDLER commands; we do not always store the - pcur position in this case, so we cannot restore cursor - position, and must return immediately */ - - /* printf("%s record not found 1\n", index->name); */ - - trx->op_info = (char *) ""; - return(DB_RECORD_NOT_FOUND); - } - - mtr_start(&mtr); - /* In a search where at most one record in the index may match, we can use a LOCK_REC_NOT_GAP type record lock when locking a non-delete- marked matching record. @@ -2858,8 +2841,21 @@ row_search_for_mysql( && dtuple_get_n_fields(search_tuple) == dict_index_get_n_unique(index)) { unique_search = TRUE; + + /* Even if the condition is unique, MySQL seems to try to + retrieve also a second row if a primary key contains more than + 1 column. Return immediately if this is not a HANDLER + command. */ + + if (direction != 0 && !prebuilt->used_in_HANDLER) { + + trx->op_info = (char*)""; + return(DB_RECORD_NOT_FOUND); + } } + mtr_start(&mtr); + /*-------------------------------------------------------------*/ /* PHASE 2: Try fast adaptive hash index search if possible */ @@ -2869,8 +2865,9 @@ row_search_for_mysql( cannot use the adaptive hash index in a search in the case the row may be long and there may be externally stored fields */ - if (unique_search + if (unique_search && index->type & DICT_CLUSTERED + && direction == 0 && !prebuilt->templ_contains_blob && !prebuilt->used_in_HANDLER && (prebuilt->mysql_row_len < UNIV_PAGE_SIZE / 8)) { |