Commit 0a49fd92 authored by Konstantin Osipov's avatar Konstantin Osipov

Backport of:

------------------------------------------------------------
revno: 2630.4.32
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-6.0-3726-w2
timestamp: Thu 2008-06-19 16:39:58 +0400
message:
  WL#3726 "DDL locking for all metadata objects".

  After-review fixes in progress.

  Ensure that metadata locking subsystem properly handles
  out-of-memory conditions. Clarified MDL interface by
  separating release of locks and removal of lock requests
  from the context.
parent bf2aae04
...@@ -965,7 +965,7 @@ bool lock_table_names(THD *thd, TABLE_LIST *table_list) ...@@ -965,7 +965,7 @@ bool lock_table_names(THD *thd, TABLE_LIST *table_list)
lock_table->mdl_lock_data= mdl_lock_data; lock_table->mdl_lock_data= mdl_lock_data;
} }
if (mdl_acquire_exclusive_locks(&thd->mdl_context)) if (mdl_acquire_exclusive_locks(&thd->mdl_context))
return 1; goto end;
return 0; return 0;
end: end:
......
This diff is collapsed.
...@@ -44,7 +44,8 @@ enum enum_mdl_type {MDL_SHARED=0, MDL_SHARED_HIGH_PRIO, ...@@ -44,7 +44,8 @@ enum enum_mdl_type {MDL_SHARED=0, MDL_SHARED_HIGH_PRIO,
/** States which metadata lock request can have. */ /** States which metadata lock request can have. */
enum enum_mdl_state {MDL_PENDING=0, MDL_ACQUIRED, MDL_PENDING_UPGRADE}; enum enum_mdl_state {MDL_INITIALIZED=0, MDL_PENDING,
MDL_ACQUIRED, MDL_PENDING_UPGRADE};
/** /**
...@@ -152,6 +153,7 @@ void mdl_init_lock(MDL_LOCK_DATA *lock_data, char *key, int type, ...@@ -152,6 +153,7 @@ void mdl_init_lock(MDL_LOCK_DATA *lock_data, char *key, int type,
MDL_LOCK_DATA *mdl_alloc_lock(int type, const char *db, const char *name, MDL_LOCK_DATA *mdl_alloc_lock(int type, const char *db, const char *name,
MEM_ROOT *root); MEM_ROOT *root);
void mdl_add_lock(MDL_CONTEXT *context, MDL_LOCK_DATA *lock_data); void mdl_add_lock(MDL_CONTEXT *context, MDL_LOCK_DATA *lock_data);
void mdl_remove_lock(MDL_CONTEXT *context, MDL_LOCK_DATA *lock_data);
void mdl_remove_all_locks(MDL_CONTEXT *context); void mdl_remove_all_locks(MDL_CONTEXT *context);
/** /**
...@@ -160,7 +162,7 @@ void mdl_remove_all_locks(MDL_CONTEXT *context); ...@@ -160,7 +162,7 @@ void mdl_remove_all_locks(MDL_CONTEXT *context);
inline void mdl_set_lock_type(MDL_LOCK_DATA *lock_data, enum_mdl_type lock_type) inline void mdl_set_lock_type(MDL_LOCK_DATA *lock_data, enum_mdl_type lock_type)
{ {
DBUG_ASSERT(lock_data->state == MDL_PENDING); DBUG_ASSERT(lock_data->state == MDL_INITIALIZED);
lock_data->type= lock_type; lock_data->type= lock_type;
} }
...@@ -170,13 +172,14 @@ bool mdl_acquire_exclusive_locks(MDL_CONTEXT *context); ...@@ -170,13 +172,14 @@ bool mdl_acquire_exclusive_locks(MDL_CONTEXT *context);
bool mdl_upgrade_shared_lock_to_exclusive(MDL_CONTEXT *context, bool mdl_upgrade_shared_lock_to_exclusive(MDL_CONTEXT *context,
MDL_LOCK_DATA *lock_data); MDL_LOCK_DATA *lock_data);
bool mdl_try_acquire_exclusive_lock(MDL_CONTEXT *context, bool mdl_try_acquire_exclusive_lock(MDL_CONTEXT *context,
MDL_LOCK_DATA *lock_data); MDL_LOCK_DATA *lock_data,
bool *conflict);
bool mdl_acquire_global_shared_lock(MDL_CONTEXT *context); bool mdl_acquire_global_shared_lock(MDL_CONTEXT *context);
bool mdl_wait_for_locks(MDL_CONTEXT *context); bool mdl_wait_for_locks(MDL_CONTEXT *context);
void mdl_release_locks(MDL_CONTEXT *context); void mdl_release_locks(MDL_CONTEXT *context);
void mdl_release_all_locks_for_name(MDL_CONTEXT *context, void mdl_release_and_remove_all_locks_for_name(MDL_CONTEXT *context,
MDL_LOCK_DATA *lock_data); MDL_LOCK_DATA *lock_data);
void mdl_release_lock(MDL_CONTEXT *context, MDL_LOCK_DATA *lock_data); void mdl_release_lock(MDL_CONTEXT *context, MDL_LOCK_DATA *lock_data);
void mdl_downgrade_exclusive_lock(MDL_CONTEXT *context, void mdl_downgrade_exclusive_lock(MDL_CONTEXT *context,
......
...@@ -2278,7 +2278,7 @@ void table_share_release_hook(void *share) ...@@ -2278,7 +2278,7 @@ void table_share_release_hook(void *share)
} }
/* /**
A helper function that acquires an MDL lock for a table A helper function that acquires an MDL lock for a table
being opened. being opened.
*/ */
...@@ -2304,8 +2304,11 @@ open_table_get_mdl_lock(THD *thd, TABLE_LIST *table_list, ...@@ -2304,8 +2304,11 @@ open_table_get_mdl_lock(THD *thd, TABLE_LIST *table_list,
*/ */
mdl_set_lock_type(mdl_lock_data, MDL_EXCLUSIVE); mdl_set_lock_type(mdl_lock_data, MDL_EXCLUSIVE);
if (mdl_acquire_exclusive_locks(&thd->mdl_context)) if (mdl_acquire_exclusive_locks(&thd->mdl_context))
{
mdl_remove_lock(&thd->mdl_context, mdl_lock_data);
return 1; return 1;
} }
}
else else
{ {
bool retry; bool retry;
...@@ -2327,6 +2330,8 @@ open_table_get_mdl_lock(THD *thd, TABLE_LIST *table_list, ...@@ -2327,6 +2330,8 @@ open_table_get_mdl_lock(THD *thd, TABLE_LIST *table_list,
{ {
if (retry) if (retry)
*action= OT_BACK_OFF_AND_RETRY; *action= OT_BACK_OFF_AND_RETRY;
else
mdl_remove_lock(&thd->mdl_context, mdl_lock_data);
return 1; return 1;
} }
} }
...@@ -2833,7 +2838,11 @@ err_unlock: ...@@ -2833,7 +2838,11 @@ err_unlock:
release_table_share(share); release_table_share(share);
err_unlock2: err_unlock2:
pthread_mutex_unlock(&LOCK_open); pthread_mutex_unlock(&LOCK_open);
if (! (flags & MYSQL_OPEN_HAS_MDL_LOCK))
{
mdl_release_lock(&thd->mdl_context, mdl_lock_data); mdl_release_lock(&thd->mdl_context, mdl_lock_data);
mdl_remove_lock(&thd->mdl_context, mdl_lock_data);
}
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
...@@ -3497,7 +3506,10 @@ recover_from_failed_open_table_attempt(THD *thd, TABLE_LIST *table, ...@@ -3497,7 +3506,10 @@ recover_from_failed_open_table_attempt(THD *thd, TABLE_LIST *table,
mdl_set_lock_type(table->mdl_lock_data, MDL_EXCLUSIVE); mdl_set_lock_type(table->mdl_lock_data, MDL_EXCLUSIVE);
mdl_add_lock(&thd->mdl_context, table->mdl_lock_data); mdl_add_lock(&thd->mdl_context, table->mdl_lock_data);
if (mdl_acquire_exclusive_locks(&thd->mdl_context)) if (mdl_acquire_exclusive_locks(&thd->mdl_context))
{
mdl_remove_lock(&thd->mdl_context, table->mdl_lock_data);
return TRUE; return TRUE;
}
pthread_mutex_lock(&LOCK_open); pthread_mutex_lock(&LOCK_open);
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name); tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name);
ha_create_table_from_engine(thd, table->db, table->table_name); ha_create_table_from_engine(thd, table->db, table->table_name);
...@@ -3506,18 +3518,23 @@ recover_from_failed_open_table_attempt(THD *thd, TABLE_LIST *table, ...@@ -3506,18 +3518,23 @@ recover_from_failed_open_table_attempt(THD *thd, TABLE_LIST *table,
thd->warning_info->clear_warning_info(thd->query_id); thd->warning_info->clear_warning_info(thd->query_id);
thd->clear_error(); // Clear error message thd->clear_error(); // Clear error message
mdl_release_lock(&thd->mdl_context, table->mdl_lock_data); mdl_release_lock(&thd->mdl_context, table->mdl_lock_data);
mdl_remove_lock(&thd->mdl_context, table->mdl_lock_data);
break; break;
case OT_REPAIR: case OT_REPAIR:
mdl_set_lock_type(table->mdl_lock_data, MDL_EXCLUSIVE); mdl_set_lock_type(table->mdl_lock_data, MDL_EXCLUSIVE);
mdl_add_lock(&thd->mdl_context, table->mdl_lock_data); mdl_add_lock(&thd->mdl_context, table->mdl_lock_data);
if (mdl_acquire_exclusive_locks(&thd->mdl_context)) if (mdl_acquire_exclusive_locks(&thd->mdl_context))
{
mdl_remove_lock(&thd->mdl_context, table->mdl_lock_data);
return TRUE; return TRUE;
}
pthread_mutex_lock(&LOCK_open); pthread_mutex_lock(&LOCK_open);
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name); tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name);
pthread_mutex_unlock(&LOCK_open); pthread_mutex_unlock(&LOCK_open);
result= auto_repair_table(thd, table); result= auto_repair_table(thd, table);
mdl_release_lock(&thd->mdl_context, table->mdl_lock_data); mdl_release_lock(&thd->mdl_context, table->mdl_lock_data);
mdl_remove_lock(&thd->mdl_context, table->mdl_lock_data);
break; break;
default: default:
DBUG_ASSERT(0); DBUG_ASSERT(0);
......
...@@ -1170,7 +1170,10 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) ...@@ -1170,7 +1170,10 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok)
mdl_set_lock_type(mdl_lock_data, MDL_EXCLUSIVE); mdl_set_lock_type(mdl_lock_data, MDL_EXCLUSIVE);
mdl_add_lock(&thd->mdl_context, mdl_lock_data); mdl_add_lock(&thd->mdl_context, mdl_lock_data);
if (mdl_acquire_exclusive_locks(&thd->mdl_context)) if (mdl_acquire_exclusive_locks(&thd->mdl_context))
{
mdl_remove_lock(&thd->mdl_context, mdl_lock_data);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
}
pthread_mutex_lock(&LOCK_open); pthread_mutex_lock(&LOCK_open);
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_list->db, tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_list->db,
table_list->table_name); table_list->table_name);
...@@ -1200,12 +1203,18 @@ end: ...@@ -1200,12 +1203,18 @@ end:
my_ok(thd); // This should return record count my_ok(thd); // This should return record count
} }
if (mdl_lock_data) if (mdl_lock_data)
{
mdl_release_lock(&thd->mdl_context, mdl_lock_data); mdl_release_lock(&thd->mdl_context, mdl_lock_data);
mdl_remove_lock(&thd->mdl_context, mdl_lock_data);
}
} }
else if (error) else if (error)
{ {
if (mdl_lock_data) if (mdl_lock_data)
{
mdl_release_lock(&thd->mdl_context, mdl_lock_data); mdl_release_lock(&thd->mdl_context, mdl_lock_data);
mdl_remove_lock(&thd->mdl_context, mdl_lock_data);
}
} }
DBUG_RETURN(error); DBUG_RETURN(error);
......
...@@ -150,6 +150,7 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables) ...@@ -150,6 +150,7 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables)
} }
pthread_mutex_unlock(&LOCK_open); pthread_mutex_unlock(&LOCK_open);
mdl_release_lock(&thd->handler_mdl_context, mdl_lock_data); mdl_release_lock(&thd->handler_mdl_context, mdl_lock_data);
mdl_remove_lock(&thd->handler_mdl_context, mdl_lock_data);
} }
else if (tables->table) else if (tables->table)
{ {
......
...@@ -3250,6 +3250,7 @@ err_unlock: ...@@ -3250,6 +3250,7 @@ err_unlock:
err: err:
mdl_release_lock(&thd->mdl_context, &mdl_lock_data); mdl_release_lock(&thd->mdl_context, &mdl_lock_data);
mdl_remove_lock(&thd->mdl_context, &mdl_lock_data);
thd->clear_error(); thd->clear_error();
return res; return res;
} }
......
...@@ -2208,7 +2208,8 @@ err: ...@@ -2208,7 +2208,8 @@ err:
and locked and therefore have to remove several metadata lock and locked and therefore have to remove several metadata lock
requests associated with them. requests associated with them.
*/ */
mdl_release_all_locks_for_name(&thd->mdl_context, table->mdl_lock_data); mdl_release_and_remove_all_locks_for_name(&thd->mdl_context,
table->mdl_lock_data);
} }
} }
} }
...@@ -4080,12 +4081,26 @@ static bool lock_table_name_if_not_cached(THD *thd, const char *db, ...@@ -4080,12 +4081,26 @@ static bool lock_table_name_if_not_cached(THD *thd, const char *db,
const char *table_name, const char *table_name,
MDL_LOCK_DATA **lock_data) MDL_LOCK_DATA **lock_data)
{ {
bool conflict;
if (!(*lock_data= mdl_alloc_lock(0, db, table_name, thd->mem_root))) if (!(*lock_data= mdl_alloc_lock(0, db, table_name, thd->mem_root)))
return TRUE; return TRUE;
mdl_set_lock_type(*lock_data, MDL_EXCLUSIVE); mdl_set_lock_type(*lock_data, MDL_EXCLUSIVE);
mdl_add_lock(&thd->mdl_context, *lock_data); mdl_add_lock(&thd->mdl_context, *lock_data);
if (mdl_try_acquire_exclusive_lock(&thd->mdl_context, *lock_data)) if (mdl_try_acquire_exclusive_lock(&thd->mdl_context, *lock_data,
&conflict))
{ {
/*
To simplify our life under LOCK TABLES we remove unsatisfied
lock request from the context.
*/
mdl_remove_lock(&thd->mdl_context, *lock_data);
if (!conflict)
{
/* Probably OOM. */
return TRUE;
}
else
*lock_data= 0; *lock_data= 0;
} }
return FALSE; return FALSE;
...@@ -4157,7 +4172,10 @@ bool mysql_create_table(THD *thd, const char *db, const char *table_name, ...@@ -4157,7 +4172,10 @@ bool mysql_create_table(THD *thd, const char *db, const char *table_name,
unlock: unlock:
if (target_lock_data) if (target_lock_data)
{
mdl_release_lock(&thd->mdl_context, target_lock_data); mdl_release_lock(&thd->mdl_context, target_lock_data);
mdl_remove_lock(&thd->mdl_context, target_lock_data);
}
pthread_mutex_lock(&LOCK_lock_db); pthread_mutex_lock(&LOCK_lock_db);
if (!--creating_table && creating_database) if (!--creating_table && creating_database)
pthread_cond_signal(&COND_refresh); pthread_cond_signal(&COND_refresh);
...@@ -4416,7 +4434,10 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, ...@@ -4416,7 +4434,10 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
mdl_set_lock_type(mdl_lock_data, MDL_EXCLUSIVE); mdl_set_lock_type(mdl_lock_data, MDL_EXCLUSIVE);
mdl_add_lock(&thd->mdl_context, mdl_lock_data); mdl_add_lock(&thd->mdl_context, mdl_lock_data);
if (mdl_acquire_exclusive_locks(&thd->mdl_context)) if (mdl_acquire_exclusive_locks(&thd->mdl_context))
{
mdl_remove_lock(&thd->mdl_context, mdl_lock_data);
DBUG_RETURN(0); DBUG_RETURN(0);
}
pthread_mutex_lock(&LOCK_open); pthread_mutex_lock(&LOCK_open);
if (!(share= (get_table_share(thd, table_list, key, key_length, 0, if (!(share= (get_table_share(thd, table_list, key, key_length, 0,
...@@ -4550,7 +4571,10 @@ end: ...@@ -4550,7 +4571,10 @@ end:
} }
/* In case of a temporary table there will be no metadata lock. */ /* In case of a temporary table there will be no metadata lock. */
if (error && mdl_lock_data) if (error && mdl_lock_data)
{
mdl_release_lock(&thd->mdl_context, mdl_lock_data); mdl_release_lock(&thd->mdl_context, mdl_lock_data);
mdl_remove_lock(&thd->mdl_context, mdl_lock_data);
}
DBUG_RETURN(error); DBUG_RETURN(error);
} }
...@@ -5518,7 +5542,10 @@ binlog: ...@@ -5518,7 +5542,10 @@ binlog:
err: err:
if (target_lock_data) if (target_lock_data)
{
mdl_release_lock(&thd->mdl_context, target_lock_data); mdl_release_lock(&thd->mdl_context, target_lock_data);
mdl_remove_lock(&thd->mdl_context, target_lock_data);
}
DBUG_RETURN(res); DBUG_RETURN(res);
} }
...@@ -6876,7 +6903,9 @@ view_err: ...@@ -6876,7 +6903,9 @@ view_err:
if (new_name != table_name || new_db != db) if (new_name != table_name || new_db != db)
{ {
mdl_release_lock(&thd->mdl_context, target_lock_data); mdl_release_lock(&thd->mdl_context, target_lock_data);
mdl_release_all_locks_for_name(&thd->mdl_context, mdl_lock_data); mdl_remove_lock(&thd->mdl_context, target_lock_data);
mdl_release_and_remove_all_locks_for_name(&thd->mdl_context,
mdl_lock_data);
} }
else else
mdl_downgrade_exclusive_lock(&thd->mdl_context, mdl_lock_data); mdl_downgrade_exclusive_lock(&thd->mdl_context, mdl_lock_data);
...@@ -7554,7 +7583,9 @@ view_err: ...@@ -7554,7 +7583,9 @@ view_err:
if ((new_name != table_name || new_db != db)) if ((new_name != table_name || new_db != db))
{ {
mdl_release_lock(&thd->mdl_context, target_lock_data); mdl_release_lock(&thd->mdl_context, target_lock_data);
mdl_release_all_locks_for_name(&thd->mdl_context, mdl_lock_data); mdl_remove_lock(&thd->mdl_context, target_lock_data);
mdl_release_and_remove_all_locks_for_name(&thd->mdl_context,
mdl_lock_data);
} }
else else
mdl_downgrade_exclusive_lock(&thd->mdl_context, mdl_lock_data); mdl_downgrade_exclusive_lock(&thd->mdl_context, mdl_lock_data);
...@@ -7613,7 +7644,10 @@ err: ...@@ -7613,7 +7644,10 @@ err:
thd->abort_on_warning= save_abort_on_warning; thd->abort_on_warning= save_abort_on_warning;
} }
if (target_lock_data) if (target_lock_data)
{
mdl_release_lock(&thd->mdl_context, target_lock_data); mdl_release_lock(&thd->mdl_context, target_lock_data);
mdl_remove_lock(&thd->mdl_context, target_lock_data);
}
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
err_with_mdl: err_with_mdl:
...@@ -7625,8 +7659,11 @@ err_with_mdl: ...@@ -7625,8 +7659,11 @@ err_with_mdl:
*/ */
thd->locked_tables_list.unlink_all_closed_tables(); thd->locked_tables_list.unlink_all_closed_tables();
if (target_lock_data) if (target_lock_data)
{
mdl_release_lock(&thd->mdl_context, target_lock_data); mdl_release_lock(&thd->mdl_context, target_lock_data);
mdl_release_all_locks_for_name(&thd->mdl_context, mdl_lock_data); mdl_remove_lock(&thd->mdl_context, target_lock_data);
}
mdl_release_and_remove_all_locks_for_name(&thd->mdl_context, mdl_lock_data);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
/* mysql_alter_table */ /* mysql_alter_table */
......
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