diff --git a/mysql-test/suite/innodb/r/alter_partitioned_debug.result b/mysql-test/suite/innodb/r/alter_partitioned_debug.result index d2ec602c6d7..29a6e5822c5 100644 --- a/mysql-test/suite/innodb/r/alter_partitioned_debug.result +++ b/mysql-test/suite/innodb/r/alter_partitioned_debug.result @@ -1,4 +1,5 @@ CREATE TABLE t1 (a INT, b VARCHAR(10)) ENGINE=InnoDB +STATS_PERSISTENT=1 STATS_AUTO_RECALC=0 PARTITION BY RANGE(a) (PARTITION pa VALUES LESS THAN (3), PARTITION pb VALUES LESS THAN (5)); @@ -19,9 +20,30 @@ connection ddl; ERROR 23000: Duplicate entry '2-two' for key 'a' connection default; DELETE FROM t1; -disconnect ddl; SET DEBUG_SYNC = 'RESET'; CHECK TABLE t1; Table Op Msg_type Msg_text test.t1 check status OK -DROP TABLE t1; +CREATE TABLE t(a INT, b VARCHAR(10)) ENGINE=InnoDB +STATS_PERSISTENT=1 STATS_AUTO_RECALC=1; +RENAME TABLE t TO u; +DELETE FROM mysql.innodb_table_stats WHERE table_name='u'; +DELETE FROM mysql.innodb_index_stats WHERE table_name='u'; +SET STATEMENT debug_dbug='+d,dict_stats_save_exit_notify_and_wait' FOR +SELECT * FROM u; +connection ddl; +SET DEBUG_SYNC='open_tables_after_open_and_process_table +WAIT_FOR dict_stats_save_finished'; +ALTER TABLE t1 EXCHANGE PARTITION pb WITH TABLE u; +connect sync,localhost,root; +SET DEBUG_SYNC='now SIGNAL dict_stats_save_unblock'; +disconnect sync; +connection default; +a b +connection ddl; +disconnect ddl; +connection default; +SELECT * FROM u; +a b +SET DEBUG_SYNC = 'RESET'; +DROP TABLE t1,u; diff --git a/mysql-test/suite/innodb/t/alter_partitioned_debug.test b/mysql-test/suite/innodb/t/alter_partitioned_debug.test index 34565e12036..cac5f960e01 100644 --- a/mysql-test/suite/innodb/t/alter_partitioned_debug.test +++ b/mysql-test/suite/innodb/t/alter_partitioned_debug.test @@ -4,6 +4,7 @@ --source include/have_debug_sync.inc CREATE TABLE t1 (a INT, b VARCHAR(10)) ENGINE=InnoDB +STATS_PERSISTENT=1 STATS_AUTO_RECALC=0 PARTITION BY RANGE(a) (PARTITION pa VALUES LESS THAN (3), PARTITION pb VALUES LESS THAN (5)); @@ -26,9 +27,46 @@ reap; connection default; DELETE FROM t1; -disconnect ddl; SET DEBUG_SYNC = 'RESET'; CHECK TABLE t1; -DROP TABLE t1; + +CREATE TABLE t(a INT, b VARCHAR(10)) ENGINE=InnoDB +STATS_PERSISTENT=1 STATS_AUTO_RECALC=1; +RENAME TABLE t TO u; +DELETE FROM mysql.innodb_table_stats WHERE table_name='u'; +DELETE FROM mysql.innodb_index_stats WHERE table_name='u'; + +send SET STATEMENT debug_dbug='+d,dict_stats_save_exit_notify_and_wait' FOR +SELECT * FROM u; + +connection ddl; +SET DEBUG_SYNC='open_tables_after_open_and_process_table +WAIT_FOR dict_stats_save_finished'; +send ALTER TABLE t1 EXCHANGE PARTITION pb WITH TABLE u; + +connect sync,localhost,root; +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = 'debug sync point: now' + and info like 'SET STATEMENT debug_dbug%SELECT * FROM u'; +--source include/wait_condition.inc +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = 'Waiting for table metadata lock' + and info like 'ALTER TABLE t1 EXCHANGE PARTITION pb WITH TABLE u'; +--source include/wait_condition.inc +SET DEBUG_SYNC='now SIGNAL dict_stats_save_unblock'; +disconnect sync; + +connection default; +reap; +connection ddl; +reap; +disconnect ddl; +connection default; +SELECT * FROM u; +SET DEBUG_SYNC = 'RESET'; + +DROP TABLE t1,u; diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 9cdc62bc49d..bbfa94e09a8 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -2887,6 +2887,13 @@ dberr_t dict_stats_save(dict_table_t* table, index_id_t index_id) STRING_WITH_LEN("now SIGNAL dict_stats_save_finished")); }); ); + DBUG_EXECUTE_IF("dict_stats_save_exit_notify_and_wait", + SCOPE_EXIT([] { + debug_sync_set_action(current_thd, + STRING_WITH_LEN("now SIGNAL dict_stats_save_finished" + " WAIT_FOR dict_stats_save_unblock")); + }); + ); #endif /* ENABLED_DEBUG_SYNC */ if (high_level_read_only) { diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 427be74e9c3..665661d28c1 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -17424,7 +17424,12 @@ ha_innobase::check_if_incompatible_data( param_new = info->option_struct; param_old = table->s->option_struct; - innobase_copy_frm_flags_from_create_info(m_prebuilt->table, info); + m_prebuilt->table->stats_mutex_lock(); + if (!m_prebuilt->table->stat_initialized()) { + innobase_copy_frm_flags_from_create_info( + m_prebuilt->table, info); + } + m_prebuilt->table->stats_mutex_unlock(); if (table_changes != IS_EQUAL_YES) {