Commit 9747fbb4 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-4786 merge 10.0-monty -> 10.0

remove TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE
parent eafb11c8
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (
id INT PRIMARY KEY,
a VARCHAR(100),
INDEX(a)
) ENGINE=MyISAM;
ALTER TABLE t1 DISABLE KEYS;
SET debug_sync= 'myisam_before_repair_by_sort SIGNAL waiting WAIT_FOR go';
ALTER TABLE t1 ENABLE KEYS;
SET debug_sync= 'now WAIT_FOR waiting';
SET debug_sync= 'now SIGNAL go';
SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MyISAM 10 Dynamic 100000 27 # # # 0 NULL # # # latin1_swedish_ci NULL
DROP TABLE t1;
#
# Test bugs in MyISAM that may cause problems for metadata
#
--source include/big_test.inc
--source include/have_debug_sync.inc
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
#
# LP:989055 - Querying myisam table metadata may corrupt the table
#
CREATE TABLE t1 (
id INT PRIMARY KEY,
a VARCHAR(100),
INDEX(a)
) ENGINE=MyISAM;
ALTER TABLE t1 DISABLE KEYS;
let $1=100000;
--disable_query_log
while ($1)
{
eval insert into t1 values($1, "line number $1");
dec $1;
}
--enable_query_log
--connect(con1,localhost,root,,)
SET debug_sync= 'myisam_before_repair_by_sort SIGNAL waiting WAIT_FOR go';
send
ALTER TABLE t1 ENABLE KEYS;
--connection default
SET debug_sync= 'now WAIT_FOR waiting';
SET debug_sync= 'now SIGNAL go';
--replace_column 7 # 8 # 9 # 12 # 13 # 14 #
SHOW TABLE STATUS LIKE 't1';
--connection con1
--reap
--connection default
--disconnect con1
DROP TABLE t1;
......@@ -7913,7 +7913,7 @@ static int mysql_init_variables(void)
log_error_file_ptr= log_error_file;
protocol_version= PROTOCOL_VERSION;
what_to_log= ~ (1L << (uint) COM_TIME);
refresh_version= 2L; /* Increments on each reload. 0 and 1 are reserved */
refresh_version= 1L; /* Increments on each reload */
denied_connections= 0;
executed_events= 0;
global_query_id= thread_id= 1L;
......
......@@ -100,7 +100,6 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
const char **ext;
MY_STAT stat_info;
Open_table_context ot_ctx(thd, (MYSQL_OPEN_IGNORE_FLUSH |
MYSQL_OPEN_FOR_REPAIR |
MYSQL_OPEN_HAS_MDL_LOCK |
MYSQL_LOCK_IGNORE_TIMEOUT));
DBUG_ENTER("prepare_for_repair");
......@@ -201,9 +200,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
to close it, but leave it protected by exclusive metadata lock.
*/
pos_in_locked_tables= table->pos_in_locked_tables;
if (wait_while_table_is_used(thd, table,
HA_EXTRA_PREPARE_FOR_FORCED_CLOSE,
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_FORCED_CLOSE))
goto end;
/* Close table but don't remove from locked list */
close_all_tables_for_name(thd, table_list->table->s,
......@@ -608,10 +605,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
*/
if (lock_type == TL_WRITE && !table->table->s->tmp_table)
{
table->table->s->protect_against_usage();
if (wait_while_table_is_used(thd, table->table,
HA_EXTRA_PREPARE_FOR_RENAME,
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
HA_EXTRA_PREPARE_FOR_RENAME))
goto err;
DEBUG_SYNC(thd, "after_admin_flush");
/* Flush entries in the query cache involving this table. */
......
......@@ -1062,7 +1062,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables,
if (share)
{
kill_delayed_threads_for_table(share);
/* tdc_remove_table() calls share->remove_from_cache_at_close() */
/* tdc_remove_table() also sets TABLE_SHARE::version to 0. */
tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED, table->db,
table->table_name, TRUE);
found=1;
......@@ -2333,8 +2333,7 @@ bool rename_temporary_table(THD* thd, TABLE *table, const char *db,
*/
bool wait_while_table_is_used(THD *thd, TABLE *table,
enum ha_extra_function function,
enum_tdc_remove_table_type remove_type)
enum ha_extra_function function)
{
DBUG_ENTER("wait_while_table_is_used");
DBUG_PRINT("enter", ("table: '%s' share: 0x%lx db_stat: %u version: %lu",
......@@ -2346,7 +2345,7 @@ bool wait_while_table_is_used(THD *thd, TABLE *table,
thd->variables.lock_wait_timeout))
DBUG_RETURN(TRUE);
tdc_remove_table(thd, remove_type,
tdc_remove_table(thd, TDC_RT_REMOVE_NOT_OWN,
table->s->db.str, table->s->table_name.str,
FALSE);
/* extra() call must come only after all instances above are closed */
......@@ -2987,8 +2986,7 @@ retry_share:
}
mysql_mutex_lock(&LOCK_open);
if (!(flags & MYSQL_OPEN_IGNORE_FLUSH) ||
(share->protected_against_usage() && !(flags & MYSQL_OPEN_FOR_REPAIR)))
if (!(flags & MYSQL_OPEN_IGNORE_FLUSH))
{
if (share->has_old_version())
{
......@@ -9584,8 +9582,7 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
{
DBUG_ASSERT(share->used_tables.is_empty());
}
else if (remove_type == TDC_RT_REMOVE_NOT_OWN ||
remove_type == TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE)
else if (remove_type == TDC_RT_REMOVE_NOT_OWN)
{
TABLE_SHARE::TABLE_list::Iterator it2(share->used_tables);
while ((table= it2++))
......@@ -9598,8 +9595,8 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
}
#endif
/*
Mark share to ensure that it gets automatically deleted once
it is no longer referenced.
Set share's version to zero in order to ensure that it gets
automatically deleted once it is no longer referenced.
Note that code in TABLE_SHARE::wait_for_old_version() assumes
that marking share as old and removal of its unused tables
......@@ -9608,13 +9605,8 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
TDC does not contain old shares which don't have any tables
used.
*/
if (remove_type == TDC_RT_REMOVE_NOT_OWN)
share->remove_from_cache_at_close();
else if (remove_type != TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE)
{
/* Ensure that no can open the table while it's used */
share->protect_against_usage();
}
if (remove_type != TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE)
share->version= 0;
while ((table= it++))
free_cache_entry(table);
......
......@@ -61,7 +61,6 @@ enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
enum enum_tdc_remove_table_type {TDC_RT_REMOVE_ALL, TDC_RT_REMOVE_NOT_OWN,
TDC_RT_REMOVE_UNUSED,
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE,
TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE};
/* bits for last argument to remove_table_from_cache() */
......@@ -187,7 +186,6 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
*/
#define MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK 0x1000
#define MYSQL_LOCK_NOT_TEMPORARY 0x2000
#define MYSQL_OPEN_FOR_REPAIR 0x4000
/**
Only check THD::killed if waits happen (e.g. wait on MDL, wait on
table flush, wait on thr_lock.c locks) while opening and locking table.
......@@ -297,9 +295,7 @@ bool setup_tables_and_check_access(THD *thd,
ulong want_access,
bool full_table_list);
bool wait_while_table_is_used(THD *thd, TABLE *table,
enum ha_extra_function function,
enum_tdc_remove_table_type remove_type=
TDC_RT_REMOVE_NOT_OWN);
enum ha_extra_function function);
void drop_open_table(THD *thd, TABLE *table, const char *db_name,
const char *table_name);
......
......@@ -2446,8 +2446,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
if (thd->locked_tables_mode)
{
if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED,
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED))
{
error= -1;
goto err;
......
......@@ -369,8 +369,7 @@ bool Sql_cmd_truncate_table::lock_table(THD *thd, TABLE_LIST *table_ref,
{
DEBUG_SYNC(thd, "upgrade_lock_for_truncate");
/* To remove the table from the cache we need an exclusive lock. */
if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DROP,
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DROP))
DBUG_RETURN(TRUE);
m_ticket_downgrade= table->mdl_ticket;
/* Close if table is going to be recreated. */
......
......@@ -318,7 +318,7 @@ TABLE_SHARE *alloc_table_share(const char *db, const char *table_name,
/* TEMPORARY FIX: if true, this means this is mysql.gtid_slave_pos table */
share->is_gtid_slave_pos= FALSE;
share->table_category= get_table_category(& share->db, & share->table_name);
share->set_refresh_version();
share->version= refresh_version;
share->open_errno= ENOENT;
/*
......
......@@ -837,36 +837,6 @@ struct TABLE_SHARE
{
return version != refresh_version;
}
inline bool protected_against_usage() const
{
return version == 0;
}
inline void protect_against_usage()
{
version= 0;
}
/*
This is used only for the case of locked tables, as we want to
allow one to do SHOW commands on them even after ALTER or REPAIR
*/
inline void allow_access_to_protected_table()
{
DBUG_ASSERT(version == 0);
version= 1;
}
/*
Remove from table definition cache at close.
Table can still be opened by SHOW
*/
inline void remove_from_cache_at_close()
{
if (version != 0) /* Don't remove protection */
version= 1;
}
inline void set_refresh_version()
{
version= refresh_version;
}
/**
Convert unrelated members of TABLE_SHARE to one enum
......
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