diff options
author | unknown <aivanov@mysql.com> | 2005-12-06 22:02:40 +0300 |
---|---|---|
committer | unknown <aivanov@mysql.com> | 2005-12-06 22:02:40 +0300 |
commit | b83c29766c916c67194c56d12f0b4542402e1e85 (patch) | |
tree | 12215ce7c080a1a2ab6d1de62d6cb0dd7957a223 /innobase/row | |
parent | c9bf8e28a86c6eec53bb20d657e667c5fe1dbe88 (diff) | |
download | mariadb-git-b83c29766c916c67194c56d12f0b4542402e1e85.tar.gz |
Fix BUG#14747: "Race condition can cause btr_search_drop_page_hash_index()
to crash".
Changes from snapshot innodb-5.0-ss52.
Note that buf_block_t::index should be protected by btr_search_latch
or an s-latch or x-latch on the index page.
btr_search_drop_page_hash_index(): Read block->index while holding
btr_search_latch and use the cached value in the loop. Remove some
redundant assertions.
Also fix 13778. When FOREIGN_KEY_CHECKS=0 we still need to check that
datatypes between foreign key references are compatible.
Also added test cases to 9802.
innobase/btr/btr0sea.c:
Changes from innodb-5.0-ss52
innobase/dict/dict0dict.c:
Changes from innodb-5.0-ss52
innobase/dict/dict0load.c:
Changes from innodb-5.0-ss52
innobase/include/buf0buf.h:
Changes from innodb-5.0-ss52
innobase/include/dict0dict.h:
Changes from innodb-5.0-ss52
innobase/include/dict0load.h:
Changes from innodb-5.0-ss52
innobase/include/rem0cmp.h:
Changes from innodb-5.0-ss52
innobase/rem/rem0cmp.c:
Changes from innodb-5.0-ss52
innobase/row/row0mysql.c:
Changes from innodb-5.0-ss52
mysql-test/r/innodb.result:
Changes from innodb-5.0-ss52
mysql-test/t/innodb.test:
Changes from innodb-5.0-ss52
sql/ha_innodb.cc:
Changes from innodb-5.0-ss52
sql/ha_innodb.h:
Changes from innodb-5.0-ss52
Diffstat (limited to 'innobase/row')
-rw-r--r-- | innobase/row/row0mysql.c | 64 |
1 files changed, 26 insertions, 38 deletions
diff --git a/innobase/row/row0mysql.c b/innobase/row/row0mysql.c index 82f7daf2ed8..723e305b2ab 100644 --- a/innobase/row/row0mysql.c +++ b/innobase/row/row0mysql.c @@ -2132,7 +2132,7 @@ row_table_add_foreign_constraints( if (err == DB_SUCCESS) { /* Check that also referencing constraints are ok */ - err = dict_load_foreigns(name, trx->check_foreigns); + err = dict_load_foreigns(name, TRUE); } if (err != DB_SUCCESS) { @@ -3590,7 +3590,8 @@ row_rename_table_for_mysql( mem_heap_t* heap = NULL; const char** constraints_to_drop = NULL; ulint n_constraints_to_drop = 0; - ibool recovering_temp_table = FALSE; + ibool recovering_temp_table = FALSE; + ibool old_is_tmp, new_is_tmp; ulint len; ulint i; ibool success; @@ -3630,6 +3631,9 @@ row_rename_table_for_mysql( trx->op_info = "renaming table"; trx_start_if_not_started(trx); + old_is_tmp = row_is_mysql_tmp_table_name(old_name); + new_is_tmp = row_is_mysql_tmp_table_name(new_name); + if (row_mysql_is_recovered_tmp_table(new_name)) { recovering_temp_table = TRUE; @@ -3676,7 +3680,7 @@ row_rename_table_for_mysql( len = (sizeof str1) + (sizeof str2) + (sizeof str3) + (sizeof str5) - 4 + ut_strlenq(new_name, '\'') + ut_strlenq(old_name, '\''); - if (row_is_mysql_tmp_table_name(new_name)) { + if (new_is_tmp) { db_name_len = dict_get_db_name_len(old_name) + 1; /* MySQL is doing an ALTER TABLE command and it renames the @@ -3829,7 +3833,7 @@ row_rename_table_for_mysql( the table is stored in a single-table tablespace */ success = dict_table_rename_in_cache(table, new_name, - !row_is_mysql_tmp_table_name(new_name)); + !new_is_tmp); if (!success) { trx->error_state = DB_SUCCESS; trx_general_rollback_for_mysql(trx, FALSE, NULL); @@ -3846,19 +3850,16 @@ row_rename_table_for_mysql( goto funct_exit; } - err = dict_load_foreigns(new_name, trx->check_foreigns); - - if (row_is_mysql_tmp_table_name(old_name)) { + /* We only want to switch off some of the type checking in + an ALTER, not in a RENAME. */ + + err = dict_load_foreigns(new_name, + old_is_tmp ? trx->check_foreigns : TRUE); - /* MySQL is doing an ALTER TABLE command and it - renames the created temporary table to the name - of the original table. In the ALTER TABLE we maybe - created some FOREIGN KEY constraints for the temporary - table. But we want to load also the foreign key - constraint definitions for the original table name. */ + if (err != DB_SUCCESS) { + ut_print_timestamp(stderr); - if (err != DB_SUCCESS) { - ut_print_timestamp(stderr); + if (old_is_tmp) { fputs(" InnoDB: Error: in ALTER TABLE ", stderr); ut_print_name(stderr, trx, new_name); @@ -3866,36 +3867,23 @@ row_rename_table_for_mysql( "InnoDB: has or is referenced in foreign key constraints\n" "InnoDB: which are not compatible with the new table definition.\n", stderr); - - ut_a(dict_table_rename_in_cache(table, - old_name, FALSE)); - trx->error_state = DB_SUCCESS; - trx_general_rollback_for_mysql(trx, FALSE, - NULL); - trx->error_state = DB_SUCCESS; - } - } else { - if (err != DB_SUCCESS) { - - ut_print_timestamp(stderr); - + } else { fputs( " InnoDB: Error: in RENAME TABLE table ", stderr); ut_print_name(stderr, trx, new_name); fputs("\n" - "InnoDB: is referenced in foreign key constraints\n" - "InnoDB: which are not compatible with the new table definition.\n", + "InnoDB: is referenced in foreign key constraints\n" + "InnoDB: which are not compatible with the new table definition.\n", stderr); - - ut_a(dict_table_rename_in_cache(table, - old_name, FALSE)); - - trx->error_state = DB_SUCCESS; - trx_general_rollback_for_mysql(trx, FALSE, - NULL); - trx->error_state = DB_SUCCESS; } + + ut_a(dict_table_rename_in_cache(table, + old_name, FALSE)); + trx->error_state = DB_SUCCESS; + trx_general_rollback_for_mysql(trx, FALSE, + NULL); + trx->error_state = DB_SUCCESS; } } funct_exit: |