MDEV-35854: Clarify row_rename_table_for_mysql()
enum rename_fk: Replaces the "bool use_fk" parameter of row_rename_table_for_mysql() and innobase_rename_table(): RENAME_IGNORE_FK: Replaces use_fk=false when the operation cannot involve any FOREIGN KEY constraints, that is, it is a partitioned table or an internal table for FULLTEXT INDEX. RENAME_REBUILD: Replaces use_fk=false when the table may contain FOREIGN KEY constraints, which must not be modified in the data dictionary tables SYS_FOREIGN and SYS_FOREIGN_COLS. RENAME_ALTER_COPY: Replaces use_fk=true. This is only specified in ha_innobase::rename_table(), which may be invoked as part of ALTER TABLE…ALGORITHM=COPY, but also during RENAME TABLE. An alternative value RENAME_FK could be useful to specify in ha_innobase::rename_table() when it is executed as part of CREATE OR REPLACE TABLE, which currently is not an atomic operation. Reviewed by: Debarun Banerjee
This commit is contained in:
parent
d4da659b43
commit
2543be6942
@ -1392,7 +1392,7 @@ static dberr_t fts_drop_table(trx_t *trx, const char *table_name, bool rename)
|
|||||||
char *tmp= dict_mem_create_temporary_tablename(heap, table->name.m_name,
|
char *tmp= dict_mem_create_temporary_tablename(heap, table->name.m_name,
|
||||||
table->id);
|
table->id);
|
||||||
dberr_t err= row_rename_table_for_mysql(table->name.m_name, tmp, trx,
|
dberr_t err= row_rename_table_for_mysql(table->name.m_name, tmp, trx,
|
||||||
false);
|
RENAME_IGNORE_FK);
|
||||||
mem_heap_free(heap);
|
mem_heap_free(heap);
|
||||||
if (err != DB_SUCCESS)
|
if (err != DB_SUCCESS)
|
||||||
{
|
{
|
||||||
@ -1450,7 +1450,7 @@ fts_rename_one_aux_table(
|
|||||||
fts_table_new_name[table_new_name_len] = 0;
|
fts_table_new_name[table_new_name_len] = 0;
|
||||||
|
|
||||||
return row_rename_table_for_mysql(
|
return row_rename_table_for_mysql(
|
||||||
fts_table_old_name, fts_table_new_name, trx, false);
|
fts_table_old_name, fts_table_new_name, trx, RENAME_IGNORE_FK);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************//**
|
/****************************************************************//**
|
||||||
|
@ -13889,10 +13889,10 @@ err_exit:
|
|||||||
@param[in,out] trx InnoDB data dictionary transaction
|
@param[in,out] trx InnoDB data dictionary transaction
|
||||||
@param[in] from old table name
|
@param[in] from old table name
|
||||||
@param[in] to new table name
|
@param[in] to new table name
|
||||||
@param[in] use_fk whether to enforce FOREIGN KEY
|
@param[in] fk how to handle FOREIGN KEY
|
||||||
@return DB_SUCCESS or error code */
|
@return DB_SUCCESS or error code */
|
||||||
static dberr_t innobase_rename_table(trx_t *trx, const char *from,
|
static dberr_t innobase_rename_table(trx_t *trx, const char *from,
|
||||||
const char *to, bool use_fk)
|
const char *to, rename_fk fk)
|
||||||
{
|
{
|
||||||
dberr_t error;
|
dberr_t error;
|
||||||
char norm_to[FN_REFLEN];
|
char norm_to[FN_REFLEN];
|
||||||
@ -13910,7 +13910,7 @@ static dberr_t innobase_rename_table(trx_t *trx, const char *from,
|
|||||||
|
|
||||||
ut_ad(trx->will_lock);
|
ut_ad(trx->will_lock);
|
||||||
|
|
||||||
error = row_rename_table_for_mysql(norm_from, norm_to, trx, use_fk);
|
error = row_rename_table_for_mysql(norm_from, norm_to, trx, fk);
|
||||||
|
|
||||||
if (error != DB_SUCCESS) {
|
if (error != DB_SUCCESS) {
|
||||||
if (error == DB_TABLE_NOT_FOUND
|
if (error == DB_TABLE_NOT_FOUND
|
||||||
@ -13936,7 +13936,8 @@ static dberr_t innobase_rename_table(trx_t *trx, const char *from,
|
|||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
trx_start_if_not_started(trx, true);
|
trx_start_if_not_started(trx, true);
|
||||||
error = row_rename_table_for_mysql(
|
error = row_rename_table_for_mysql(
|
||||||
par_case_name, norm_to, trx, false);
|
par_case_name, norm_to, trx,
|
||||||
|
RENAME_IGNORE_FK);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14132,7 +14133,8 @@ int ha_innobase::truncate()
|
|||||||
|
|
||||||
if (error == DB_SUCCESS)
|
if (error == DB_SUCCESS)
|
||||||
{
|
{
|
||||||
error= innobase_rename_table(trx, ib_table->name.m_name, temp_name, false);
|
error= innobase_rename_table(trx, ib_table->name.m_name, temp_name,
|
||||||
|
RENAME_REBUILD);
|
||||||
if (error == DB_SUCCESS)
|
if (error == DB_SUCCESS)
|
||||||
error= trx->drop_table(*ib_table);
|
error= trx->drop_table(*ib_table);
|
||||||
}
|
}
|
||||||
@ -14330,7 +14332,8 @@ ha_innobase::rename_table(
|
|||||||
row_mysql_lock_data_dictionary(trx);
|
row_mysql_lock_data_dictionary(trx);
|
||||||
|
|
||||||
if (error == DB_SUCCESS) {
|
if (error == DB_SUCCESS) {
|
||||||
error = innobase_rename_table(trx, from, to, true);
|
error = innobase_rename_table(trx, from, to,
|
||||||
|
RENAME_ALTER_COPY);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_SYNC(thd, "after_innobase_rename_table");
|
DEBUG_SYNC(thd, "after_innobase_rename_table");
|
||||||
|
@ -10414,10 +10414,12 @@ commit_try_rebuild(
|
|||||||
char* old_name= mem_heap_strdup(ctx->heap, user_table->name.m_name);
|
char* old_name= mem_heap_strdup(ctx->heap, user_table->name.m_name);
|
||||||
|
|
||||||
dberr_t error = row_rename_table_for_mysql(user_table->name.m_name,
|
dberr_t error = row_rename_table_for_mysql(user_table->name.m_name,
|
||||||
ctx->tmp_name, trx, false);
|
ctx->tmp_name, trx,
|
||||||
|
RENAME_REBUILD);
|
||||||
if (error == DB_SUCCESS) {
|
if (error == DB_SUCCESS) {
|
||||||
error = row_rename_table_for_mysql(
|
error = row_rename_table_for_mysql(
|
||||||
rebuilt_table->name.m_name, old_name, trx, false);
|
rebuilt_table->name.m_name, old_name, trx,
|
||||||
|
RENAME_REBUILD);
|
||||||
if (error == DB_SUCCESS) {
|
if (error == DB_SUCCESS) {
|
||||||
/* The statistics for the surviving indexes will be
|
/* The statistics for the surviving indexes will be
|
||||||
re-inserted in alter_stats_rebuild(). */
|
re-inserted in alter_stats_rebuild(). */
|
||||||
|
@ -370,6 +370,15 @@ row_import_tablespace_for_mysql(
|
|||||||
row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL */
|
row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL */
|
||||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||||
|
|
||||||
|
enum rename_fk {
|
||||||
|
/** ignore FOREIGN KEY constraints */
|
||||||
|
RENAME_IGNORE_FK= 0,
|
||||||
|
/** Rename a table as part of a native table-rebuilding DDL operation */
|
||||||
|
RENAME_REBUILD,
|
||||||
|
/** Rename as part of ALTER TABLE...ALGORITHM=COPY */
|
||||||
|
RENAME_ALTER_COPY
|
||||||
|
};
|
||||||
|
|
||||||
/*********************************************************************//**
|
/*********************************************************************//**
|
||||||
Renames a table for MySQL.
|
Renames a table for MySQL.
|
||||||
@return error code or DB_SUCCESS */
|
@return error code or DB_SUCCESS */
|
||||||
@ -379,7 +388,7 @@ row_rename_table_for_mysql(
|
|||||||
const char* old_name, /*!< in: old table name */
|
const char* old_name, /*!< in: old table name */
|
||||||
const char* new_name, /*!< in: new table name */
|
const char* new_name, /*!< in: new table name */
|
||||||
trx_t* trx, /*!< in/out: transaction */
|
trx_t* trx, /*!< in/out: transaction */
|
||||||
bool use_fk) /*!< in: whether to parse and enforce
|
rename_fk fk) /*!< in: how to handle
|
||||||
FOREIGN KEY constraints */
|
FOREIGN KEY constraints */
|
||||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||||
|
|
||||||
|
@ -2554,7 +2554,7 @@ row_rename_table_for_mysql(
|
|||||||
const char* old_name, /*!< in: old table name */
|
const char* old_name, /*!< in: old table name */
|
||||||
const char* new_name, /*!< in: new table name */
|
const char* new_name, /*!< in: new table name */
|
||||||
trx_t* trx, /*!< in/out: transaction */
|
trx_t* trx, /*!< in/out: transaction */
|
||||||
bool use_fk) /*!< in: whether to parse and enforce
|
rename_fk fk) /*!< in: how to handle
|
||||||
FOREIGN KEY constraints */
|
FOREIGN KEY constraints */
|
||||||
{
|
{
|
||||||
dict_table_t* table = NULL;
|
dict_table_t* table = NULL;
|
||||||
@ -2579,6 +2579,8 @@ row_rename_table_for_mysql(
|
|||||||
old_is_tmp = dict_table_t::is_temporary_name(old_name);
|
old_is_tmp = dict_table_t::is_temporary_name(old_name);
|
||||||
new_is_tmp = dict_table_t::is_temporary_name(new_name);
|
new_is_tmp = dict_table_t::is_temporary_name(new_name);
|
||||||
|
|
||||||
|
ut_ad(fk != RENAME_IGNORE_FK || !new_is_tmp);
|
||||||
|
|
||||||
table = dict_table_open_on_name(old_name, true,
|
table = dict_table_open_on_name(old_name, true,
|
||||||
DICT_ERR_IGNORE_FK_NOKEY);
|
DICT_ERR_IGNORE_FK_NOKEY);
|
||||||
|
|
||||||
@ -2638,10 +2640,9 @@ row_rename_table_for_mysql(
|
|||||||
<< TROUBLESHOOTING_MSG;
|
<< TROUBLESHOOTING_MSG;
|
||||||
|
|
||||||
goto funct_exit;
|
goto funct_exit;
|
||||||
|
} else if (fk == RENAME_ALTER_COPY && !old_is_tmp && new_is_tmp) {
|
||||||
} else if (use_fk && !old_is_tmp && new_is_tmp) {
|
/* Non-native ALTER TABLE is renaming the
|
||||||
/* MySQL is doing an ALTER TABLE command and it renames the
|
original table to a temporary name. We want to preserve
|
||||||
original table to a temporary table name. We want to preserve
|
|
||||||
the original foreign key constraint definitions despite the
|
the original foreign key constraint definitions despite the
|
||||||
name change. An exception is those constraints for which
|
name change. An exception is those constraints for which
|
||||||
the ALTER TABLE contained DROP FOREIGN KEY <foreign key id>.*/
|
the ALTER TABLE contained DROP FOREIGN KEY <foreign key id>.*/
|
||||||
@ -2685,7 +2686,7 @@ row_rename_table_for_mysql(
|
|||||||
goto rollback_and_exit;
|
goto rollback_and_exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!new_is_tmp) {
|
if (/* fk == RENAME_IGNORE_FK || */ !new_is_tmp) {
|
||||||
/* Rename all constraints. */
|
/* Rename all constraints. */
|
||||||
char new_table_name[MAX_TABLE_NAME_LEN + 1];
|
char new_table_name[MAX_TABLE_NAME_LEN + 1];
|
||||||
char old_table_utf8[MAX_TABLE_NAME_LEN + 1];
|
char old_table_utf8[MAX_TABLE_NAME_LEN + 1];
|
||||||
@ -2859,7 +2860,7 @@ row_rename_table_for_mysql(
|
|||||||
err = dict_load_foreigns(
|
err = dict_load_foreigns(
|
||||||
new_name, nullptr, trx->id,
|
new_name, nullptr, trx->id,
|
||||||
!old_is_tmp || trx->check_foreigns,
|
!old_is_tmp || trx->check_foreigns,
|
||||||
use_fk
|
fk == RENAME_ALTER_COPY
|
||||||
? DICT_ERR_IGNORE_NONE
|
? DICT_ERR_IGNORE_NONE
|
||||||
: DICT_ERR_IGNORE_FK_NOKEY,
|
: DICT_ERR_IGNORE_FK_NOKEY,
|
||||||
fk_tables);
|
fk_tables);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user