diff options
-rw-r--r-- | mysql-test/main/create_or_replace.result | 3 | ||||
-rw-r--r-- | mysql-test/main/create_or_replace.test | 1 | ||||
-rw-r--r-- | sql/debug.cc | 2 | ||||
-rw-r--r-- | sql/handler.h | 7 | ||||
-rw-r--r-- | sql/sql_table.cc | 23 | ||||
-rw-r--r-- | sql/sql_table.h | 2 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 16 |
7 files changed, 37 insertions, 17 deletions
diff --git a/mysql-test/main/create_or_replace.result b/mysql-test/main/create_or_replace.result index e63df3c5c13..4f8b4ea2b02 100644 --- a/mysql-test/main/create_or_replace.result +++ b/mysql-test/main/create_or_replace.result @@ -915,10 +915,11 @@ Warning 1265 Data truncated for column 'stat_description' at row 2 Warning 1265 Data truncated for column 'stat_description' at row 3 lock table t write; create or replace table t (y int); +create or replace table t (z int) engine innodb; unlock tables; alter table mysql.innodb_index_stats modify stat_description varchar(1024) not null; select * from t; -y +z drop table t; set sql_mode= default; # diff --git a/mysql-test/main/create_or_replace.test b/mysql-test/main/create_or_replace.test index b3aa6d38ccd..c9d481de320 100644 --- a/mysql-test/main/create_or_replace.test +++ b/mysql-test/main/create_or_replace.test @@ -708,6 +708,7 @@ insert into t values (77); alter table mysql.innodb_index_stats modify stat_description char(10); lock table t write; create or replace table t (y int); +create or replace table t (z int) engine innodb; # cleanup unlock tables; alter table mysql.innodb_index_stats modify stat_description varchar(1024) not null; diff --git a/sql/debug.cc b/sql/debug.cc index a0e2340e254..5810bafa1b7 100644 --- a/sql/debug.cc +++ b/sql/debug.cc @@ -16,6 +16,7 @@ #include "mariadb.h" #include "sql_class.h" #include "debug.h" +#include <mysql/service_debug_sync.h> /** Debug utility to do crash after a set number of executions @@ -51,6 +52,7 @@ void debug_crash_here(const char *keyword) DBUG_ENTER("debug_crash_here"); DBUG_PRINT("enter", ("keyword: %s", keyword)); + DEBUG_SYNC(current_thd, keyword); DBUG_EXECUTE_IF(keyword, if (debug_decrement_counter(&debug_crash_counter)) { diff --git a/sql/handler.h b/sql/handler.h index 22090143835..088022b434e 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -3256,7 +3256,11 @@ public: bool mark_trx_read_write_done; /* mark_trx_read_write was called */ bool check_table_binlog_row_based_done; /* check_table_binlog.. was called */ bool check_table_binlog_row_based_result; /* cached check_table_binlog... */ - /* + /* + Used to tell the table rename do as much as possible (ignore stats errors). + */ + bool ddl_log_operation; + /* TRUE <=> the engine guarantees that returned records are within the range being scanned. */ @@ -3430,6 +3434,7 @@ public: mark_trx_read_write_done(0), check_table_binlog_row_based_done(0), check_table_binlog_row_based_result(0), + ddl_log_operation(false), in_range_check_pushed_down(FALSE), lookup_errkey(-1), errkey(-1), key_used_on_scan(MAX_KEY), active_index(MAX_KEY), keyread(MAX_KEY), diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 77c4f7a9b48..d54ed5185d5 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4480,7 +4480,7 @@ bool HA_CREATE_INFO::finalize_atomic_replace(THD *thd, TABLE_LIST *orig_table) orig_table->table= NULL; } - param.rename_flags= FN_TO_IS_TMP; + param.rename_flags= FN_TO_IS_TMP | DDL_LOG; param.from_table_hton= old_hton; param.old_version= org_tabledef_version; param.old_alias= lower_case_table_names == 2 ? orig_table->alias : @@ -4545,7 +4545,7 @@ bool HA_CREATE_INFO::finalize_atomic_replace(THD *thd, TABLE_LIST *orig_table) cpath.length= build_table_filename(path, sizeof(path) - 1, db.str, table_name.str, "", 0); - param.rename_flags= FN_FROM_IS_TMP; + param.rename_flags= FN_FROM_IS_TMP | DDL_LOG; param.from_table_hton= db_type; param.old_version= tabledef_version; param.old_alias= tmp_name.table_name; @@ -5642,14 +5642,19 @@ mysql_rename_table(handlerton *base, const LEX_CSTRING *old_db, DBUG_RETURN(TRUE); } - if (file && file->needs_lower_case_filenames()) + if (file) { - build_lower_case_table_filename(lc_from, sizeof(lc_from) -1, - old_db, old_name, flags & FN_FROM_IS_TMP); - build_lower_case_table_filename(lc_to, sizeof(lc_from) -1, - new_db, new_name, flags & FN_TO_IS_TMP); - from_base= lc_from; - to_base= lc_to; + if (file->needs_lower_case_filenames()) + { + build_lower_case_table_filename(lc_from, sizeof(lc_from) -1, + old_db, old_name, flags & FN_FROM_IS_TMP); + build_lower_case_table_filename(lc_to, sizeof(lc_from) -1, + new_db, new_name, flags & FN_TO_IS_TMP); + from_base= lc_from; + to_base= lc_to; + } + if (flags & DDL_LOG) + file->ddl_log_operation= true; } if (flags & NO_HA_TABLE) diff --git a/sql/sql_table.h b/sql/sql_table.h index 5502140babb..98def404cc8 100644 --- a/sql/sql_table.h +++ b/sql/sql_table.h @@ -77,6 +77,8 @@ static const uint SKIP_SYMDIR_ACCESS= 1 << 5; static const uint NO_FK_CHECKS= 1 << 6; /* Don't delete .par table in quick_rm_table() */ static const uint NO_PAR_TABLE= 1 << 7; +/* Tell the file operation to do as much as possible (f.ex. ignore stat errors on rename) */ +static const uint DDL_LOG= 1 << 8; uint filename_to_tablename(const char *from, char *to, size_t to_length, bool stay_quiet = false); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 23daa3293df..9c9bc87b136 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -14136,12 +14136,16 @@ ha_innobase::rename_table( if (error == DB_SUCCESS && table_stats && index_stats) { error = dict_stats_rename_table(norm_from, norm_to, trx); - if (error == DB_DUPLICATE_KEY) { - /* The duplicate may also occur in - mysql.innodb_index_stats. */ - my_error(ER_DUP_KEY, MYF(0), - "mysql.innodb_table_stats"); - error = DB_ERROR; + if (error) { + if (ddl_log_operation) { + error = DB_SUCCESS; + } else if (error == DB_DUPLICATE_KEY) { + /* The duplicate may also occur in + mysql.innodb_index_stats. */ + my_error(ER_DUP_KEY, MYF(0), + "mysql.innodb_table_stats"); + error = DB_ERROR; + } } } |