Commit d7e0c3cc authored by Sergei Golubchik's avatar Sergei Golubchik

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.
parent bae5b92a
......@@ -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),
......
......@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment