diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2016-06-23 07:42:40 +0300 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2016-06-23 07:42:40 +0300 |
commit | 26de9061e8c4462152b4bcff2b9cbb80cde12de1 (patch) | |
tree | 517ff7ad9e9f1417960d31172dfeadb0472b9bbb /storage/xtradb | |
parent | e16780619630676f822248f3637972235481fd96 (diff) | |
download | mariadb-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.cc | 16 | ||||
-rw-r--r-- | storage/xtradb/fts/fts0fts.cc | 4 | ||||
-rw-r--r-- | storage/xtradb/handler/ha_innodb.cc | 6 | ||||
-rw-r--r-- | storage/xtradb/include/row0mysql.h | 3 | ||||
-rw-r--r-- | storage/xtradb/row/row0merge.cc | 2 | ||||
-rw-r--r-- | storage/xtradb/row/row0mysql.cc | 22 | ||||
-rw-r--r-- | storage/xtradb/trx/trx0roll.cc | 2 |
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); |