diff --git a/mysql-test/suite/archive/discover.result b/mysql-test/suite/archive/discover.result index dc71eca8a40..4701d70273b 100644 --- a/mysql-test/suite/archive/discover.result +++ b/mysql-test/suite/archive/discover.result @@ -124,3 +124,9 @@ drop table `a/../`; create database test1; create table test1.t1 (i int) engine=archive; drop database test1; +create table t1 (a int) engine=archive; +select * from t1; +a +flush tables; +select * from t1; +ERROR 42S02: Table 'test.t1' doesn't exist diff --git a/mysql-test/suite/archive/discover.test b/mysql-test/suite/archive/discover.test index c0f7c31725b..ad53ffa78c8 100644 --- a/mysql-test/suite/archive/discover.test +++ b/mysql-test/suite/archive/discover.test @@ -107,3 +107,14 @@ create database test1; create table test1.t1 (i int) engine=archive; drop database test1; +# +# MDEV-4456 Reverse discovery of ARCHIVE table on SELECT after disappearance of ARZ file +# +create table t1 (a int) engine=archive; +select * from t1; +flush tables; +remove_file $mysqld_datadir/test/t1.ARZ; +--error ER_NO_SUCH_TABLE +select * from t1; +--list_files $mysqld_datadir/test + diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 109a4ef41e9..63733d00c43 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -632,10 +632,8 @@ TABLE_SHARE *get_table_share(THD *thd, const char *db, const char *table_name, mysql_mutex_lock(&share->LOCK_ha_data); mysql_mutex_unlock(&LOCK_open); - if (flags & GTS_FORCE_DISCOVERY) - ha_discover_table(thd, share); // don't read the frm at all - else - open_table_def(thd, share, flags | GTS_FORCE_DISCOVERY); // frm or discover + /* note that get_table_share() *always* uses discovery */ + open_table_def(thd, share, flags | GTS_USE_DISCOVERY); mysql_mutex_unlock(&share->LOCK_ha_data); mysql_mutex_lock(&LOCK_open); @@ -3992,15 +3990,16 @@ recover_from_failed_open(THD *thd) tdc_remove_table(thd, TDC_RT_REMOVE_ALL, m_failed_table->db, m_failed_table->table_name, FALSE); + + thd->warning_info->clear_warning_info(thd->query_id); + thd->clear_error(); // Clear error message + if ((result= !get_table_share(thd, m_failed_table->db, m_failed_table->table_name, GTS_TABLE | GTS_FORCE_DISCOVERY | GTS_NOLOCK))) break; - - thd->warning_info->clear_warning_info(thd->query_id); - thd->clear_error(); // Clear error message thd->mdl_context.release_transactional_locks(); break; } @@ -5967,7 +5966,7 @@ TABLE *open_table_uncached(THD *thd, handlerton *hton, strend(saved_cache_key)+1, tmp_path); share->db_plugin= ha_lock_engine(thd, hton); - if (open_table_def(thd, share, GTS_TABLE | GTS_FORCE_DISCOVERY) || + if (open_table_def(thd, share, GTS_TABLE | GTS_USE_DISCOVERY) || open_table_from_share(thd, share, table_name, (uint) (HA_OPEN_KEYFILE | HA_OPEN_RNDFILE | HA_GET_INDEX), diff --git a/sql/table.cc b/sql/table.cc index dab76723b4e..8cb4f26c429 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -606,10 +606,19 @@ enum open_frm_error open_table_def(THD *thd, TABLE_SHARE *share, uint flags) share->error= OPEN_FRM_OPEN_ERROR; strxmov(path, share->normalized_path.str, reg_ext, NullS); - file= mysql_file_open(key_file_frm, path, O_RDONLY | O_SHARE, MYF(0)); + if (flags & GTS_FORCE_DISCOVERY) + { + DBUG_ASSERT(flags & GTS_TABLE); + DBUG_ASSERT(flags & GTS_USE_DISCOVERY); + mysql_file_delete_with_symlink(key_file_frm, path, MYF(0)); + file= -1; + } + else + file= mysql_file_open(key_file_frm, path, O_RDONLY | O_SHARE, MYF(0)); + if (file < 0) { - if ((flags & GTS_TABLE) && (flags & GTS_FORCE_DISCOVERY)) + if ((flags & GTS_TABLE) && (flags & GTS_USE_DISCOVERY)) { ha_discover_table(thd, share); error_given= true; @@ -2803,8 +2812,22 @@ partititon_err: !(ha_open_flags & HA_OPEN_FOR_REPAIR)); outparam->file->print_error(ha_err, MYF(0)); error_reported= TRUE; + if (ha_err == HA_ERR_TABLE_DEF_CHANGED) error= OPEN_FRM_DISCOVER; + + /* + We're here, because .frm file was successfully opened. + + But if the table doesn't exist in the engine and the engine + supports discovery, we force rediscover to discover + the fact that table doesn't in fact exist and remove + the stray .frm file. + */ + if (share->db_type()->discover_table && + (ha_err == ENOENT || ha_err == HA_ERR_NO_SUCH_TABLE)) + error= OPEN_FRM_DISCOVER; + goto err; } } diff --git a/sql/table.h b/sql/table.h index 068cbe9a763..c7282cee093 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2495,7 +2495,8 @@ enum get_table_share_flags { GTS_TABLE = 1, GTS_VIEW = 2, GTS_NOLOCK = 4, - GTS_FORCE_DISCOVERY = 8 + GTS_USE_DISCOVERY = 8, + GTS_FORCE_DISCOVERY = 16 }; size_t max_row_length(TABLE *table, const uchar *data);