Commit b474ad26 authored by Konstantin Osipov's avatar Konstantin Osipov

Backport of:

------------------------------------------------------------
revno: 2630.9.2
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-6.0-3726-w3
timestamp: Tue 2008-06-10 18:01:56 +0400
message:
  WL#3726 "DDL locking for all metadata objects".

  After review fixes in progress.
parent 78460958
...@@ -611,6 +611,7 @@ static bool can_grant_lock(MDL_LOCK *lock, MDL_LOCK_DATA *lock_data) ...@@ -611,6 +611,7 @@ static bool can_grant_lock(MDL_LOCK *lock, MDL_LOCK_DATA *lock_data)
This function must be called after the lock is added to a context. This function must be called after the lock is added to a context.
@param context [in] Context containing request for lock
@param lock_data [in] Lock request object for lock to be acquired @param lock_data [in] Lock request object for lock to be acquired
@param retry [out] Indicates that conflicting lock exists and another @param retry [out] Indicates that conflicting lock exists and another
attempt should be made after releasing all current attempt should be made after releasing all current
...@@ -622,16 +623,19 @@ static bool can_grant_lock(MDL_LOCK *lock, MDL_LOCK_DATA *lock_data) ...@@ -622,16 +623,19 @@ static bool can_grant_lock(MDL_LOCK *lock, MDL_LOCK_DATA *lock_data)
In the latter case "retry" parameter is set to TRUE. In the latter case "retry" parameter is set to TRUE.
*/ */
bool mdl_acquire_shared_lock(MDL_LOCK_DATA *lock_data, bool *retry) bool mdl_acquire_shared_lock(MDL_CONTEXT *context, MDL_LOCK_DATA *lock_data,
bool *retry)
{ {
MDL_LOCK *lock; MDL_LOCK *lock;
*retry= FALSE; *retry= FALSE;
DBUG_ASSERT(is_shared(lock_data) && lock_data->state == MDL_PENDING); DBUG_ASSERT(is_shared(lock_data) && lock_data->state == MDL_PENDING);
DBUG_ASSERT(lock_data->ctx == context);
safe_mutex_assert_not_owner(&LOCK_open); safe_mutex_assert_not_owner(&LOCK_open);
if (lock_data->ctx->has_global_shared_lock && if (context->has_global_shared_lock &&
lock_data->type == MDL_SHARED_UPGRADABLE) lock_data->type == MDL_SHARED_UPGRADABLE)
{ {
my_error(ER_CANT_UPDATE_WITH_READLOCK, MYF(0)); my_error(ER_CANT_UPDATE_WITH_READLOCK, MYF(0));
......
...@@ -164,7 +164,8 @@ inline void mdl_set_lock_type(MDL_LOCK_DATA *lock_data, enum_mdl_type lock_type) ...@@ -164,7 +164,8 @@ inline void mdl_set_lock_type(MDL_LOCK_DATA *lock_data, enum_mdl_type lock_type)
lock_data->type= lock_type; lock_data->type= lock_type;
} }
bool mdl_acquire_shared_lock(MDL_LOCK_DATA *lock_data, bool *retry); bool mdl_acquire_shared_lock(MDL_CONTEXT *context, MDL_LOCK_DATA *lock_data,
bool *retry);
bool mdl_acquire_exclusive_locks(MDL_CONTEXT *context); 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);
......
...@@ -2837,7 +2837,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, ...@@ -2837,7 +2837,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root,
if (flags & MYSQL_LOCK_IGNORE_FLUSH) if (flags & MYSQL_LOCK_IGNORE_FLUSH)
mdl_set_lock_type(mdl_lock_data, MDL_SHARED_HIGH_PRIO); mdl_set_lock_type(mdl_lock_data, MDL_SHARED_HIGH_PRIO);
if (mdl_acquire_shared_lock(mdl_lock_data, &retry)) if (mdl_acquire_shared_lock(&thd->mdl_context, mdl_lock_data, &retry))
{ {
if (retry) if (retry)
*action= OT_BACK_OFF_AND_RETRY; *action= OT_BACK_OFF_AND_RETRY;
...@@ -4044,17 +4044,20 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list) ...@@ -4044,17 +4044,20 @@ static bool auto_repair_table(THD *thd, TABLE_LIST *table_list)
/** /**
Handle failed attempt ot open table by performing requested action. Recover from failed attempt ot open table by performing requested action.
@param thd Thread context @param thd Thread context
@param table Table list element for table that caused problem @param table Table list element for table that caused problem
@param action Type of action requested by failed open_table() call @param action Type of action requested by failed open_table() call
@pre This function should be called only with "action" != OT_NO_ACTION.
@retval FALSE - Success. One should try to open tables once again. @retval FALSE - Success. One should try to open tables once again.
@retval TRUE - Error @retval TRUE - Error
*/ */
static bool handle_failed_open_table_attempt(THD *thd, TABLE_LIST *table, static bool
recover_from_failed_open_table_attempt(THD *thd, TABLE_LIST *table,
enum_open_table_action action) enum_open_table_action action)
{ {
bool result= FALSE; bool result= FALSE;
...@@ -4678,7 +4681,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags) ...@@ -4678,7 +4681,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
TABLE_LIST element. Altough currently this assumption is valid TABLE_LIST element. Altough currently this assumption is valid
it may change in future. it may change in future.
*/ */
if (handle_failed_open_table_attempt(thd, tables, action)) if (recover_from_failed_open_table_attempt(thd, tables, action))
{ {
result= -1; result= -1;
goto err; goto err;
...@@ -4997,7 +5000,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type, ...@@ -4997,7 +5000,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type,
might have been acquired successfully. might have been acquired successfully.
*/ */
close_thread_tables(thd, (action == OT_BACK_OFF_AND_RETRY)); close_thread_tables(thd, (action == OT_BACK_OFF_AND_RETRY));
if (handle_failed_open_table_attempt(thd, table_list, action)) if (recover_from_failed_open_table_attempt(thd, table_list, action))
break; break;
} }
...@@ -8530,7 +8533,13 @@ bool notify_thread_having_shared_lock(THD *thd, THD *in_use) ...@@ -8530,7 +8533,13 @@ bool notify_thread_having_shared_lock(THD *thd, THD *in_use)
thd_table ; thd_table ;
thd_table= thd_table->next) thd_table= thd_table->next)
{ {
/* TODO With new MDL check for db_stat is probably a legacy */ /*
Check for TABLE::db_stat is needed since in some places we call
handler::close() for table instance (and set TABLE::db_stat to 0)
and do not remove such instances from the THD::open_tables
for some time, during which other thread can see those instances
(e.g. see partitioning code).
*/
if (thd_table->db_stat) if (thd_table->db_stat)
signalled|= mysql_lock_abort_for_thread(thd, thd_table); signalled|= mysql_lock_abort_for_thread(thd, thd_table);
} }
......
...@@ -3145,7 +3145,7 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table, ...@@ -3145,7 +3145,7 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table,
*/ */
while (1) while (1)
{ {
if (mdl_acquire_shared_lock(&mdl_lock_data, &retry)) if (mdl_acquire_shared_lock(&thd->mdl_context, &mdl_lock_data, &retry))
{ {
if (!retry || mdl_wait_for_locks(&thd->mdl_context)) if (!retry || mdl_wait_for_locks(&thd->mdl_context))
{ {
......
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