mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Fixed bug LP:973039 - Assertion `share->in_trans == 0' failed in maria_close on DROP TABLE under LOCK
- 5.5 was missing calls to ha_extra(HA_PREPARE_FOR_DROP | HA_PREPARE_FOR_RENAME); Lost in merge 5.3 -> 5.5 sql/sql_admin.cc: Updated arguments for close_all_tables_for_name sql/sql_base.h: Updated arguments for close_all_tables_for_name sql/sql_partition.cc: Updated arguments for close_all_tables_for_name sql/sql_table.cc: Updated arguments for close_all_tables_for_name Removed test of kill, as we have already called 'ha_extra(HA_PREPARE_FOR_DROP)' and the table may be inconsistent. sql/sql_trigger.cc: Updated arguments for close_all_tables_for_name sql/sql_truncate.cc: For truncate that is done with drop + recreate, signal that the table will be dropped.
This commit is contained in:
10
mysql-test/suite/maria/lock.result
Normal file
10
mysql-test/suite/maria/lock.result
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
drop table if exists t1,t2;
|
||||||
|
Warnings:
|
||||||
|
Note 1051 Unknown table 't1'
|
||||||
|
Note 1051 Unknown table 't2'
|
||||||
|
CREATE TABLE t1 (i INT) ENGINE=Aria;
|
||||||
|
CREATE TABLE t2 (i INT) ENGINE=Aria;
|
||||||
|
LOCK TABLE t1 WRITE, t2 WRITE;
|
||||||
|
DROP TABLE t1;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
DROP TABLE t2;
|
21
mysql-test/suite/maria/lock.test
Normal file
21
mysql-test/suite/maria/lock.test
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#
|
||||||
|
# Testing of potential problems in Aria with locking
|
||||||
|
#
|
||||||
|
|
||||||
|
-- source include/have_maria.inc
|
||||||
|
|
||||||
|
drop table if exists t1,t2;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Test for Bug#973039
|
||||||
|
# Assertion `share->in_trans == 0' failed in maria_close on DROP TABLE
|
||||||
|
# under LOCK
|
||||||
|
#
|
||||||
|
|
||||||
|
CREATE TABLE t1 (i INT) ENGINE=Aria;
|
||||||
|
CREATE TABLE t2 (i INT) ENGINE=Aria;
|
||||||
|
LOCK TABLE t1 WRITE, t2 WRITE;
|
||||||
|
# Also fails with FLUSH TABLE t1 and with REPAIR TABLE t1 USE_FRM
|
||||||
|
DROP TABLE t1;
|
||||||
|
UNLOCK TABLES;
|
||||||
|
DROP TABLE t2;
|
@ -196,7 +196,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
|||||||
*/
|
*/
|
||||||
if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
|
if (wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN))
|
||||||
goto end;
|
goto end;
|
||||||
close_all_tables_for_name(thd, table_list->table->s, FALSE);
|
close_all_tables_for_name(thd, table_list->table->s, HA_EXTRA_NORMAL);
|
||||||
table_list->table= 0;
|
table_list->table= 0;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -1116,7 +1116,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables,
|
|||||||
result= TRUE;
|
result= TRUE;
|
||||||
goto err_with_reopen;
|
goto err_with_reopen;
|
||||||
}
|
}
|
||||||
close_all_tables_for_name(thd, table->s, FALSE);
|
close_all_tables_for_name(thd, table->s, HA_EXTRA_NORMAL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1393,7 +1393,7 @@ static void close_open_tables(THD *thd)
|
|||||||
|
|
||||||
void
|
void
|
||||||
close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
|
close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
|
||||||
bool remove_from_locked_tables)
|
ha_extra_function extra)
|
||||||
{
|
{
|
||||||
char key[MAX_DBKEY_LENGTH];
|
char key[MAX_DBKEY_LENGTH];
|
||||||
uint key_length= share->table_cache_key.length;
|
uint key_length= share->table_cache_key.length;
|
||||||
@ -1412,19 +1412,17 @@ close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
|
|||||||
{
|
{
|
||||||
thd->locked_tables_list.unlink_from_list(thd,
|
thd->locked_tables_list.unlink_from_list(thd,
|
||||||
table->pos_in_locked_tables,
|
table->pos_in_locked_tables,
|
||||||
remove_from_locked_tables);
|
extra != HA_EXTRA_NORMAL);
|
||||||
|
/* Inform handler that there is a drop table or rename going on */
|
||||||
|
if (extra != HA_EXTRA_NORMAL && table->db_stat)
|
||||||
|
table->file->extra(extra);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Does nothing if the table is not locked.
|
Does nothing if the table is not locked.
|
||||||
This allows one to use this function after a table
|
This allows one to use this function after a table
|
||||||
has been unlocked, e.g. in partition management.
|
has been unlocked, e.g. in partition management.
|
||||||
*/
|
*/
|
||||||
mysql_lock_remove(thd, thd->lock, table);
|
mysql_lock_remove(thd, thd->lock, table);
|
||||||
|
|
||||||
/* Inform handler that table will be dropped after close */
|
|
||||||
#ifdef MERGE_FOR_MONTY_TO_FIX
|
|
||||||
if (remove_from_locked_tables && table->db_stat) /* Not true for partitioned tables. */
|
|
||||||
table->file->extra(HA_EXTRA_PREPARE_FOR_DROP);
|
|
||||||
#endif
|
|
||||||
close_thread_table(thd, prev);
|
close_thread_table(thd, prev);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -289,7 +289,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables,
|
|||||||
bool wait_for_refresh, ulong timeout);
|
bool wait_for_refresh, ulong timeout);
|
||||||
bool close_cached_connection_tables(THD *thd, LEX_STRING *connect_string);
|
bool close_cached_connection_tables(THD *thd, LEX_STRING *connect_string);
|
||||||
void close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
|
void close_all_tables_for_name(THD *thd, TABLE_SHARE *share,
|
||||||
bool remove_from_locked_tables);
|
ha_extra_function extra);
|
||||||
OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild);
|
OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild);
|
||||||
void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
|
void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
|
||||||
const char *db, const char *table_name,
|
const char *db, const char *table_name,
|
||||||
|
@ -6270,7 +6270,7 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt)
|
|||||||
THD *thd= lpt->thd;
|
THD *thd= lpt->thd;
|
||||||
|
|
||||||
if (lpt->old_table)
|
if (lpt->old_table)
|
||||||
close_all_tables_for_name(thd, lpt->old_table->s, FALSE);
|
close_all_tables_for_name(thd, lpt->old_table->s, HA_EXTRA_NORMAL);
|
||||||
if (lpt->table)
|
if (lpt->table)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@ -6307,7 +6307,7 @@ static int alter_close_tables(ALTER_PARTITION_PARAM_TYPE *lpt, bool close_old)
|
|||||||
}
|
}
|
||||||
if (close_old && lpt->old_table)
|
if (close_old && lpt->old_table)
|
||||||
{
|
{
|
||||||
close_all_tables_for_name(lpt->thd, lpt->old_table->s, FALSE);
|
close_all_tables_for_name(lpt->thd, lpt->old_table->s, HA_EXTRA_NORMAL);
|
||||||
lpt->old_table= 0;
|
lpt->old_table= 0;
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
@ -2126,7 +2126,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
error= -1;
|
error= -1;
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
close_all_tables_for_name(thd, table->table->s, TRUE);
|
close_all_tables_for_name(thd, table->table->s,
|
||||||
|
HA_EXTRA_PREPARE_FOR_DROP);
|
||||||
table->table= 0;
|
table->table= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2134,11 +2135,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
|||||||
DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db,
|
DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db,
|
||||||
table->table_name,
|
table->table_name,
|
||||||
MDL_EXCLUSIVE));
|
MDL_EXCLUSIVE));
|
||||||
if (thd->killed)
|
|
||||||
{
|
|
||||||
error= -1;
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
alias= (lower_case_table_names == 2) ? table->alias : table->table_name;
|
alias= (lower_case_table_names == 2) ? table->alias : table->table_name;
|
||||||
/* remove .frm file and engine files */
|
/* remove .frm file and engine files */
|
||||||
path_length= build_table_filename(path, sizeof(path) - 1, db, alias,
|
path_length= build_table_filename(path, sizeof(path) - 1, db, alias,
|
||||||
@ -6188,7 +6185,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
*/
|
*/
|
||||||
if (wait_while_table_is_used(thd, table, extra_func))
|
if (wait_while_table_is_used(thd, table, extra_func))
|
||||||
goto err;
|
goto err;
|
||||||
close_all_tables_for_name(thd, table->s, TRUE);
|
close_all_tables_for_name(thd, table->s, HA_EXTRA_PREPARE_FOR_RENAME);
|
||||||
/*
|
/*
|
||||||
Then, we want check once again that target table does not exist.
|
Then, we want check once again that target table does not exist.
|
||||||
Actually the order of these two steps does not matter since
|
Actually the order of these two steps does not matter since
|
||||||
@ -6895,7 +6892,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
close_all_tables_for_name(thd, table->s,
|
close_all_tables_for_name(thd, table->s,
|
||||||
new_name != table_name || new_db != db);
|
new_name != table_name || new_db != db ?
|
||||||
|
HA_EXTRA_PREPARE_FOR_RENAME :
|
||||||
|
HA_EXTRA_NORMAL);
|
||||||
|
|
||||||
error=0;
|
error=0;
|
||||||
table_list->table= table= 0; /* Safety */
|
table_list->table= table= 0; /* Safety */
|
||||||
|
@ -561,7 +561,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create)
|
|||||||
if (result)
|
if (result)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
close_all_tables_for_name(thd, table->s, FALSE);
|
close_all_tables_for_name(thd, table->s, HA_EXTRA_NORMAL);
|
||||||
/*
|
/*
|
||||||
Reopen the table if we were under LOCK TABLES.
|
Reopen the table if we were under LOCK TABLES.
|
||||||
Ignore the return value for now. It's better to
|
Ignore the return value for now. It's better to
|
||||||
|
@ -363,7 +363,7 @@ bool Truncate_statement::lock_table(THD *thd, TABLE_LIST *table_ref,
|
|||||||
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. */
|
||||||
if (*hton_can_recreate)
|
if (*hton_can_recreate)
|
||||||
close_all_tables_for_name(thd, table->s, FALSE);
|
close_all_tables_for_name(thd, table->s, HA_EXTRA_PREPARE_FOR_DROP);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user