summaryrefslogtreecommitdiff
path: root/storage/xtradb
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2016-06-23 07:42:40 +0300
committerJan Lindström <jan.lindstrom@mariadb.com>2016-06-23 07:42:40 +0300
commit26de9061e8c4462152b4bcff2b9cbb80cde12de1 (patch)
tree517ff7ad9e9f1417960d31172dfeadb0472b9bbb /storage/xtradb
parente16780619630676f822248f3637972235481fd96 (diff)
downloadmariadb-git-26de9061e8c4462152b4bcff2b9cbb80cde12de1.tar.gz
Merge following commit from 5.5:
commit ef92aaf9ece92c873ae0f3448ab2274c958ba3fe Author: Jan Lindström <jan.lindstrom@mariadb.com> Date: Wed Jun 22 22:37:28 2016 +0300 MDEV-10083: Orphan ibd file when playing with foreign keys Analysis: row_drop_table_for_mysql did not allow dropping referenced table even in case when actual creating of the referenced table was not successfull if foreign_key_checks=1. Fix: Allow dropping referenced table even if foreign_key_checks=1 if actual table create returned error.
Diffstat (limited to 'storage/xtradb')
-rw-r--r--storage/xtradb/dict/dict0crea.cc16
-rw-r--r--storage/xtradb/fts/fts0fts.cc4
-rw-r--r--storage/xtradb/handler/ha_innodb.cc6
-rw-r--r--storage/xtradb/include/row0mysql.h3
-rw-r--r--storage/xtradb/row/row0merge.cc2
-rw-r--r--storage/xtradb/row/row0mysql.cc22
-rw-r--r--storage/xtradb/trx/trx0roll.cc2
7 files changed, 34 insertions, 21 deletions
diff --git a/storage/xtradb/dict/dict0crea.cc b/storage/xtradb/dict/dict0crea.cc
index 37ebdbae54a..b0a3263d097 100644
--- a/storage/xtradb/dict/dict0crea.cc
+++ b/storage/xtradb/dict/dict0crea.cc
@@ -1365,7 +1365,7 @@ dict_create_or_check_foreign_constraint_tables(void)
ib_logf(IB_LOG_LEVEL_WARN,
"Dropping incompletely created "
"SYS_FOREIGN table.");
- row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE);
+ row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE, TRUE);
}
if (sys_foreign_cols_err == DB_CORRUPTION) {
@@ -1373,7 +1373,7 @@ dict_create_or_check_foreign_constraint_tables(void)
"Dropping incompletely created "
"SYS_FOREIGN_COLS table.");
- row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE);
+ row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE, TRUE);
}
ib_logf(IB_LOG_LEVEL_WARN,
@@ -1427,8 +1427,8 @@ dict_create_or_check_foreign_constraint_tables(void)
ut_ad(err == DB_OUT_OF_FILE_SPACE
|| err == DB_TOO_MANY_CONCURRENT_TRXS);
- 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);
if (err == DB_OUT_OF_FILE_SPACE) {
err = DB_MUST_GET_MORE_FILE_SPACE;
@@ -1852,7 +1852,7 @@ dict_create_or_check_sys_tablespace(void)
ib_logf(IB_LOG_LEVEL_WARN,
"Dropping incompletely created "
"SYS_TABLESPACES table.");
- row_drop_table_for_mysql("SYS_TABLESPACES", trx, TRUE);
+ row_drop_table_for_mysql("SYS_TABLESPACES", trx, TRUE, TRUE);
}
if (sys_datafiles_err == DB_CORRUPTION) {
@@ -1860,7 +1860,7 @@ dict_create_or_check_sys_tablespace(void)
"Dropping incompletely created "
"SYS_DATAFILES table.");
- row_drop_table_for_mysql("SYS_DATAFILES", trx, TRUE);
+ row_drop_table_for_mysql("SYS_DATAFILES", trx, TRUE, TRUE);
}
ib_logf(IB_LOG_LEVEL_INFO,
@@ -1896,8 +1896,8 @@ dict_create_or_check_sys_tablespace(void)
ut_a(err == DB_OUT_OF_FILE_SPACE
|| err == DB_TOO_MANY_CONCURRENT_TRXS);
- row_drop_table_for_mysql("SYS_TABLESPACES", trx, TRUE);
- row_drop_table_for_mysql("SYS_DATAFILES", trx, TRUE);
+ row_drop_table_for_mysql("SYS_TABLESPACES", trx, TRUE, TRUE);
+ row_drop_table_for_mysql("SYS_DATAFILES", trx, TRUE, TRUE);
if (err == DB_OUT_OF_FILE_SPACE) {
err = DB_MUST_GET_MORE_FILE_SPACE;
diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc
index fe97b9f7e1a..695e1d25dbe 100644
--- a/storage/xtradb/fts/fts0fts.cc
+++ b/storage/xtradb/fts/fts0fts.cc
@@ -1919,7 +1919,7 @@ func_exit:
trx_rollback_to_savepoint(trx, NULL);
- row_drop_table_for_mysql(table->name, trx, FALSE);
+ row_drop_table_for_mysql(table->name, trx, FALSE, TRUE);
trx->error_state = DB_SUCCESS;
}
@@ -2071,7 +2071,7 @@ fts_create_index_tables_low(
trx_rollback_to_savepoint(trx, NULL);
- row_drop_table_for_mysql(table_name, trx, FALSE);
+ row_drop_table_for_mysql(table_name, trx, FALSE, TRUE);
trx->error_state = DB_SUCCESS;
}
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 0bedadc63d9..82e44fe5af0 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -11470,7 +11470,8 @@ ha_innobase::delete_table(
/* Drop the table in InnoDB */
err = row_drop_table_for_mysql(
- norm_name, trx, thd_sql_command(thd) == SQLCOM_DROP_DB);
+ norm_name, trx, thd_sql_command(thd) == SQLCOM_DROP_DB,
+ FALSE);
if (err == DB_TABLE_NOT_FOUND
@@ -11501,7 +11502,8 @@ ha_innobase::delete_table(
#endif
err = row_drop_table_for_mysql(
par_case_name, trx,
- thd_sql_command(thd) == SQLCOM_DROP_DB);
+ thd_sql_command(thd) == SQLCOM_DROP_DB,
+ FALSE);
}
}
diff --git a/storage/xtradb/include/row0mysql.h b/storage/xtradb/include/row0mysql.h
index 027d76317c4..a2f2a2e7371 100644
--- a/storage/xtradb/include/row0mysql.h
+++ b/storage/xtradb/include/row0mysql.h
@@ -488,6 +488,9 @@ row_drop_table_for_mysql(
const char* name, /*!< in: table name */
trx_t* trx, /*!< in: dictionary transaction handle */
bool drop_db,/*!< in: true=dropping whole database */
+ ibool create_failed,/*!<in: TRUE=create table failed
+ because e.g. foreign key column
+ type mismatch. */
bool nonatomic = true)
/*!< in: whether it is permitted
to release and reacquire dict_operation_lock */
diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc
index f7268af84c9..21304719a53 100644
--- a/storage/xtradb/row/row0merge.cc
+++ b/storage/xtradb/row/row0merge.cc
@@ -3635,7 +3635,7 @@ row_merge_drop_table(
/* There must be no open transactions on the table. */
ut_a(table->n_ref_count == 0);
- return(row_drop_table_for_mysql(table->name, trx, false, false));
+ return(row_drop_table_for_mysql(table->name, trx, false, false, false));
}
/*********************************************************************//**
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index 999bfbd401e..446237078c2 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -2400,7 +2400,7 @@ err_exit:
dict_table_close(table, TRUE, FALSE);
- row_drop_table_for_mysql(table->name, trx, FALSE);
+ row_drop_table_for_mysql(table->name, trx, FALSE, TRUE);
if (commit) {
trx_commit_for_mysql(trx);
@@ -2560,7 +2560,7 @@ error_handling:
trx_rollback_to_savepoint(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);
@@ -2637,7 +2637,7 @@ row_table_add_foreign_constraints(
trx_rollback_to_savepoint(trx, NULL);
- row_drop_table_for_mysql(name, trx, FALSE);
+ row_drop_table_for_mysql(name, trx, FALSE, TRUE);
trx_commit_for_mysql(trx);
@@ -2678,7 +2678,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
@@ -3776,6 +3776,9 @@ row_drop_table_for_mysql(
const char* name, /*!< in: table name */
trx_t* trx, /*!< in: transaction handle */
bool drop_db,/*!< in: true=dropping whole database */
+ ibool create_failed,/*!<in: TRUE=create table failed
+ because e.g. foreign key column
+ type mismatch. */
bool nonatomic)
/*!< in: whether it is permitted
to release and reacquire dict_operation_lock */
@@ -3966,7 +3969,12 @@ row_drop_table_for_mysql(
name,
foreign->foreign_table_name_lookup);
- if (foreign->foreign_table != table && !ref_ok) {
+ /* 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->foreign_table != table &&
+ !create_failed && !ref_ok) {
FILE* ef = dict_foreign_err_file;
@@ -4507,7 +4515,7 @@ row_mysql_drop_temp_tables(void)
table = dict_table_get_low(table_name);
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);
}
@@ -4676,7 +4684,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.cc b/storage/xtradb/trx/trx0roll.cc
index e2c3c0b949c..0243507ddfb 100644
--- a/storage/xtradb/trx/trx0roll.cc
+++ b/storage/xtradb/trx/trx0roll.cc
@@ -641,7 +641,7 @@ trx_rollback_active(
"in recovery",
table->name, trx->table_id);
- 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 == DB_SUCCESS);