MDEV-4786 merge 10.0-monty -> 10.0
remove TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE
This commit is contained in:
parent
eafb11c821
commit
9747fbb411
@ -1,15 +0,0 @@
|
|||||||
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;
|
|
@ -1,48 +0,0 @@
|
|||||||
#
|
|
||||||
# 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;
|
log_error_file_ptr= log_error_file;
|
||||||
protocol_version= PROTOCOL_VERSION;
|
protocol_version= PROTOCOL_VERSION;
|
||||||
what_to_log= ~ (1L << (uint) COM_TIME);
|
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;
|
denied_connections= 0;
|
||||||
executed_events= 0;
|
executed_events= 0;
|
||||||
global_query_id= thread_id= 1L;
|
global_query_id= thread_id= 1L;
|
||||||
|
@ -100,7 +100,6 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
|||||||
const char **ext;
|
const char **ext;
|
||||||
MY_STAT stat_info;
|
MY_STAT stat_info;
|
||||||
Open_table_context ot_ctx(thd, (MYSQL_OPEN_IGNORE_FLUSH |
|
Open_table_context ot_ctx(thd, (MYSQL_OPEN_IGNORE_FLUSH |
|
||||||
MYSQL_OPEN_FOR_REPAIR |
|
|
||||||
MYSQL_OPEN_HAS_MDL_LOCK |
|
MYSQL_OPEN_HAS_MDL_LOCK |
|
||||||
MYSQL_LOCK_IGNORE_TIMEOUT));
|
MYSQL_LOCK_IGNORE_TIMEOUT));
|
||||||
DBUG_ENTER("prepare_for_repair");
|
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.
|
to close it, but leave it protected by exclusive metadata lock.
|
||||||
*/
|
*/
|
||||||
pos_in_locked_tables= table->pos_in_locked_tables;
|
pos_in_locked_tables= table->pos_in_locked_tables;
|
||||||
if (wait_while_table_is_used(thd, table,
|
if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_FORCED_CLOSE))
|
||||||
HA_EXTRA_PREPARE_FOR_FORCED_CLOSE,
|
|
||||||
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
|
|
||||||
goto end;
|
goto end;
|
||||||
/* Close table but don't remove from locked list */
|
/* Close table but don't remove from locked list */
|
||||||
close_all_tables_for_name(thd, table_list->table->s,
|
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)
|
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,
|
if (wait_while_table_is_used(thd, table->table,
|
||||||
HA_EXTRA_PREPARE_FOR_RENAME,
|
HA_EXTRA_PREPARE_FOR_RENAME))
|
||||||
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
|
|
||||||
goto err;
|
goto err;
|
||||||
DEBUG_SYNC(thd, "after_admin_flush");
|
DEBUG_SYNC(thd, "after_admin_flush");
|
||||||
/* Flush entries in the query cache involving this table. */
|
/* Flush entries in the query cache involving this table. */
|
||||||
|
@ -1062,7 +1062,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables,
|
|||||||
if (share)
|
if (share)
|
||||||
{
|
{
|
||||||
kill_delayed_threads_for_table(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,
|
tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED, table->db,
|
||||||
table->table_name, TRUE);
|
table->table_name, TRUE);
|
||||||
found=1;
|
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,
|
bool wait_while_table_is_used(THD *thd, TABLE *table,
|
||||||
enum ha_extra_function function,
|
enum ha_extra_function function)
|
||||||
enum_tdc_remove_table_type remove_type)
|
|
||||||
{
|
{
|
||||||
DBUG_ENTER("wait_while_table_is_used");
|
DBUG_ENTER("wait_while_table_is_used");
|
||||||
DBUG_PRINT("enter", ("table: '%s' share: 0x%lx db_stat: %u version: %lu",
|
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))
|
thd->variables.lock_wait_timeout))
|
||||||
DBUG_RETURN(TRUE);
|
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,
|
table->s->db.str, table->s->table_name.str,
|
||||||
FALSE);
|
FALSE);
|
||||||
/* extra() call must come only after all instances above are closed */
|
/* extra() call must come only after all instances above are closed */
|
||||||
@ -2987,8 +2986,7 @@ retry_share:
|
|||||||
}
|
}
|
||||||
|
|
||||||
mysql_mutex_lock(&LOCK_open);
|
mysql_mutex_lock(&LOCK_open);
|
||||||
if (!(flags & MYSQL_OPEN_IGNORE_FLUSH) ||
|
if (!(flags & MYSQL_OPEN_IGNORE_FLUSH))
|
||||||
(share->protected_against_usage() && !(flags & MYSQL_OPEN_FOR_REPAIR)))
|
|
||||||
{
|
{
|
||||||
if (share->has_old_version())
|
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());
|
DBUG_ASSERT(share->used_tables.is_empty());
|
||||||
}
|
}
|
||||||
else if (remove_type == TDC_RT_REMOVE_NOT_OWN ||
|
else if (remove_type == TDC_RT_REMOVE_NOT_OWN)
|
||||||
remove_type == TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE)
|
|
||||||
{
|
{
|
||||||
TABLE_SHARE::TABLE_list::Iterator it2(share->used_tables);
|
TABLE_SHARE::TABLE_list::Iterator it2(share->used_tables);
|
||||||
while ((table= it2++))
|
while ((table= it2++))
|
||||||
@ -9598,8 +9595,8 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
Mark share to ensure that it gets automatically deleted once
|
Set share's version to zero in order to ensure that it gets
|
||||||
it is no longer referenced.
|
automatically deleted once it is no longer referenced.
|
||||||
|
|
||||||
Note that code in TABLE_SHARE::wait_for_old_version() assumes
|
Note that code in TABLE_SHARE::wait_for_old_version() assumes
|
||||||
that marking share as old and removal of its unused tables
|
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
|
TDC does not contain old shares which don't have any tables
|
||||||
used.
|
used.
|
||||||
*/
|
*/
|
||||||
if (remove_type == TDC_RT_REMOVE_NOT_OWN)
|
if (remove_type != TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE)
|
||||||
share->remove_from_cache_at_close();
|
share->version= 0;
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((table= it++))
|
while ((table= it++))
|
||||||
free_cache_entry(table);
|
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,
|
enum enum_tdc_remove_table_type {TDC_RT_REMOVE_ALL, TDC_RT_REMOVE_NOT_OWN,
|
||||||
TDC_RT_REMOVE_UNUSED,
|
TDC_RT_REMOVE_UNUSED,
|
||||||
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE,
|
|
||||||
TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE};
|
TDC_RT_REMOVE_NOT_OWN_KEEP_SHARE};
|
||||||
|
|
||||||
/* bits for last argument to remove_table_from_cache() */
|
/* 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_OPEN_SKIP_SCOPED_MDL_LOCK 0x1000
|
||||||
#define MYSQL_LOCK_NOT_TEMPORARY 0x2000
|
#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
|
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.
|
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,
|
ulong want_access,
|
||||||
bool full_table_list);
|
bool full_table_list);
|
||||||
bool wait_while_table_is_used(THD *thd, TABLE *table,
|
bool wait_while_table_is_used(THD *thd, TABLE *table,
|
||||||
enum ha_extra_function function,
|
enum ha_extra_function function);
|
||||||
enum_tdc_remove_table_type remove_type=
|
|
||||||
TDC_RT_REMOVE_NOT_OWN);
|
|
||||||
|
|
||||||
void drop_open_table(THD *thd, TABLE *table, const char *db_name,
|
void drop_open_table(THD *thd, TABLE *table, const char *db_name,
|
||||||
const char *table_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 (thd->locked_tables_mode)
|
||||||
{
|
{
|
||||||
if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED,
|
if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED))
|
||||||
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
|
|
||||||
{
|
{
|
||||||
error= -1;
|
error= -1;
|
||||||
goto err;
|
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");
|
DEBUG_SYNC(thd, "upgrade_lock_for_truncate");
|
||||||
/* To remove the table from the cache we need an exclusive lock. */
|
/* 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,
|
if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DROP))
|
||||||
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
|
|
||||||
DBUG_RETURN(TRUE);
|
DBUG_RETURN(TRUE);
|
||||||
m_ticket_downgrade= table->mdl_ticket;
|
m_ticket_downgrade= table->mdl_ticket;
|
||||||
/* Close if table is going to be recreated. */
|
/* 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 */
|
/* TEMPORARY FIX: if true, this means this is mysql.gtid_slave_pos table */
|
||||||
share->is_gtid_slave_pos= FALSE;
|
share->is_gtid_slave_pos= FALSE;
|
||||||
share->table_category= get_table_category(& share->db, & share->table_name);
|
share->table_category= get_table_category(& share->db, & share->table_name);
|
||||||
share->set_refresh_version();
|
share->version= refresh_version;
|
||||||
share->open_errno= ENOENT;
|
share->open_errno= ENOENT;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
30
sql/table.h
30
sql/table.h
@ -837,36 +837,6 @@ struct TABLE_SHARE
|
|||||||
{
|
{
|
||||||
return version != refresh_version;
|
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
|
Convert unrelated members of TABLE_SHARE to one enum
|
||||||
|
Loading…
x
Reference in New Issue
Block a user