MDEV-4456 Reverse discovery of ARCHIVE table on SELECT after disappearance of ARZ file
Implement discovery of table non-existence, and related changes: 1. Split GTS_FORCE_DISCOVERY (that was meaning two different things in two different functions) into GTS_FORCE_DISCOVERY and GTS_USE_DISCOVERY. 2. Move GTS_FORCE_DISCOVERY implementation into open_table_def(). 3. In recover_from_failed_open() clear old errors *before* discovery, not after successful discovery. The final error should come from the discovery. 4. On forced discovery delete table .frm first. Discovery will write a new one, if desired. 5. If the frm file exists, but not the table in the engine, force rediscovery if the engine supports it.
This commit is contained in:
parent
bae5b92ae6
commit
d7e0c3cc73
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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),
|
||||
|
27
sql/table.cc
27
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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user