#At file:///home/dlenev/src/bzr/mysql-6.1-mil14/ based on revid:dlenev@stripped
2737 Dmitry Lenev 2009-05-22
Milestone 14 "DDL checks and changes: DROP, TRUNCATE, RENAME".
After-review fixes in progress.
Get rid of unnecessary allocation of metadata lock requests.
To achieve this instead of using TABLE_LIST::mdl_request pointer
as indication that table which was dropped was a temporary table
we use bool member in newly introduce Drop_table_rcontext class.
modified:
sql/ha_ndbcluster.cc
sql/sql_db.cc
sql/sql_table.cc
sql/table.h
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2009-04-22 22:12:25 +0000
+++ b/sql/ha_ndbcluster.cc 2009-05-22 09:50:20 +0000
@@ -7597,9 +7597,12 @@ int ndbcluster_find_files(handlerton *ht
DBUG_PRINT("info", ("Remove table %s/%s", db, file_name_str));
// Delete the table and all related files
TABLE_LIST table_list;
+ MDL_request mdl_request;
bzero((char*) &table_list,sizeof(table_list));
table_list.db= (char*) db;
table_list.alias= table_list.table_name= (char*)file_name_str;
+ mdl_request.init(0, db, file_name_str);
+ table_list.mdl_request= &mdl_request;
/*
set TNO_NO_NDB_DROP_TABLE flag to not drop ndb table.
it should not exist anyways
=== modified file 'sql/sql_db.cc'
--- a/sql/sql_db.cc 2009-05-05 12:58:43 +0000
+++ b/sql/sql_db.cc 2009-05-22 09:50:20 +0000
@@ -1162,6 +1162,9 @@ static long mysql_rm_known_files(THD *th
table_list->alias= table_list->table_name; // If lower_case_table_names=2
table_list->internal_tmp_table= is_prefix(file->name, tmp_file_prefix);
+ table_list->mdl_request= MDL_request::create(0, table_list->db,
+ table_list->table_name,
+ thd->mem_root);
/* Link into list */
(*tot_list_next)= table_list;
tot_list_next= &table_list->next_local;
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2009-05-21 07:08:15 +0000
+++ b/sql/sql_table.cc 2009-05-22 09:50:20 +0000
@@ -1748,6 +1748,33 @@ static bool fk_drop_table_add_parent_tab
/**
+ Context carrying information about table being dropped for the whole
+ duration of DROP TABLE/DROP DATABASE operation.
+*/
+
+class Drop_table_rcontext: public Sql_alloc
+{
+public:
+
+ Drop_table_rcontext()
+ : table_type(NULL), is_temporary(FALSE)
+ {}
+
+ /**
+ Engine for table being dropped. NULL - if we don't know yet
+ what the table's engine is.
+ */
+ handlerton *table_type;
+ /**
+ Indicates that there is a temporary table which matches table
+ name specified in the statement and which is going to be dropped
+ as result.
+ */
+ bool is_temporary;
+};
+
+
+/**
Runtime context for changes performed by DDL statement on a table
which participates in foreign key constraints.
@@ -1961,7 +1988,7 @@ Foreign_key_ddl_rcontext::prepare_drop_t
is a temporary table which shadows it and gets dropped instead of it)
it must present among additionally locked tables.
*/
- if (! tab || ! tab->mdl_request)
+ if (! tab || tab->drop_table_rctx->is_temporary)
tab= find_table_in_local_list(all_parent_tables,
fk_s->parent_table_db.str,
fk_s->parent_table_name.str);
@@ -2020,7 +2047,7 @@ Foreign_key_ddl_rcontext::prepare_drop_t
fk_s_p->child_table_db.str,
fk_s_p->child_table_name.str);
- if (! tab || ! tab->mdl_request)
+ if (! tab || tab->drop_table_rctx->is_temporary)
tab= find_table_in_local_list(all_parent_tables,
fk_s_p->child_table_db.str,
fk_s_p->child_table_name.str);
@@ -2190,24 +2217,10 @@ lock_dropped_and_parent_tables(THD *thd,
for (table= tables; table; table= table->next_local)
{
- if (! table->table)
+ if (! table->drop_table_rctx->is_temporary)
{
- /*
- QQ: Ideally we should get rid of allocation here. But this can be
- problematic due to fact that we set TABLE_LIST::mdl_lock_data
- to 0 for temporary tables and rely on that (think of
- re-execution). Any other ideas?
- */
- if (! (mdl_request= MDL_request::create(0, table->db,
- table->table_name,
- thd->mem_root)))
- {
- thd->mdl_context.remove_all_requests();
- return TRUE;
- }
- mdl_request->set_type(MDL_EXCLUSIVE);
- thd->mdl_context.add_request(mdl_request);
- table->mdl_request= mdl_request;
+ table->mdl_request->set_type(MDL_EXCLUSIVE);
+ thd->mdl_context.add_request(table->mdl_request);
}
}
@@ -2260,7 +2273,7 @@ upgrade_mdl_for_dropped_and_parent_table
/* Upgrade meta-data locks for all tables to be dropped. */
for (table= tables; table; table= table->next_local)
{
- if (table->table->s->tmp_table == NO_TMP_TABLE)
+ if (! table->drop_table_rctx->is_temporary)
{
if (wait_while_table_is_used(thd, table->table, HA_EXTRA_FORCE_REOPEN))
{
@@ -2332,12 +2345,13 @@ upgrade_mdl_for_dropped_and_parent_table
*/
static bool
-fk_check_tables_before_drop(THD *thd, TABLE_LIST *tables,
+fk_check_tables_before_drop(THD *thd,
+ TABLE_LIST *tables,
TABLE_LIST **parents_to_lock,
List<Foreign_key_name> *fk_names_to_lock,
bool *has_not_locked_parent_or_fk_name)
{
- TABLE_LIST *table;
+ TABLE_LIST *table, *tab;
TABLE_SHARE *share;
char key[MAX_DBKEY_LENGTH];
uint key_length;
@@ -2352,7 +2366,7 @@ fk_check_tables_before_drop(THD *thd, TA
for (table= tables; table; table= table->next_local)
{
/* Skip this table if it is a temporary table. */
- if (table->table)
+ if (table->drop_table_rctx->is_temporary)
continue;
/*
@@ -2406,8 +2420,9 @@ fk_check_tables_before_drop(THD *thd, TA
*/
while ((fk_p_s= fkeys_p_it++))
{
- if (! find_table_in_local_list(tables, fk_p_s->child_table_db.str,
- fk_p_s->child_table_name.str))
+ if (! (tab= find_table_in_local_list(tables, fk_p_s->child_table_db.str,
+ fk_p_s->child_table_name.str)) ||
+ tab->drop_table_rctx->is_temporary)
{
my_error(ER_FK_CHILD_TABLE_EXISTS, MYF(0), fk_p_s->name.str,
thd->lex->sql_command == SQLCOM_DROP_DB ? "DROP DATABASE" :
@@ -2486,7 +2501,6 @@ fk_check_tables_before_drop(THD *thd, TA
child_table_db,
fk_c_s->name)) ||
fk_names_to_lock->push_back(fk_name, thd->mem_root)))
-
{
pthread_mutex_lock(&LOCK_open);
release_table_share(share);
@@ -2529,14 +2543,14 @@ fk_check_tables_before_drop(THD *thd,
TABLE_LIST *tables, TABLE_LIST **parents_locked,
List<Foreign_key_name> *fk_names_locked)
{
- TABLE_LIST *table;
+ TABLE_LIST *table, *tab;
TABLE_SHARE *share;
Foreign_key_name *fk_name;
for (table= tables; table; table= table->next_local)
{
/* Skip this table if it is a temporary table. */
- if (table->table->s->tmp_table != NO_TMP_TABLE)
+ if (table->drop_table_rctx->is_temporary)
continue;
share= table->table->s;
@@ -2547,8 +2561,9 @@ fk_check_tables_before_drop(THD *thd,
while ((fk_p_s= fkeys_p_it++))
{
- if (! find_table_in_local_list(tables, fk_p_s->child_table_db.str,
- fk_p_s->child_table_name.str))
+ if (! (tab= find_table_in_local_list(tables, fk_p_s->child_table_db.str,
+ fk_p_s->child_table_name.str)) ||
+ tab->drop_table_rctx->is_temporary)
{
my_error(ER_FK_CHILD_TABLE_EXISTS, MYF(0), fk_p_s->name.str,
thd->lex->sql_command == SQLCOM_DROP_DB ? "DROP DATABASE" :
@@ -2563,9 +2578,10 @@ fk_check_tables_before_drop(THD *thd,
while ((fk_c_s= fkeys_c_it++))
{
- if (! find_table_in_local_list(tables,
+ if ((! (tab= find_table_in_local_list(tables,
fk_c_s->parent_table_db.str,
- fk_c_s->parent_table_name.str) &&
+ fk_c_s->parent_table_name.str)) ||
+ tab->drop_table_rctx->is_temporary) &&
! find_table_in_local_list(*parents_locked,
fk_c_s->parent_table_db.str,
fk_c_s->parent_table_name.str))
@@ -2592,7 +2608,8 @@ fk_check_tables_before_drop(THD *thd,
@sa fk_take_mdl_on_fk_names().
*/
- fk_name= thd->locked_tables_list.find_fk_name(table->db, fk_c_s->name.str);
+ fk_name= thd->locked_tables_list.find_fk_name(table->db,
+ fk_c_s->name.str);
DBUG_ASSERT(fk_name);
if (fk_names_locked->push_back(fk_name, thd->mem_root))
@@ -2674,6 +2691,13 @@ int mysql_rm_table_part2(THD *thd, TABLE
if (!drop_temporary)
global_schema_lock_guard.lock();
+ /* Create per-table runtime contexts for the operation. */
+ for (table= tables; table; table= table->next_local)
+ {
+ if (! (table->drop_table_rctx= new(thd->mem_root) Drop_table_rcontext()))
+ DBUG_RETURN(1);
+ }
+
/*
If we have the table in the definition cache, we don't have to check the
.frm file to find if the table is a normal table (not view) and what
@@ -2683,9 +2707,9 @@ int mysql_rm_table_part2(THD *thd, TABLE
for (table= tables; table; table= table->next_local)
{
TABLE_SHARE *share;
- table->db_type= NULL;
+
if ((share= get_cached_table_share(table->db, table->table_name)))
- table->db_type= share->db_type();
+ table->drop_table_rctx->table_type= share->db_type();
/* Disable drop of enabled log tables */
if (share && (share->table_category == TABLE_CATEGORY_PERFORMANCE) &&
@@ -2709,15 +2733,8 @@ int mysql_rm_table_part2(THD *thd, TABLE
*/
for (table= tables; table; table= table->next_local)
{
- if ((table->table= find_temporary_table(thd, table->db,
- table->table_name)))
- {
- /*
- Since we don't acquire metadata lock if we have found temporary
- table, we should do something to avoid releasing it at the end.
- */
- table->mdl_request= 0;
- }
+ if (find_temporary_table(thd, table->db, table->table_name))
+ table->drop_table_rctx->is_temporary= TRUE;
}
if (!thd->locked_tables_mode)
@@ -2747,7 +2764,8 @@ retry_lock:
else
{
for (table= tables; table; table= table->next_local)
- if (! table->table)
+ {
+ if (! table->drop_table_rctx->is_temporary)
{
/*
Check that each non-temporary table to be dropped is locked
@@ -2760,6 +2778,7 @@ retry_lock:
DBUG_RETURN(1);
table->mdl_request->ticket= table->table->mdl_ticket;
}
+ }
/*
Check that we are not dropping parent tables withour dropping child
@@ -2806,8 +2825,8 @@ retry_lock:
switch (error) {
case 0:
// removed temporary table
+ DBUG_ASSERT(drop_temporary || table->drop_table_rctx->is_temporary);
tmp_table_deleted= 1;
- table->table= 0;
continue;
case -1:
DBUG_ASSERT(thd->in_sub_stmt);
@@ -2815,6 +2834,7 @@ retry_lock:
goto err;
default:
// temporary table not found
+ DBUG_ASSERT(! table->drop_table_rctx->is_temporary);
error= 0;
}
@@ -2844,7 +2864,7 @@ retry_lock:
built_query.append("`,");
}
- table_type= table->db_type;
+ table_type= table->drop_table_rctx->table_type;
if (!drop_temporary)
{
if (opt_fk_all_engines &&
@@ -3108,7 +3128,7 @@ err:
}
for (table= tables; table; table= table->next_local)
{
- if (table->mdl_request)
+ if (! table->drop_table_rctx->is_temporary)
{
/*
Under LOCK TABLES we may have several instances of table open
=== modified file 'sql/table.h'
--- a/sql/table.h 2009-05-14 14:18:43 +0000
+++ b/sql/table.h 2009-05-22 09:50:20 +0000
@@ -1088,6 +1088,7 @@ class SJ_MATERIALIZATION_INFO;
class Index_hint;
class Item_in_subselect;
class Parent_info;
+class Drop_table_rcontext;
/*
@@ -1424,7 +1425,6 @@ struct TABLE_LIST
bool check_option_processed;
/* FRMTYPE_ERROR if any type is acceptable */
enum frm_type_enum required_type;
- handlerton *db_type; /* table_type for handler */
char timestamp_buffer[20]; /* buffer for timestamp (19+1) */
/*
This TABLE_LIST object is just placeholder for prelocking, it will be
@@ -1537,6 +1537,13 @@ struct TABLE_LIST
*/
Parent_info *parent_info;
+ /**
+ For table list elements representing tables being dropped in DROP TABLES
+ and DROP DATABASE statements context holding information about such table
+ for the whole duration of the statement.
+ */
+ Drop_table_rcontext *drop_table_rctx;
+
void calc_md5(char *buffer);
void set_underlying_merge();
int view_check_option(THD *thd, bool ignore_failure);
Attachment: [text/bzr-bundle] bzr/dlenev@mysql.com-20090522095020-v1lw99ewjmzmxbcm.bundle
| Thread |
|---|
| • bzr commit into mysql-6.1-fk branch (dlenev:2737) | Dmitry Lenev | 22 May |