diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-03-03 22:15:44 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-03-03 22:25:20 +0200 |
commit | 37e7bde12abddcda4d5505450e39a739561bd4d5 (patch) | |
tree | e7c236289d9a662947557131729c623f640489fe | |
parent | 1ef10744abfac64583c793080ef678ac2575a5b1 (diff) | |
download | mariadb-git-37e7bde12abddcda4d5505450e39a739561bd4d5.tar.gz |
MDEV-14425 preparation: Remove log_t::append_on_checkpoint
Simplify the logging of ALTER TABLE operations, by making use of the
TRX_UNDO_RENAME_TABLE undo log record that was introduced in
commit 0bc36758ba08ddeea6f7896a0fb815a13a48895a.
commit_try_rebuild(): Invoke row_rename_table_for_mysql() and
actually rename the files before committing the transaction.
fil_mtr_rename_log(), commit_cache_rebuild(),
log_append_on_checkpoint(), row_merge_rename_tables_dict(): Remove.
mtr_buf_copy_t, log_t::append_on_checkpoint: Remove.
row_rename_table_for_mysql(): If !use_fk, ignore missing foreign
keys. Remove a call to dict_table_rename_in_cache(), because
trx_rollback_to_savepoint() should invoke the function if needed.
-rw-r--r-- | mysql-test/suite/innodb/r/alter_rename_existing.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/alter_rename_files.result | 19 | ||||
-rw-r--r-- | mysql-test/suite/innodb/r/foreign_key.result | 4 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/alter_rename_existing.test | 2 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/alter_rename_files.test | 31 | ||||
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 79 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 2 | ||||
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 108 | ||||
-rw-r--r-- | storage/innobase/include/dyn0buf.h | 16 | ||||
-rw-r--r-- | storage/innobase/include/fil0fil.h | 14 | ||||
-rw-r--r-- | storage/innobase/include/log0log.h | 13 | ||||
-rw-r--r-- | storage/innobase/include/row0merge.h | 16 | ||||
-rw-r--r-- | storage/innobase/log/log0log.cc | 15 | ||||
-rw-r--r-- | storage/innobase/row/row0merge.cc | 115 | ||||
-rw-r--r-- | storage/innobase/row/row0mysql.cc | 13 |
15 files changed, 19 insertions, 430 deletions
diff --git a/mysql-test/suite/innodb/r/alter_rename_existing.result b/mysql-test/suite/innodb/r/alter_rename_existing.result index 8fc54adbd10..aff8a3a09a1 100644 --- a/mysql-test/suite/innodb/r/alter_rename_existing.result +++ b/mysql-test/suite/innodb/r/alter_rename_existing.result @@ -59,7 +59,7 @@ ALTER TABLE t1 ADD COLUMN d INT, ALGORITHM=COPY; # SET GLOBAL innodb_file_per_table=ON; ALTER TABLE t1 FORCE, ALGORITHM=INPLACE; -ERROR HY000: Tablespace for table 'test/t1' exists. Please DISCARD the tablespace before IMPORT +ERROR HY000: Tablespace for table 'test/#sql-ib' exists. Please DISCARD the tablespace before IMPORT ALTER TABLE t1 FORCE, ALGORITHM=COPY; ERROR HY000: Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME' (errno: 184 "Tablespace already exists") # diff --git a/mysql-test/suite/innodb/r/alter_rename_files.result b/mysql-test/suite/innodb/r/alter_rename_files.result deleted file mode 100644 index 490f6773765..00000000000 --- a/mysql-test/suite/innodb/r/alter_rename_files.result +++ /dev/null @@ -1,19 +0,0 @@ -CREATE TABLE t1 (x INT NOT NULL UNIQUE KEY) ENGINE=InnoDB; -INSERT INTO t1 VALUES(5); -SET GLOBAL innodb_log_checkpoint_now=TRUE; -SET DEBUG_SYNC='commit_cache_rebuild SIGNAL ready WAIT_FOR finish'; -ALTER TABLE t1 FORCE;; -connect con1,localhost,root,,; -SET DEBUG_SYNC='now WAIT_FOR ready'; -SET GLOBAL innodb_log_checkpoint_now=TRUE; -SET DEBUG_SYNC='now SIGNAL finish'; -disconnect con1; -connection default; -SHOW CREATE TABLE t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `x` int(11) NOT NULL, - UNIQUE KEY `x` (`x`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 -DROP TABLE t1; -SET DEBUG_SYNC='RESET'; diff --git a/mysql-test/suite/innodb/r/foreign_key.result b/mysql-test/suite/innodb/r/foreign_key.result index df5ae6088ad..55a10141995 100644 --- a/mysql-test/suite/innodb/r/foreign_key.result +++ b/mysql-test/suite/innodb/r/foreign_key.result @@ -237,11 +237,7 @@ SET SESSION FOREIGN_KEY_CHECKS = OFF; ALTER TABLE t1 ADD FOREIGN KEY (f) REFERENCES non_existing_table (x); SET SESSION FOREIGN_KEY_CHECKS = ON; ALTER TABLE t1 ADD FULLTEXT INDEX ft1 (f); -Warnings: -Warning 1088 failed to load FOREIGN KEY constraints ALTER TABLE t1 ADD FULLTEXT INDEX ft2 (f); -Warnings: -Warning 1088 failed to load FOREIGN KEY constraints DROP TABLE t1; CREATE TABLE t1 (f VARCHAR(256), FTS_DOC_ID BIGINT UNSIGNED PRIMARY KEY) ENGINE=InnoDB; diff --git a/mysql-test/suite/innodb/t/alter_rename_existing.test b/mysql-test/suite/innodb/t/alter_rename_existing.test index 0202f2b6ad3..06602ae8e74 100644 --- a/mysql-test/suite/innodb/t/alter_rename_existing.test +++ b/mysql-test/suite/innodb/t/alter_rename_existing.test @@ -59,7 +59,7 @@ ALTER TABLE t1 ADD COLUMN d INT, ALGORITHM=COPY; --echo # while a blocking t1.ibd file exists. --echo # SET GLOBAL innodb_file_per_table=ON; ---replace_regex /$MYSQLD_DATADIR/MYSQLD_DATADIR/ +--replace_regex /#sql-ib[1-9][0-9]*/#sql-ib/ --error ER_TABLESPACE_EXISTS ALTER TABLE t1 FORCE, ALGORITHM=INPLACE; --replace_regex /Error on rename of '.*' to '.*'/Error on rename of 'OLD_FILE_NAME' to 'NEW_FILE_NAME'/ diff --git a/mysql-test/suite/innodb/t/alter_rename_files.test b/mysql-test/suite/innodb/t/alter_rename_files.test deleted file mode 100644 index 27408320f7d..00000000000 --- a/mysql-test/suite/innodb/t/alter_rename_files.test +++ /dev/null @@ -1,31 +0,0 @@ ---source include/have_debug.inc ---source include/have_debug_sync.inc ---source include/have_innodb.inc ---source include/count_sessions.inc - -CREATE TABLE t1 (x INT NOT NULL UNIQUE KEY) ENGINE=InnoDB; -INSERT INTO t1 VALUES(5); - -SET GLOBAL innodb_log_checkpoint_now=TRUE; - -# Start an ALTER TABLE and stop it before renaming the files -SET DEBUG_SYNC='commit_cache_rebuild SIGNAL ready WAIT_FOR finish'; - ---send ALTER TABLE t1 FORCE; - -connect (con1,localhost,root,,); - -SET DEBUG_SYNC='now WAIT_FOR ready'; - -SET GLOBAL innodb_log_checkpoint_now=TRUE; - -SET DEBUG_SYNC='now SIGNAL finish'; - -disconnect con1; -connection default; -reap; -SHOW CREATE TABLE t1; -DROP TABLE t1; -SET DEBUG_SYNC='RESET'; - ---source include/wait_until_count_sessions.inc diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index a7bad31078a..129f672255b 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -4417,80 +4417,6 @@ fil_delete_file( } } -/** Generate redo log for swapping two .ibd files -@param[in] old_table old table -@param[in] new_table new table -@param[in] tmp_name temporary table name -@param[in,out] mtr mini-transaction -@return innodb error code */ -dberr_t -fil_mtr_rename_log( - const dict_table_t* old_table, - const dict_table_t* new_table, - const char* tmp_name, - mtr_t* mtr) -{ - ut_ad(old_table->space != fil_system.temp_space); - ut_ad(new_table->space != fil_system.temp_space); - ut_ad(old_table->space->id == old_table->space_id); - ut_ad(new_table->space->id == new_table->space_id); - - /* If neither table is file-per-table, - there will be no renaming of files. */ - if (!old_table->space_id && !new_table->space_id) { - return(DB_SUCCESS); - } - - const bool has_data_dir = DICT_TF_HAS_DATA_DIR(old_table->flags); - - if (old_table->space_id) { - char* tmp_path = fil_make_filepath( - has_data_dir ? old_table->data_dir_path : NULL, - tmp_name, IBD, has_data_dir); - if (tmp_path == NULL) { - return(DB_OUT_OF_MEMORY); - } - - const char* old_path = old_table->space->chain.start->name; - /* Temp filepath must not exist. */ - dberr_t err = fil_rename_tablespace_check( - old_path, tmp_path, !old_table->space); - if (err != DB_SUCCESS) { - ut_free(tmp_path); - return(err); - } - - fil_name_write_rename_low( - old_table->space_id, old_path, tmp_path, mtr); - - ut_free(tmp_path); - } - - if (new_table->space_id) { - const char* new_path = new_table->space->chain.start->name; - char* old_path = fil_make_filepath( - has_data_dir ? old_table->data_dir_path : NULL, - old_table->name.m_name, IBD, has_data_dir); - - /* Destination filepath must not exist unless this ALTER - TABLE starts and ends with a file_per-table tablespace. */ - if (!old_table->space_id) { - dberr_t err = fil_rename_tablespace_check( - new_path, old_path, !new_table->space); - if (err != DB_SUCCESS) { - ut_free(old_path); - return(err); - } - } - - fil_name_write_rename_low( - new_table->space_id, new_path, old_path, mtr); - ut_free(old_path); - } - - return DB_SUCCESS; -} - #ifdef UNIV_DEBUG /** Check that a tablespace is valid for mtr_commit(). @param[in] space persistent tablespace that has been changed */ @@ -4594,11 +4520,6 @@ fil_names_clear( ut_ad(log_mutex_own()); ut_ad(lsn); - if (log_sys.append_on_checkpoint) { - mtr_write_log(log_sys.append_on_checkpoint); - do_write = true; - } - mtr.start(); for (fil_space_t* space = UT_LIST_GET_FIRST(fil_system.named_spaces); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index a36cc87a201..38d7299923a 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -18590,8 +18590,6 @@ checkpoint_now_set(THD*, st_mysql_sys_var*, void*, const void* save) while (log_sys.last_checkpoint_lsn + SIZE_OF_FILE_CHECKPOINT - + (log_sys.append_on_checkpoint != NULL - ? log_sys.append_on_checkpoint->size() : 0) < log_sys.lsn) { log_make_checkpoint(); log_sys.log.flush_data_only(); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 3b84a9947b2..f889d2fc1b6 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -46,7 +46,6 @@ Smart ALTER TABLE #include "row0row.h" #include "row0upd.h" #include "trx0trx.h" -#include "trx0roll.h" #include "handler0alter.h" #include "srv0mon.h" #include "srv0srv.h" @@ -9771,13 +9770,16 @@ commit_try_rebuild( /* We can now rename the old table as a temporary table, rename the new temporary table as the old table and drop the - old table. First, we only do this in the data dictionary - tables. The actual renaming will be performed in - commit_cache_rebuild(), once the data dictionary transaction - has been successfully committed. */ + old table. */ + char* old_name= mem_heap_strdup(ctx->heap, user_table->name.m_name); - error = row_merge_rename_tables_dict( - user_table, rebuilt_table, ctx->tmp_name, trx); + error = row_rename_table_for_mysql(user_table->name.m_name, + ctx->tmp_name, trx, false, false); + if (error == DB_SUCCESS) { + error = row_rename_table_for_mysql(rebuilt_table->name.m_name, + old_name, trx, + false, false); + } /* We must be still holding a table handle. */ DBUG_ASSERT(user_table->get_ref_count() == 1); @@ -9834,38 +9836,6 @@ rename_indexes_try( return false; } -/** Apply the changes made during commit_try_rebuild(), -to the data dictionary cache and the file system. -@param ctx In-place ALTER TABLE context */ -inline MY_ATTRIBUTE((nonnull)) -void -commit_cache_rebuild( -/*=================*/ - ha_innobase_inplace_ctx* ctx) -{ - dberr_t error; - - DBUG_ENTER("commit_cache_rebuild"); - DEBUG_SYNC_C("commit_cache_rebuild"); - DBUG_ASSERT(ctx->need_rebuild()); - DBUG_ASSERT(!ctx->old_table->space == !ctx->new_table->space); - - const char* old_name = mem_heap_strdup( - ctx->heap, ctx->old_table->name.m_name); - - /* We already committed and redo logged the renames, - so this must succeed. */ - error = dict_table_rename_in_cache( - ctx->old_table, ctx->tmp_name, false); - ut_a(error == DB_SUCCESS); - - error = dict_table_rename_in_cache( - ctx->new_table, old_name, false); - ut_a(error == DB_SUCCESS); - - DBUG_VOID_RETURN; -} - /** Set of column numbers */ typedef std::set<ulint, std::less<ulint>, ut_allocator<ulint> > col_set; @@ -10613,7 +10583,6 @@ ha_innobase::commit_inplace_alter_table( bool commit) { ha_innobase_inplace_ctx*ctx0; - struct mtr_buf_copy_t logs; ctx0 = static_cast<ha_innobase_inplace_ctx*> (ha_alter_info->handler_ctx); @@ -10760,8 +10729,6 @@ ha_innobase::commit_inplace_alter_table( or lock waits can happen in it during the data dictionary operation. */ row_mysql_lock_data_dictionary(trx); - ut_ad(log_append_on_checkpoint(NULL) == NULL); - /* Prevent the background statistics collection from accessing the tables. */ for (;;) { @@ -10852,33 +10819,6 @@ ha_innobase::commit_inplace_alter_table( } else if (!new_clustered) { trx_commit_for_mysql(trx); } else { - mtr_t mtr; - mtr_start(&mtr); - - for (inplace_alter_handler_ctx** pctx = ctx_array; - *pctx; pctx++) { - ha_innobase_inplace_ctx* ctx - = static_cast<ha_innobase_inplace_ctx*>(*pctx); - - DBUG_ASSERT(ctx->need_rebuild()); - /* Check for any possible problems for any - file operations that will be performed in - commit_cache_rebuild(), and if none, generate - the redo log for these operations. */ - dberr_t error = fil_mtr_rename_log( - ctx->old_table, ctx->new_table, ctx->tmp_name, - &mtr); - if (error != DB_SUCCESS) { - /* Out of memory or a problem will occur - when renaming files. */ - fail = true; - my_error_innodb(error, ctx->old_table->name.m_name, - ctx->old_table->flags); - } - DBUG_INJECT_CRASH("ib_commit_inplace_crash", - crash_inject_count++); - } - /* Test what happens on crash if the redo logs are flushed to disk here. The log records about the rename should not be committed, and @@ -10890,34 +10830,11 @@ ha_innobase::commit_inplace_alter_table( ut_ad(!trx->fts_trx); if (fail) { - mtr.set_log_mode(MTR_LOG_NO_REDO); - mtr_commit(&mtr); trx_rollback_for_mysql(trx); } else { ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE)); ut_ad(trx->has_logged()); - - if (mtr.get_log()->size() > 0) { - ut_ad((*mtr.get_log()->front()->begin() - & 0xf0) == FILE_RENAME); - /* Append the FILE_RENAME - records on checkpoint, as a separate - mini-transaction before the one that - contains the FILE_CHECKPOINT marker. */ - mtr.get_log()->for_each_block(logs); - logs.m_buf.push(field_ref_zero, 1); - log_append_on_checkpoint(&logs.m_buf); - } - - /* The following call commits the - mini-transaction, making the data dictionary - transaction committed at mtr.end_lsn. The - transaction becomes 'durable' by the time when - log_buffer_flush_to_disk() returns. In the - logical sense the commit in the file-based - data structures happens here. */ - - trx_commit_low(trx, &mtr); + trx_commit(trx); } /* If server crashes here, the dictionary in @@ -10994,9 +10911,6 @@ ha_innobase::commit_inplace_alter_table( DBUG_PRINT("to_be_dropped", ("table: %s", ctx->old_table->name.m_name)); - /* Rename the tablespace files. */ - commit_cache_rebuild(ctx); - if (innobase_update_foreign_cache(ctx, m_user_thd) != DB_SUCCESS && m_prebuilt->trx->check_foreigns) { @@ -11030,8 +10944,6 @@ foreign_fail: crash_inject_count++); } - log_append_on_checkpoint(NULL); - /* Tell the InnoDB server that there might be work for utility threads: */ diff --git a/storage/innobase/include/dyn0buf.h b/storage/innobase/include/dyn0buf.h index b15d35c4831..ffe9b5d21dc 100644 --- a/storage/innobase/include/dyn0buf.h +++ b/storage/innobase/include/dyn0buf.h @@ -475,20 +475,4 @@ private: block_t m_first_block; }; -/** mtr_buf_t copier */ -struct mtr_buf_copy_t { - /** The copied buffer */ - mtr_buf_t m_buf; - - /** Append a block to the redo log buffer. - @return whether the appending should continue (always true here) */ - bool operator()(const mtr_buf_t::block_t* block) - { - byte* buf = m_buf.open(block->used()); - memcpy(buf, block->begin(), block->used()); - m_buf.close(buf + block->used()); - return(true); - } -}; - #endif /* dyn0buf_h */ diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 59ef0f80c42..e34c563df9e 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -1484,20 +1484,6 @@ char* fil_path_to_space_name( const char* filename); -/** Generate redo log for swapping two .ibd files -@param[in] old_table old table -@param[in] new_table new table -@param[in] tmp_name temporary table name -@param[in,out] mtr mini-transaction -@return innodb error code */ -dberr_t -fil_mtr_rename_log( - const dict_table_t* old_table, - const dict_table_t* new_table, - const char* tmp_name, - mtr_t* mtr) - MY_ATTRIBUTE((nonnull, warn_unused_result)); - /** Acquire the fil_system mutex. */ #define fil_system_enter() mutex_enter(&fil_system.mutex) /** Release the fil_system mutex. */ diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index 69d6064f49f..a484f04666a 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -218,12 +218,6 @@ void log_header_read(ulint header); @param[in] end_lsn start LSN of the FILE_CHECKPOINT mini-transaction */ void log_write_checkpoint_info(lsn_t end_lsn); -/** Set extra data to be written to the redo log during checkpoint. -@param[in] buf data to be appended on checkpoint, or NULL -@return pointer to previous data to be appended on checkpoint */ -mtr_buf_t* -log_append_on_checkpoint( - mtr_buf_t* buf); /** Checks that there is enough free space in the log to start a new query step. Flushes the log buffer or makes a new checkpoint if necessary. NOTE: this @@ -750,13 +744,6 @@ struct log_t{ /*!< latest checkpoint lsn */ lsn_t next_checkpoint_lsn; /*!< next checkpoint lsn */ - mtr_buf_t* append_on_checkpoint; - /*!< extra redo log records to write - during a checkpoint, or NULL if none. - The pointer is protected by - log_sys.mutex, and the data must - remain constant as long as this - pointer is not NULL. */ ulint n_pending_checkpoint_writes; /*!< number of currently pending checkpoint writes */ diff --git a/storage/innobase/include/row0merge.h b/storage/innobase/include/row0merge.h index 3ba7508911a..25ee088f1f7 100644 --- a/storage/innobase/include/row0merge.h +++ b/storage/innobase/include/row0merge.h @@ -215,22 +215,6 @@ row_make_new_pathname( MY_ATTRIBUTE((nonnull, warn_unused_result)); /*********************************************************************//** -Rename the tables in the data dictionary. The data dictionary must -have been locked exclusively by the caller, because the transaction -will not be committed. -@return error code or DB_SUCCESS */ -dberr_t -row_merge_rename_tables_dict( -/*=========================*/ - dict_table_t* old_table, /*!< in/out: old table, renamed to - tmp_name */ - dict_table_t* new_table, /*!< in/out: new table, renamed to - old_table->name */ - const char* tmp_name, /*!< in: new name for old_table */ - trx_t* trx) /*!< in/out: dictionary transaction */ - MY_ATTRIBUTE((nonnull, warn_unused_result)); - -/*********************************************************************//** Rename an index in the dictionary that was created. The data dictionary must have been locked exclusively by the caller, because the transaction will not be committed. diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 4a1ff08e2bc..b63ea201ffb 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -544,7 +544,6 @@ void log_t::create() max_checkpoint_age= 0; next_checkpoint_no= 0; next_checkpoint_lsn= 0; - append_on_checkpoint= NULL; n_pending_checkpoint_writes= 0; last_checkpoint_lsn= lsn; @@ -1435,20 +1434,6 @@ void log_write_checkpoint_info(lsn_t end_lsn) log_mutex_exit(); } -/** Set extra data to be written to the redo log during checkpoint. -@param[in] buf data to be appended on checkpoint, or NULL -@return pointer to previous data to be appended on checkpoint */ -mtr_buf_t* -log_append_on_checkpoint( - mtr_buf_t* buf) -{ - log_mutex_enter(); - mtr_buf_t* old = log_sys.append_on_checkpoint; - log_sys.append_on_checkpoint = buf; - log_mutex_exit(); - return(old); -} - /** Make a checkpoint. Note that this function does not flush dirty blocks from the buffer pool: it only checks what is lsn of the oldest modification in the pool, and writes information about the lsn in diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 044a974f253..5523b867bf5 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -4250,121 +4250,6 @@ row_make_new_pathname( new_name); } -/*********************************************************************//** -Rename the tables in the data dictionary. The data dictionary must -have been locked exclusively by the caller, because the transaction -will not be committed. -@return error code or DB_SUCCESS */ -dberr_t -row_merge_rename_tables_dict( -/*=========================*/ - dict_table_t* old_table, /*!< in/out: old table, renamed to - tmp_name */ - dict_table_t* new_table, /*!< in/out: new table, renamed to - old_table->name */ - const char* tmp_name, /*!< in: new name for old_table */ - trx_t* trx) /*!< in/out: dictionary transaction */ -{ - dberr_t err = DB_ERROR; - pars_info_t* info; - - ut_ad(!srv_read_only_mode); - ut_ad(old_table != new_table); - ut_d(dict_sys.assert_locked()); - ut_a(trx->dict_operation_lock_mode == RW_X_LATCH); - ut_ad(trx_get_dict_operation(trx) == TRX_DICT_OP_TABLE - || trx_get_dict_operation(trx) == TRX_DICT_OP_INDEX); - - trx->op_info = "renaming tables"; - - /* We use the private SQL parser of Innobase to generate the query - graphs needed in updating the dictionary data in system tables. */ - - info = pars_info_create(); - - pars_info_add_str_literal(info, "new_name", new_table->name.m_name); - pars_info_add_str_literal(info, "old_name", old_table->name.m_name); - pars_info_add_str_literal(info, "tmp_name", tmp_name); - - err = que_eval_sql(info, - "PROCEDURE RENAME_TABLES () IS\n" - "BEGIN\n" - "UPDATE SYS_TABLES SET NAME = :tmp_name\n" - " WHERE NAME = :old_name;\n" - "UPDATE SYS_TABLES SET NAME = :old_name\n" - " WHERE NAME = :new_name;\n" - "END;\n", FALSE, trx); - - /* Update SYS_TABLESPACES and SYS_DATAFILES if the old table being - renamed is a single-table tablespace, which must be implicitly - renamed along with the table. */ - if (err == DB_SUCCESS - && old_table->space_id) { - /* Make pathname to update SYS_DATAFILES. */ - char* tmp_path = row_make_new_pathname(old_table, tmp_name); - - info = pars_info_create(); - - pars_info_add_str_literal(info, "tmp_name", tmp_name); - pars_info_add_str_literal(info, "tmp_path", tmp_path); - pars_info_add_int4_literal(info, "old_space", - old_table->space_id); - - err = que_eval_sql(info, - "PROCEDURE RENAME_OLD_SPACE () IS\n" - "BEGIN\n" - "UPDATE SYS_TABLESPACES" - " SET NAME = :tmp_name\n" - " WHERE SPACE = :old_space;\n" - "UPDATE SYS_DATAFILES" - " SET PATH = :tmp_path\n" - " WHERE SPACE = :old_space;\n" - "END;\n", FALSE, trx); - - ut_free(tmp_path); - } - - /* Update SYS_TABLESPACES and SYS_DATAFILES if the new table being - renamed is a single-table tablespace, which must be implicitly - renamed along with the table. */ - if (err == DB_SUCCESS - && dict_table_is_file_per_table(new_table)) { - /* Make pathname to update SYS_DATAFILES. */ - char* old_path = row_make_new_pathname( - new_table, old_table->name.m_name); - - info = pars_info_create(); - - pars_info_add_str_literal(info, "old_name", - old_table->name.m_name); - pars_info_add_str_literal(info, "old_path", old_path); - pars_info_add_int4_literal(info, "new_space", - new_table->space_id); - - err = que_eval_sql(info, - "PROCEDURE RENAME_NEW_SPACE () IS\n" - "BEGIN\n" - "UPDATE SYS_TABLESPACES" - " SET NAME = :old_name\n" - " WHERE SPACE = :new_space;\n" - "UPDATE SYS_DATAFILES" - " SET PATH = :old_path\n" - " WHERE SPACE = :new_space;\n" - "END;\n", FALSE, trx); - - ut_free(old_path); - } - - if (err == DB_SUCCESS && (new_table->flags2 & DICT_TF2_DISCARDED)) { - err = row_import_update_discarded_flag( - trx, new_table->id, true); - } - - trx->op_info = ""; - - return(err); -} - /** Create the index and load in to the dictionary. @param[in,out] table the index is on this table @param[in] index_def the index definition diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 5cc02dff1e2..601c30b7396 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -4544,13 +4544,16 @@ end: } /* We only want to switch off some of the type checking in - an ALTER TABLE...ALGORITHM=COPY, not in a RENAME. */ + an ALTER TABLE, not in a RENAME. */ dict_names_t fk_tables; err = dict_load_foreigns( - new_name, NULL, - false, !old_is_tmp || trx->check_foreigns, - DICT_ERR_IGNORE_NONE, fk_tables); + new_name, NULL, false, + !old_is_tmp || trx->check_foreigns, + use_fk + ? DICT_ERR_IGNORE_NONE + : DICT_ERR_IGNORE_FK_NOKEY, + fk_tables); if (err != DB_SUCCESS) { @@ -4569,8 +4572,6 @@ end: " with the new table definition."; } - ut_a(DB_SUCCESS == dict_table_rename_in_cache( - table, old_name, FALSE)); trx->error_state = DB_SUCCESS; trx_rollback_to_savepoint(trx, NULL); trx->error_state = DB_SUCCESS; |