summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-03-03 22:15:44 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-03-03 22:25:20 +0200
commit37e7bde12abddcda4d5505450e39a739561bd4d5 (patch)
treee7c236289d9a662947557131729c623f640489fe
parent1ef10744abfac64583c793080ef678ac2575a5b1 (diff)
downloadmariadb-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.result2
-rw-r--r--mysql-test/suite/innodb/r/alter_rename_files.result19
-rw-r--r--mysql-test/suite/innodb/r/foreign_key.result4
-rw-r--r--mysql-test/suite/innodb/t/alter_rename_existing.test2
-rw-r--r--mysql-test/suite/innodb/t/alter_rename_files.test31
-rw-r--r--storage/innobase/fil/fil0fil.cc79
-rw-r--r--storage/innobase/handler/ha_innodb.cc2
-rw-r--r--storage/innobase/handler/handler0alter.cc108
-rw-r--r--storage/innobase/include/dyn0buf.h16
-rw-r--r--storage/innobase/include/fil0fil.h14
-rw-r--r--storage/innobase/include/log0log.h13
-rw-r--r--storage/innobase/include/row0merge.h16
-rw-r--r--storage/innobase/log/log0log.cc15
-rw-r--r--storage/innobase/row/row0merge.cc115
-rw-r--r--storage/innobase/row/row0mysql.cc13
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;