From deb5fda307a8598206cf7ab97ea415ad7a710b40 Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Sep 2003 00:31:43 +0300 Subject: row0sel.c: Fix bug: if a primary key contains more than one column, then MySQL seems to do fetch next even for a unique search condition: this in turn caused unnecessary locking which did not agree what the InnoDB manual promised innobase/row/row0sel.c: Fix bug: if a primary key contains more than one column, then MySQL seems to do fetch next even for a unique search condition: this in turn caused unnecessary locking which did not agree what the InnoDB manual promised --- innobase/row/row0sel.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) (limited to 'innobase') diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index a263de74e3e..6172b36dc7e 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2810,21 +2810,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 @@ -2841,6 +2826,16 @@ 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) { + + return(DB_RECORD_NOT_FOUND); + } } /*-------------------------------------------------------------*/ @@ -2852,8 +2847,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)) { -- cgit v1.2.1 From 2af98e36422a2ce51b99a6e8b8d71ca977e803fd Mon Sep 17 00:00:00 2001 From: unknown Date: Fri, 12 Sep 2003 01:35:32 +0300 Subject: row0sel.c: Fix buglets in previous push innobase/row/row0sel.c: Fix buglets in previous push --- innobase/row/row0sel.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'innobase') diff --git a/innobase/row/row0sel.c b/innobase/row/row0sel.c index 6172b36dc7e..482f82b02ba 100644 --- a/innobase/row/row0sel.c +++ b/innobase/row/row0sel.c @@ -2810,8 +2810,6 @@ row_search_for_mysql( mode = pcur->search_mode; } - 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. @@ -2834,10 +2832,13 @@ row_search_for_mysql( 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 */ -- cgit v1.2.1 From 8e31a241905262fe438c0354e948ac25121f9ee3 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Oct 2003 10:46:22 +0300 Subject: row0mysql.c: Fix bug: if one used the rename trick of ibman section 15.1 to recover a temp table, InnoDB asserted because it tried to lock the data dictionary twice innobase/row/row0mysql.c: Fix bug: if one used the rename trick of ibman section 15.1 to recover a temp table, InnoDB asserted because it tried to lock the data dictionary twice --- innobase/row/row0mysql.c | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) (limited to 'innobase') diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 51231de4d77..03e938baf25 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1217,7 +1217,9 @@ row_mysql_lock_data_dictionary( /*===========================*/ trx_t* trx) /* in: transaction */ { - ut_a(trx->dict_operation_lock_mode == 0); + ut_ad(trx->dict_operation_lock_mode == 0); /* This is allowed to fail + in a rename #sql... to + rsql... */ /* Serialize data dictionary operations with dictionary mutex: no deadlocks or lock waits can occur then in these operations */ @@ -1236,7 +1238,9 @@ row_mysql_unlock_data_dictionary( /*=============================*/ trx_t* trx) /* in: transaction */ { - ut_a(trx->dict_operation_lock_mode == RW_X_LATCH); + ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); /* This is allowed + to fail in a rename #sql... to + rsql... */ /* Serialize data dictionary operations with dictionary mutex: no deadlocks can occur then in these operations */ @@ -2190,6 +2194,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]; @@ -2226,10 +2233,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); @@ -2396,8 +2416,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); -- cgit v1.2.1 From fed70100e762eb88a0f1c8bb57715e9530b76666 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 6 Oct 2003 10:50:12 +0300 Subject: row0mysql.c: Remove unintentional changes in previous push innobase/row/row0mysql.c: Remove unintentional changes in previous push --- innobase/row/row0mysql.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'innobase') diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 03e938baf25..468404268f4 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -1217,9 +1217,7 @@ row_mysql_lock_data_dictionary( /*===========================*/ trx_t* trx) /* in: transaction */ { - ut_ad(trx->dict_operation_lock_mode == 0); /* This is allowed to fail - in a rename #sql... to - rsql... */ + ut_a(trx->dict_operation_lock_mode == 0); /* Serialize data dictionary operations with dictionary mutex: no deadlocks or lock waits can occur then in these operations */ @@ -1238,9 +1236,7 @@ row_mysql_unlock_data_dictionary( /*=============================*/ trx_t* trx) /* in: transaction */ { - ut_ad(trx->dict_operation_lock_mode == RW_X_LATCH); /* This is allowed - to fail in a rename #sql... to - rsql... */ + ut_a(trx->dict_operation_lock_mode == RW_X_LATCH); /* Serialize data dictionary operations with dictionary mutex: no deadlocks can occur then in these operations */ -- cgit v1.2.1