diff options
author | Nirbhay Choubey <nirbhay@mariadb.com> | 2016-08-10 10:34:54 -0400 |
---|---|---|
committer | Nirbhay Choubey <nirbhay@mariadb.com> | 2016-08-10 10:34:54 -0400 |
commit | 38a0def80588dd8a093af3e225101365c74e0faa (patch) | |
tree | 57ac2c3d59b2e7fefc37fdc9763715ee74d90ca2 /storage | |
parent | 44e3046d3b09a21e21295979d6ddad9f332ebadd (diff) | |
parent | 5ad02062d928cccbd29c0a2db6f0f7ceb33195d1 (diff) | |
download | mariadb-git-38a0def80588dd8a093af3e225101365c74e0faa.tar.gz |
Merge tag 'mariadb-5.5.51' into 5.5-galera
Diffstat (limited to 'storage')
24 files changed, 158 insertions, 75 deletions
diff --git a/storage/innobase/dict/dict0crea.c b/storage/innobase/dict/dict0crea.c index 8102f570175..f8bcc6f2d5f 100644 --- a/storage/innobase/dict/dict0crea.c +++ b/storage/innobase/dict/dict0crea.c @@ -1242,14 +1242,14 @@ dict_create_or_check_foreign_constraint_tables(void) fprintf(stderr, "InnoDB: dropping incompletely created" " SYS_FOREIGN table\n"); - row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE, TRUE); } if (table2) { fprintf(stderr, "InnoDB: dropping incompletely created" " SYS_FOREIGN_COLS table\n"); - row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE, TRUE); } fprintf(stderr, @@ -1298,8 +1298,8 @@ dict_create_or_check_foreign_constraint_tables(void) "InnoDB: dropping incompletely created" " SYS_FOREIGN tables\n"); - row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE); - row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE, TRUE); error = DB_MUST_GET_MORE_FILE_SPACE; } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 28694c526b9..5261a50fdd6 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -8705,7 +8705,8 @@ ha_innobase::delete_table( error = row_drop_table_for_mysql(norm_name, trx, thd_sql_command(thd) - == SQLCOM_DROP_DB); + == SQLCOM_DROP_DB, + FALSE); /* Flush the log to reduce probability that the .frm files and the InnoDB data dictionary get out-of-sync if the user runs diff --git a/storage/innobase/include/os0sync.h b/storage/innobase/include/os0sync.h index 213974b01de..af58a232746 100644 --- a/storage/innobase/include/os0sync.h +++ b/storage/innobase/include/os0sync.h @@ -348,20 +348,13 @@ os_atomic_test_and_set(volatile lock_word_t* ptr) } /** Do an atomic release. - -In theory __sync_lock_release should be used to release the lock. -Unfortunately, it does not work properly alone. The workaround is -that more conservative __sync_lock_test_and_set is used instead. - -Performance regression was observed at some conditions for Intel -architecture. Disable release barrier on Intel architecture for now. @param[in,out] ptr Memory location to write to @return the previous value */ static inline -lock_word_t +void os_atomic_clear(volatile lock_word_t* ptr) { - return(__sync_lock_test_and_set(ptr, 0)); + __sync_lock_release(ptr); } # elif defined(HAVE_IB_GCC_ATOMIC_TEST_AND_SET) diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index 7abb0b67fff..0f66644d906 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -454,7 +454,10 @@ row_drop_table_for_mysql( /*=====================*/ const char* name, /*!< in: table name */ trx_t* trx, /*!< in: transaction handle */ - ibool drop_db);/*!< in: TRUE=dropping whole database */ + ibool drop_db,/*!< in: TRUE=dropping whole database */ + ibool create_failed);/*!<in: TRUE=create table failed + because e.g. foreign key column + type mismatch. */ /*********************************************************************//** Drop all temporary tables during crash recovery. */ UNIV_INTERN diff --git a/storage/innobase/include/sync0sync.ic b/storage/innobase/include/sync0sync.ic index 1120da8a3be..d0f266309fc 100644 --- a/storage/innobase/include/sync0sync.ic +++ b/storage/innobase/include/sync0sync.ic @@ -178,6 +178,11 @@ mutex_exit_func( to wake up possible hanging threads if they are missed in mutex_signal_object. */ + /* We add a memory barrier to prevent reading of the + number of waiters before releasing the lock. */ + + os_mb; + if (mutex_get_waiters(mutex) != 0) { mutex_signal_object(mutex); diff --git a/storage/innobase/page/page0cur.c b/storage/innobase/page/page0cur.c index a722f5b188d..4b6a1551ada 100644 --- a/storage/innobase/page/page0cur.c +++ b/storage/innobase/page/page0cur.c @@ -1048,6 +1048,26 @@ use_heap: insert_rec = rec_copy(insert_buf, rec, offsets); rec_offs_make_valid(insert_rec, index, offsets); + /* This is because assertion below is debug assertion */ +#ifdef UNIV_DEBUG + if (UNIV_UNLIKELY(current_rec == insert_rec)) { + ulint extra_len, data_len; + extra_len = rec_offs_extra_size(offsets); + data_len = rec_offs_data_size(offsets); + + fprintf(stderr, "InnoDB: Error: current_rec == insert_rec " + " extra_len %lu data_len %lu insert_buf %p rec %p\n", + extra_len, data_len, insert_buf, rec); + fprintf(stderr, "InnoDB; Physical record: \n"); + rec_print(stderr, rec, index); + fprintf(stderr, "InnoDB: Inserted record: \n"); + rec_print(stderr, insert_rec, index); + fprintf(stderr, "InnoDB: Current record: \n"); + rec_print(stderr, current_rec, index); + ut_a(current_rec != insert_rec); + } +#endif /* UNIV_DEBUG */ + /* 4. Insert the record in the linked list of records */ ut_ad(current_rec != insert_rec); diff --git a/storage/innobase/row/row0merge.c b/storage/innobase/row/row0merge.c index f7d546c84c8..7d87d1f9c8f 100644 --- a/storage/innobase/row/row0merge.c +++ b/storage/innobase/row/row0merge.c @@ -2685,7 +2685,7 @@ row_merge_drop_table( /* There must be no open transactions on the table. */ ut_a(table->n_mysql_handles_opened == 0); - return(row_drop_table_for_mysql(table->name, trx, FALSE)); + return(row_drop_table_for_mysql(table->name, trx, FALSE, FALSE)); } /*********************************************************************//** diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index 1a11e398959..6206bef6b56 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -1987,7 +1987,7 @@ err_exit: if (dict_table_get_low(table->name, DICT_ERR_IGNORE_NONE)) { - row_drop_table_for_mysql(table->name, trx, FALSE); + row_drop_table_for_mysql(table->name, trx, FALSE, TRUE); trx_commit_for_mysql(trx); } else { dict_mem_table_free(table); @@ -2117,7 +2117,7 @@ error_handling: trx_general_rollback_for_mysql(trx, NULL); - row_drop_table_for_mysql(table_name, trx, FALSE); + row_drop_table_for_mysql(table_name, trx, FALSE, TRUE); trx_commit_for_mysql(trx); @@ -2187,7 +2187,7 @@ row_table_add_foreign_constraints( trx_general_rollback_for_mysql(trx, NULL); - row_drop_table_for_mysql(name, trx, FALSE); + row_drop_table_for_mysql(name, trx, FALSE, TRUE); trx_commit_for_mysql(trx); @@ -2228,7 +2228,7 @@ row_drop_table_for_mysql_in_background( /* Try to drop the table in InnoDB */ - error = row_drop_table_for_mysql(name, trx, FALSE); + error = row_drop_table_for_mysql(name, trx, FALSE, FALSE); /* Flush the log to reduce probability that the .frm files and the InnoDB data dictionary get out-of-sync if the user runs @@ -3078,7 +3078,10 @@ row_drop_table_for_mysql( /*=====================*/ const char* name, /*!< in: table name */ trx_t* trx, /*!< in: transaction handle */ - ibool drop_db)/*!< in: TRUE=dropping whole database */ + ibool drop_db,/*!< in: TRUE=dropping whole database */ + ibool create_failed) /*!<in: TRUE=create table failed + because e.g. foreign key column + type mismatch. */ { dict_foreign_t* foreign; dict_table_t* table; @@ -3193,7 +3196,11 @@ check_next_foreign: foreign = UT_LIST_GET_NEXT(referenced_list, foreign); } - if (foreign && trx->check_foreigns + /* We should allow dropping a referenced table if creating + that referenced table has failed for some reason. For example + if referenced table is created but it column types that are + referenced do not match. */ + if (foreign && trx->check_foreigns && !create_failed && !(drop_db && dict_tables_have_same_db( name, foreign->foreign_table_name_lookup))) { FILE* ef = dict_foreign_err_file; @@ -3578,7 +3585,7 @@ row_mysql_drop_temp_tables(void) table = dict_load_table(table_name, TRUE, DICT_ERR_IGNORE_NONE); if (table) { - row_drop_table_for_mysql(table_name, trx, FALSE); + row_drop_table_for_mysql(table_name, trx, FALSE, FALSE); trx_commit_for_mysql(trx); } @@ -3708,7 +3715,7 @@ loop: goto loop; } - err = row_drop_table_for_mysql(table_name, trx, TRUE); + err = row_drop_table_for_mysql(table_name, trx, TRUE, FALSE); trx_commit_for_mysql(trx); if (err != DB_SUCCESS) { diff --git a/storage/innobase/trx/trx0roll.c b/storage/innobase/trx/trx0roll.c index d0bbf7fd7c2..90207c0bb2c 100644 --- a/storage/innobase/trx/trx0roll.c +++ b/storage/innobase/trx/trx0roll.c @@ -519,7 +519,7 @@ trx_rollback_active( ut_print_name(stderr, trx, TRUE, table->name); fputs(" in recovery\n", stderr); - err = row_drop_table_for_mysql(table->name, trx, TRUE); + err = row_drop_table_for_mysql(table->name, trx, TRUE, FALSE); trx_commit_for_mysql(trx); ut_a(err == (int) DB_SUCCESS); diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index a2e62d8ae1e..784da17d790 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1433,6 +1433,7 @@ int ha_myisam::enable_indexes(uint mode) else if (mode == HA_KEY_SWITCH_NONUNIQ_SAVE) { THD *thd= table->in_use; + int was_error= thd->is_error(); HA_CHECK ¶m= *(HA_CHECK*) thd->alloc(sizeof(param)); const char *save_proc_info=thd->proc_info; @@ -1475,7 +1476,7 @@ int ha_myisam::enable_indexes(uint mode) might have been set by the first repair. They can still be seen with SHOW WARNINGS then. */ - if (! error) + if (! error && ! was_error) thd->clear_error(); } info(HA_STATUS_CONST); diff --git a/storage/tokudb/ft-index/ft/txn/txn.cc b/storage/tokudb/ft-index/ft/txn/txn.cc index 9aa93375126..34c7e0f2a67 100644 --- a/storage/tokudb/ft-index/ft/txn/txn.cc +++ b/storage/tokudb/ft-index/ft/txn/txn.cc @@ -336,17 +336,26 @@ static txn_child_manager tcm; .xa_xid = {0, 0, 0, {}}, .progress_poll_fun = NULL, .progress_poll_fun_extra = NULL, - .txn_lock = TOKU_MUTEX_INITIALIZER, + .txn_lock = {}, // Needs to be set to 0 after initialization. + // See: + // https://llvm.org/bugs/show_bug.cgi?id=21689 + // and MDEV-10229 .open_fts = open_fts, .roll_info = roll_info, - .state_lock = TOKU_MUTEX_INITIALIZER, - .state_cond = TOKU_COND_INITIALIZER, + .state_lock = {}, // Needs to be set to 0. + .state_cond = {}, // Needs to be set to 0. .state = TOKUTXN_LIVE, .num_pin = 0, .client_id = 0, .start_time = time(NULL), }; + // We initialize the locks afterwards, but to prevent undefined behaviour + // we zero-out the structures containing them. + ZERO_STRUCT(new_txn.txn_lock); + ZERO_STRUCT(new_txn.state_lock); + ZERO_STRUCT(new_txn.state_cond); + TOKUTXN result = NULL; XMEMDUP(result, &new_txn); invalidate_xa_xid(&result->xa_xid); diff --git a/storage/xtradb/dict/dict0crea.c b/storage/xtradb/dict/dict0crea.c index a77acf8b577..b44fdc1d2e4 100644 --- a/storage/xtradb/dict/dict0crea.c +++ b/storage/xtradb/dict/dict0crea.c @@ -1444,14 +1444,14 @@ dict_create_or_check_foreign_constraint_tables(void) fprintf(stderr, "InnoDB: dropping incompletely created" " SYS_FOREIGN table\n"); - row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE, TRUE); } if (table2) { fprintf(stderr, "InnoDB: dropping incompletely created" " SYS_FOREIGN_COLS table\n"); - row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE, TRUE); } fprintf(stderr, @@ -1500,8 +1500,8 @@ dict_create_or_check_foreign_constraint_tables(void) "InnoDB: dropping incompletely created" " SYS_FOREIGN tables\n"); - row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE); - row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE, TRUE); + row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE, TRUE); error = DB_MUST_GET_MORE_FILE_SPACE; } diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 1e2128f4f88..9cce7ad35ae 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -9834,7 +9834,8 @@ ha_innobase::delete_table( error = row_drop_table_for_mysql(norm_name, trx, thd_sql_command(thd) - == SQLCOM_DROP_DB); + == SQLCOM_DROP_DB, + FALSE); /* Flush the log to reduce probability that the .frm files and the InnoDB data dictionary get out-of-sync if the user runs @@ -9919,6 +9920,7 @@ innobase_drop_database( trx_free_for_mysql(trx); return; /* ignore */ } + row_drop_database_for_mysql(namebuf, trx); my_free(namebuf); diff --git a/storage/xtradb/include/log0online.h b/storage/xtradb/include/log0online.h index a20eef57d7a..02d75001505 100644 --- a/storage/xtradb/include/log0online.h +++ b/storage/xtradb/include/log0online.h @@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA +this program; if not, write to the Free Software Foundation, Inc., 51 Franklin +Street, Fifth Floor, Boston, MA 02110-1301, USA *****************************************************************************/ diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h index b52c078fa54..08da9dff4e3 100644 --- a/storage/xtradb/include/os0sync.h +++ b/storage/xtradb/include/os0sync.h @@ -381,20 +381,13 @@ os_atomic_test_and_set(volatile lock_word_t* ptr) } /** Do an atomic release. - -In theory __sync_lock_release should be used to release the lock. -Unfortunately, it does not work properly alone. The workaround is -that more conservative __sync_lock_test_and_set is used instead. - -Performance regression was observed at some conditions for Intel -architecture. Disable release barrier on Intel architecture for now. @param[in,out] ptr Memory location to write to @return the previous value */ static inline -lock_word_t +void os_atomic_clear(volatile lock_word_t* ptr) { - return(__sync_lock_test_and_set(ptr, 0)); + __sync_lock_release(ptr); } # elif defined(HAVE_IB_GCC_ATOMIC_TEST_AND_SET) diff --git a/storage/xtradb/include/row0mysql.h b/storage/xtradb/include/row0mysql.h index 35378bf3302..e228289bdae 100644 --- a/storage/xtradb/include/row0mysql.h +++ b/storage/xtradb/include/row0mysql.h @@ -470,7 +470,10 @@ row_drop_table_for_mysql( /*=====================*/ const char* name, /*!< in: table name */ trx_t* trx, /*!< in: transaction handle */ - ibool drop_db);/*!< in: TRUE=dropping whole database */ + ibool drop_db,/*!< in: TRUE=dropping whole database */ + ibool create_failed);/*!<in: TRUE=create table failed + because e.g. foreign key column + type mismatch. */ /*********************************************************************//** Drop all temporary tables during crash recovery. */ UNIV_INTERN diff --git a/storage/xtradb/include/sync0sync.ic b/storage/xtradb/include/sync0sync.ic index 48039c854d9..c733becf6df 100644 --- a/storage/xtradb/include/sync0sync.ic +++ b/storage/xtradb/include/sync0sync.ic @@ -178,6 +178,11 @@ mutex_exit_func( to wake up possible hanging threads if they are missed in mutex_signal_object. */ + /* We add a memory barrier to prevent reading of the + number of waiters before releasing the lock. */ + + os_mb; + if (mutex_get_waiters(mutex) != 0) { mutex_signal_object(mutex); diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i index 2aaabf64a4e..9d4b3e5a136 100644 --- a/storage/xtradb/include/univ.i +++ b/storage/xtradb/include/univ.i @@ -64,7 +64,7 @@ component, i.e. we show M.N.P as M.N */ (INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR) #ifndef PERCONA_INNODB_VERSION -#define PERCONA_INNODB_VERSION 37.9 +#define PERCONA_INNODB_VERSION 38.0 #endif #define INNODB_VERSION_STR "5.5.49-MariaDB-" IB_TO_STR(PERCONA_INNODB_VERSION) diff --git a/storage/xtradb/log/log0online.c b/storage/xtradb/log/log0online.c index a8444199ea9..d0127488f67 100644 --- a/storage/xtradb/log/log0online.c +++ b/storage/xtradb/log/log0online.c @@ -11,8 +11,8 @@ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., 59 Temple -Place, Suite 330, Boston, MA 02111-1307 USA +this program; if not, write to the Free Software Foundation, Inc., 51 Franklin +Street, Fifth Floor, Boston, MA 02110-1301, USA *****************************************************************************/ diff --git a/storage/xtradb/log/log0recv.c b/storage/xtradb/log/log0recv.c index 479f50d1931..1e670d553c5 100644 --- a/storage/xtradb/log/log0recv.c +++ b/storage/xtradb/log/log0recv.c @@ -666,6 +666,7 @@ recv_check_cp_is_consistent( } #ifndef UNIV_HOTBACKUP + /********************************************************//** Looks for the maximum consistent checkpoint from the log groups. @return error code or DB_SUCCESS */ @@ -692,8 +693,37 @@ recv_find_max_checkpoint( buf = log_sys->checkpoint_buf; while (group) { + + ulint log_hdr_log_block_size; + group->state = LOG_GROUP_CORRUPTED; + /* Assert that we can reuse log_sys->checkpoint_buf to read the + part of the header that contains the log block size. */ + ut_ad(LOG_FILE_OS_FILE_LOG_BLOCK_SIZE + 4 + < OS_FILE_LOG_BLOCK_SIZE); + + fil_io(OS_FILE_READ | OS_FILE_LOG, TRUE, group->space_id, 0, + 0, 0, OS_FILE_LOG_BLOCK_SIZE, + log_sys->checkpoint_buf, NULL); + log_hdr_log_block_size + = mach_read_from_4(log_sys->checkpoint_buf + + LOG_FILE_OS_FILE_LOG_BLOCK_SIZE); + if (log_hdr_log_block_size == 0) { + /* 0 means default value */ + log_hdr_log_block_size = 512; + } + if (log_hdr_log_block_size != srv_log_block_size) { + fprintf(stderr, + "InnoDB: Error: The block size of ib_logfile " + "%lu is not equal to innodb_log_block_size " + "%lu.\n" + "InnoDB: Error: Suggestion - Recreate log " + "files.\n", + log_hdr_log_block_size, srv_log_block_size); + return(DB_ERROR); + } + for (field = LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2; field += LOG_CHECKPOINT_2 - LOG_CHECKPOINT_1) { @@ -2989,7 +3019,6 @@ recv_recovery_from_checkpoint_start_func( log_group_t* max_cp_group; log_group_t* up_to_date_group; ulint max_cp_field; - ulint log_hdr_log_block_size; ib_uint64_t checkpoint_lsn; ib_uint64_t checkpoint_no; ib_uint64_t old_scanned_lsn; @@ -3092,21 +3121,6 @@ recv_recovery_from_checkpoint_start_func( log_hdr_buf, max_cp_group); } - log_hdr_log_block_size - = mach_read_from_4(log_hdr_buf + LOG_FILE_OS_FILE_LOG_BLOCK_SIZE); - if (log_hdr_log_block_size == 0) { - /* 0 means default value */ - log_hdr_log_block_size = 512; - } - if (log_hdr_log_block_size != srv_log_block_size) { - fprintf(stderr, - "InnoDB: Error: The block size of ib_logfile (%lu) " - "is not equal to innodb_log_block_size.\n" - "InnoDB: Error: Suggestion - Recreate log files.\n", - log_hdr_log_block_size); - return(DB_ERROR); - } - #ifdef UNIV_LOG_ARCHIVE group = UT_LIST_GET_FIRST(log_sys->log_groups); diff --git a/storage/xtradb/page/page0cur.c b/storage/xtradb/page/page0cur.c index a722f5b188d..4b6a1551ada 100644 --- a/storage/xtradb/page/page0cur.c +++ b/storage/xtradb/page/page0cur.c @@ -1048,6 +1048,26 @@ use_heap: insert_rec = rec_copy(insert_buf, rec, offsets); rec_offs_make_valid(insert_rec, index, offsets); + /* This is because assertion below is debug assertion */ +#ifdef UNIV_DEBUG + if (UNIV_UNLIKELY(current_rec == insert_rec)) { + ulint extra_len, data_len; + extra_len = rec_offs_extra_size(offsets); + data_len = rec_offs_data_size(offsets); + + fprintf(stderr, "InnoDB: Error: current_rec == insert_rec " + " extra_len %lu data_len %lu insert_buf %p rec %p\n", + extra_len, data_len, insert_buf, rec); + fprintf(stderr, "InnoDB; Physical record: \n"); + rec_print(stderr, rec, index); + fprintf(stderr, "InnoDB: Inserted record: \n"); + rec_print(stderr, insert_rec, index); + fprintf(stderr, "InnoDB: Current record: \n"); + rec_print(stderr, current_rec, index); + ut_a(current_rec != insert_rec); + } +#endif /* UNIV_DEBUG */ + /* 4. Insert the record in the linked list of records */ ut_ad(current_rec != insert_rec); diff --git a/storage/xtradb/row/row0merge.c b/storage/xtradb/row/row0merge.c index 752e941af7f..3a03c7c8578 100644 --- a/storage/xtradb/row/row0merge.c +++ b/storage/xtradb/row/row0merge.c @@ -2747,7 +2747,7 @@ row_merge_drop_table( /* There must be no open transactions on the table. */ ut_a(table->n_mysql_handles_opened == 0); - return(row_drop_table_for_mysql(table->name, trx, FALSE)); + return(row_drop_table_for_mysql(table->name, trx, FALSE, FALSE)); } /*********************************************************************//** diff --git a/storage/xtradb/row/row0mysql.c b/storage/xtradb/row/row0mysql.c index e6ccf44b884..0182752132a 100644 --- a/storage/xtradb/row/row0mysql.c +++ b/storage/xtradb/row/row0mysql.c @@ -2013,7 +2013,7 @@ err_exit: if (dict_table_get_low(table->name, DICT_ERR_IGNORE_NONE)) { - row_drop_table_for_mysql(table->name, trx, FALSE); + row_drop_table_for_mysql(table->name, trx, FALSE, TRUE); trx_commit_for_mysql(trx); } else { dict_mem_table_free(table); @@ -2143,7 +2143,7 @@ error_handling: trx_general_rollback_for_mysql(trx, NULL); - row_drop_table_for_mysql(table_name, trx, FALSE); + row_drop_table_for_mysql(table_name, trx, FALSE, TRUE); trx_commit_for_mysql(trx); @@ -2278,7 +2278,7 @@ row_table_add_foreign_constraints( trx_general_rollback_for_mysql(trx, NULL); - row_drop_table_for_mysql(name, trx, FALSE); + row_drop_table_for_mysql(name, trx, FALSE, TRUE); trx_commit_for_mysql(trx); @@ -2319,7 +2319,7 @@ row_drop_table_for_mysql_in_background( /* Try to drop the table in InnoDB */ - error = row_drop_table_for_mysql(name, trx, FALSE); + error = row_drop_table_for_mysql(name, trx, FALSE, FALSE); /* Flush the log to reduce probability that the .frm files and the InnoDB data dictionary get out-of-sync if the user runs @@ -3216,7 +3216,10 @@ row_drop_table_for_mysql( /*=====================*/ const char* name, /*!< in: table name */ trx_t* trx, /*!< in: transaction handle */ - ibool drop_db)/*!< in: TRUE=dropping whole database */ + ibool drop_db,/*!< in: TRUE=dropping whole database */ + ibool create_failed) /*!<in: TRUE=create table failed + because e.g. foreign key column + type mismatch. */ { dict_foreign_t* foreign; dict_table_t* table; @@ -3331,7 +3334,11 @@ check_next_foreign: foreign = UT_LIST_GET_NEXT(referenced_list, foreign); } - if (foreign && trx->check_foreigns + /* We should allow dropping a referenced table if creating + that referenced table has failed for some reason. For example + if referenced table is created but it column types that are + referenced do not match. */ + if (foreign && trx->check_foreigns && !create_failed && !(drop_db && dict_tables_have_same_db( name, foreign->foreign_table_name_lookup))) { FILE* ef = dict_foreign_err_file; @@ -3718,7 +3725,7 @@ row_mysql_drop_temp_tables(void) table = dict_table_get_low(table_name, DICT_ERR_IGNORE_ALL); if (table) { - row_drop_table_for_mysql(table_name, trx, FALSE); + row_drop_table_for_mysql(table_name, trx, FALSE, FALSE); trx_commit_for_mysql(trx); } @@ -3848,7 +3855,7 @@ loop: goto loop; } - err = row_drop_table_for_mysql(table_name, trx, TRUE); + err = row_drop_table_for_mysql(table_name, trx, TRUE, FALSE); trx_commit_for_mysql(trx); if (err != DB_SUCCESS) { diff --git a/storage/xtradb/trx/trx0roll.c b/storage/xtradb/trx/trx0roll.c index 2dde8900cda..2eeed9378cc 100644 --- a/storage/xtradb/trx/trx0roll.c +++ b/storage/xtradb/trx/trx0roll.c @@ -519,7 +519,7 @@ trx_rollback_active( ut_print_name(stderr, trx, TRUE, table->name); fputs(" in recovery\n", stderr); - err = row_drop_table_for_mysql(table->name, trx, TRUE); + err = row_drop_table_for_mysql(table->name, trx, TRUE, FALSE); trx_commit_for_mysql(trx); ut_a(err == (int) DB_SUCCESS); |