diff options
author | Konstantin Osipov <kostja@sun.com> | 2009-12-01 01:33:22 +0300 |
---|---|---|
committer | Konstantin Osipov <kostja@sun.com> | 2009-12-01 01:33:22 +0300 |
commit | e23046d1bcaf54838167dd6bd3d8c6900e24b2ef (patch) | |
tree | ba3438eef550d9cf10d121bad3981f18566659d4 | |
parent | cf45b61a6a611415161e6176b8c8ae85a51e9349 (diff) | |
download | mariadb-git-e23046d1bcaf54838167dd6bd3d8c6900e24b2ef.tar.gz |
Backport of:
------------------------------------------------------------
revno: 2630.4.17
committer: Dmitry Lenev <dlenev@mysql.com>
branch nick: mysql-6.0-3726-w2
timestamp: Thu 2008-05-29 16:52:56 +0400
message:
WL#3726 "DDL locking for all metadata objects".
After review fixes in progress.
"The great correction of names".
Renamed MDL_LOCK and MDL_LOCK_DATA classes to make usage of
these names in metadata locking subsystem consistent with
other parts of server (i.e. thr_lock.cc). Now we MDL_LOCK_DATA
corresponds to request for a lock and MDL_LOCK to the lock
itself. Adjusted code in MDL subsystem and other places
using these classes accordingly.
Did similar thing for GLOBAL_MDL_LOCK_DATA class and also
changed name of its members to correspond to names of
MDL_LOCK_DATA members.
Finally got rid of usage of one letter variables in MDL
code since it makes code harder to search in (according
to reviewer).
-rw-r--r-- | sql/ha_ndbcluster_binlog.cc | 8 | ||||
-rw-r--r-- | sql/lock.cc | 11 | ||||
-rw-r--r-- | sql/log_event.cc | 9 | ||||
-rw-r--r-- | sql/mdl.cc | 624 | ||||
-rw-r--r-- | sql/mdl.h | 94 | ||||
-rw-r--r-- | sql/sp_head.cc | 13 | ||||
-rw-r--r-- | sql/sql_base.cc | 47 | ||||
-rw-r--r-- | sql/sql_delete.cc | 18 | ||||
-rw-r--r-- | sql/sql_handler.cc | 22 | ||||
-rw-r--r-- | sql/sql_parse.cc | 6 | ||||
-rw-r--r-- | sql/sql_show.cc | 14 | ||||
-rw-r--r-- | sql/sql_table.cc | 67 | ||||
-rw-r--r-- | sql/table.cc | 5 | ||||
-rw-r--r-- | sql/table.h | 6 |
14 files changed, 484 insertions, 460 deletions
diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index f272526edb8..14d14db6b7d 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -140,8 +140,8 @@ static Uint64 *p_latest_trans_gci= 0; */ static TABLE *ndb_binlog_index= 0; static TABLE_LIST binlog_tables; -static MDL_LOCK binlog_mdl_lock; -static char binlog_mdlkey[MAX_DBKEY_LENGTH]; +static MDL_LOCK_DATA binlog_mdl_lock_data; +static char binlog_mdlkey[MAX_DBKEY_LENGTH]; /* Helper functions @@ -2343,9 +2343,9 @@ static int open_ndb_binlog_index(THD *thd, TABLE **ndb_binlog_index) tables->alias= tables->table_name= reptable; tables->lock_type= TL_WRITE; thd->proc_info= "Opening " NDB_REP_DB "." NDB_REP_TABLE; - mdl_init_lock(&binlog_mdl_lock, binlog_mdlkey, 0, tables->db, + mdl_init_lock(&binlog_mdl_lock_data, binlog_mdlkey, 0, tables->db, tables->table_name); - tables->mdl_lock= &binlog_mdl_lock; + tables->mdl_lock_data= &binlog_mdl_lock_data; tables->required_type= FRMTYPE_TABLE; uint counter; thd->clear_error(); diff --git a/sql/lock.cc b/sql/lock.cc index 38b2d22f91f..b5eaaa05fff 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -966,15 +966,16 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, bool lock_table_names(THD *thd, TABLE_LIST *table_list) { TABLE_LIST *lock_table; - MDL_LOCK *mdl_lock; + MDL_LOCK_DATA *mdl_lock_data; for (lock_table= table_list; lock_table; lock_table= lock_table->next_local) { - if (!(mdl_lock= mdl_alloc_lock(0, lock_table->db, lock_table->table_name, - thd->mem_root))) + if (!(mdl_lock_data= mdl_alloc_lock(0, lock_table->db, + lock_table->table_name, + thd->mem_root))) goto end; - mdl_set_lock_type(mdl_lock, MDL_EXCLUSIVE); - mdl_add_lock(&thd->mdl_context, mdl_lock); + mdl_set_lock_type(mdl_lock_data, MDL_EXCLUSIVE); + mdl_add_lock(&thd->mdl_context, mdl_lock_data); } if (mdl_acquire_exclusive_locks(&thd->mdl_context)) return 1; diff --git a/sql/log_event.cc b/sql/log_event.cc index fd0e20d690d..92de9933181 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -8058,7 +8058,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli) { RPL_TABLE_LIST *table_list; char *db_mem, *tname_mem, *mdlkey; - MDL_LOCK *mdl_lock; + MDL_LOCK_DATA *mdl_lock_data; size_t dummy_len; void *memory; DBUG_ENTER("Table_map_log_event::do_apply_event(Relay_log_info*)"); @@ -8073,7 +8073,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli) &table_list, (uint) sizeof(RPL_TABLE_LIST), &db_mem, (uint) NAME_LEN + 1, &tname_mem, (uint) NAME_LEN + 1, - &mdl_lock, sizeof(MDL_LOCK), + &mdl_lock_data, sizeof(MDL_LOCK_DATA), &mdlkey, MAX_DBKEY_LENGTH, NullS))) DBUG_RETURN(HA_ERR_OUT_OF_MEM); @@ -8087,8 +8087,9 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli) table_list->updating= 1; strmov(table_list->db, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len)); strmov(table_list->table_name, m_tblnam); - mdl_init_lock(mdl_lock, mdlkey, 0, table_list->db, table_list->table_name); - table_list->mdl_lock= mdl_lock; + mdl_init_lock(mdl_lock_data, mdlkey, 0, table_list->db, + table_list->table_name); + table_list->mdl_lock_data= mdl_lock_data; int error= 0; diff --git a/sql/mdl.cc b/sql/mdl.cc index ddd027c4027..64c011d34bf 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -26,34 +26,34 @@ /** The lock context. Created internally for an acquired lock. - For a given name, there exists only one MDL_LOCK_DATA instance, + For a given name, there exists only one MDL_LOCK instance, and it exists only when the lock has been granted. Can be seen as an MDL subsystem's version of TABLE_SHARE. */ -struct MDL_LOCK_DATA +struct MDL_LOCK { - I_P_List<MDL_LOCK, MDL_LOCK_lock> active_shared; + I_P_List<MDL_LOCK_DATA, MDL_LOCK_DATA_lock> active_shared; /* There can be several upgraders and active exclusive belonging to the same context. */ - I_P_List<MDL_LOCK, MDL_LOCK_lock> active_shared_waiting_upgrade; - I_P_List<MDL_LOCK, MDL_LOCK_lock> active_exclusive; - I_P_List<MDL_LOCK, MDL_LOCK_lock> waiting_exclusive; + I_P_List<MDL_LOCK_DATA, MDL_LOCK_DATA_lock> active_shared_waiting_upgrade; + I_P_List<MDL_LOCK_DATA, MDL_LOCK_DATA_lock> active_exclusive; + I_P_List<MDL_LOCK_DATA, MDL_LOCK_DATA_lock> waiting_exclusive; /** - Number of MDL_LOCK objects associated with this MDL_LOCK_DATA instance + Number of MDL_LOCK_DATA objects associated with this MDL_LOCK instance and therefore present in one of above lists. Note that this number doesn't account for pending requests for shared lock since we don't - associate them with MDL_LOCK_DATA and don't keep them in any list. + associate them with MDL_LOCK and don't keep them in any list. */ - uint lock_count; + uint lock_data_count; void *cached_object; mdl_cached_object_release_hook cached_object_release_hook; - MDL_LOCK_DATA() : cached_object(0), cached_object_release_hook(0) {} + MDL_LOCK() : cached_object(0), cached_object_release_hook(0) {} - MDL_LOCK *get_key_owner() + MDL_LOCK_DATA *get_key_owner() { return !active_shared.is_empty() ? active_shared.head() : @@ -63,9 +63,9 @@ struct MDL_LOCK_DATA active_exclusive.head() : waiting_exclusive.head())); } - bool has_one_lock() + bool has_one_lock_data() { - return (lock_count == 1); + return (lock_data_count == 1); } }; @@ -82,18 +82,18 @@ HASH mdl_locks; or shared upgradable lock on particular object. */ -struct MDL_GLOBAL_LOCK_DATA +struct MDL_GLOBAL_LOCK { - uint shared_pending; - uint shared_acquired; - uint intention_exclusive_acquired; + uint waiting_shared; + uint active_shared; + uint active_intention_exclusive; } global_lock; extern "C" uchar *mdl_locks_key(const uchar *record, size_t *length, my_bool not_used __attribute__((unused))) { - MDL_LOCK_DATA *entry=(MDL_LOCK_DATA*) record; + MDL_LOCK *entry=(MDL_LOCK*) record; *length= entry->get_key_owner()->key_length; return (uchar*) entry->get_key_owner()->key; } @@ -123,8 +123,8 @@ void mdl_init() pthread_cond_init(&COND_mdl, NULL); my_hash_init(&mdl_locks, &my_charset_bin, 16 /* FIXME */, 0, 0, mdl_locks_key, 0, 0); - global_lock.shared_pending= global_lock.shared_acquired= 0; - global_lock.intention_exclusive_acquired= 0; + global_lock.waiting_shared= global_lock.active_shared= 0; + global_lock.active_intention_exclusive= 0; } @@ -211,18 +211,18 @@ void mdl_context_restore(MDL_CONTEXT *ctx, MDL_CONTEXT *backup) void mdl_context_merge(MDL_CONTEXT *dst, MDL_CONTEXT *src) { - MDL_LOCK *l; + MDL_LOCK_DATA *lock_data; DBUG_ASSERT(dst->thd == src->thd); if (!src->locks.is_empty()) { - I_P_List_iterator<MDL_LOCK, MDL_LOCK_context> it(src->locks); - while ((l= it++)) + I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(src->locks); + while ((lock_data= it++)) { - DBUG_ASSERT(l->ctx); - l->ctx= dst; - dst->locks.push_front(l); + DBUG_ASSERT(lock_data->ctx); + lock_data->ctx= dst; + dst->locks.push_front(lock_data); } src->locks.empty(); } @@ -247,7 +247,7 @@ void mdl_context_merge(MDL_CONTEXT *dst, MDL_CONTEXT *src) request encloses calls to mdl_acquire_shared_lock() and mdl_release_locks(). - @param mdl Pointer to an MDL_LOCK object to initialize + @param lock_data Pointer to an MDL_LOCK_DATA object to initialize @param key_buff Pointer to the buffer for key for the lock request (should be at least strlen(db) + strlen(name) + 2 bytes, or, if the lengths are not known, MAX_DBNAME_LENGTH) @@ -269,19 +269,19 @@ void mdl_context_merge(MDL_CONTEXT *dst, MDL_CONTEXT *src) they share the same name space in the SQL standard. */ -void mdl_init_lock(MDL_LOCK *mdl, char *key, int type, const char *db, - const char *name) +void mdl_init_lock(MDL_LOCK_DATA *lock_data, char *key, int type, + const char *db, const char *name) { int4store(key, type); - mdl->key_length= (uint) (strmov(strmov(key+4, db)+1, name)-key)+1; - mdl->key= key; - mdl->type= MDL_SHARED; - mdl->state= MDL_PENDING; - mdl->prio= MDL_NORMAL_PRIO; - mdl->is_upgradable= FALSE; + lock_data->key_length= (uint) (strmov(strmov(key+4, db)+1, name)-key)+1; + lock_data->key= key; + lock_data->type= MDL_SHARED; + lock_data->state= MDL_PENDING; + lock_data->prio= MDL_NORMAL_PRIO; + lock_data->is_upgradable= FALSE; #ifndef DBUG_OFF - mdl->ctx= 0; - mdl->lock_data= 0; + lock_data->ctx= 0; + lock_data->lock= 0; #endif } @@ -305,19 +305,19 @@ void mdl_init_lock(MDL_LOCK *mdl, char *key, int type, const char *db, @retval non-0 Pointer to an object representing a lock request */ -MDL_LOCK *mdl_alloc_lock(int type, const char *db, const char *name, - MEM_ROOT *root) +MDL_LOCK_DATA *mdl_alloc_lock(int type, const char *db, const char *name, + MEM_ROOT *root) { - MDL_LOCK *lock; + MDL_LOCK_DATA *lock_data; char *key; - if (!multi_alloc_root(root, &lock, sizeof(MDL_LOCK), &key, + if (!multi_alloc_root(root, &lock_data, sizeof(MDL_LOCK_DATA), &key, MAX_DBKEY_LENGTH, NULL)) return NULL; - mdl_init_lock(lock, key, type, db, name); + mdl_init_lock(lock_data, key, type, db, name); - return lock; + return lock_data; } @@ -334,16 +334,16 @@ MDL_LOCK *mdl_alloc_lock(int type, const char *db, const char *name, @param context The MDL context to associate the lock with. There should be no more than one context per connection, to avoid deadlocks. - @param lock The lock request to be added. + @param lock_data The lock request to be added. */ -void mdl_add_lock(MDL_CONTEXT *context, MDL_LOCK *lock) +void mdl_add_lock(MDL_CONTEXT *context, MDL_LOCK_DATA *lock_data) { DBUG_ENTER("mdl_add_lock"); - DBUG_ASSERT(lock->state == MDL_PENDING); - DBUG_ASSERT(!lock->ctx); - lock->ctx= context; - context->locks.push_front(lock); + DBUG_ASSERT(lock_data->state == MDL_PENDING); + DBUG_ASSERT(!lock_data->ctx); + lock_data->ctx= context; + context->locks.push_front(lock_data); DBUG_VOID_RETURN; } @@ -372,16 +372,16 @@ void mdl_add_lock(MDL_CONTEXT *context, MDL_LOCK *lock) void mdl_remove_all_locks(MDL_CONTEXT *context) { - MDL_LOCK *l; - I_P_List_iterator<MDL_LOCK, MDL_LOCK_context> it(context->locks); - while ((l= it++)) + MDL_LOCK_DATA *lock_data; + I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(context->locks); + while ((lock_data= it++)) { /* Reset lock request back to its initial state. */ - l->type= MDL_SHARED; - l->prio= MDL_NORMAL_PRIO; - l->is_upgradable= FALSE; + lock_data->type= MDL_SHARED; + lock_data->prio= MDL_NORMAL_PRIO; + lock_data->is_upgradable= FALSE; #ifndef DBUG_OFF - l->ctx= 0; + lock_data->ctx= 0; #endif } context->locks.empty(); @@ -389,20 +389,20 @@ void mdl_remove_all_locks(MDL_CONTEXT *context) /** - Auxiliary functions needed for creation/destruction of MDL_LOCK_DATA + Auxiliary functions needed for creation/destruction of MDL_LOCK objects. @todo This naive implementation should be replaced with one that saves on memory allocation by reusing released objects. */ -static MDL_LOCK_DATA* get_lock_data_object(void) +static MDL_LOCK* get_lock_object(void) { - return new MDL_LOCK_DATA(); + return new MDL_LOCK(); } -static void release_lock_data_object(MDL_LOCK_DATA *lock) +static void release_lock_object(MDL_LOCK *lock) { delete lock; } @@ -421,27 +421,27 @@ static void release_lock_data_object(MDL_LOCK_DATA *lock) This function must be called after the lock is added to a context. - @param lock [in] Lock request object for lock to be acquired - @param retry [out] Indicates that conflicting lock exists and another - attempt should be made after releasing all current - locks and waiting for conflicting lock go away - (using mdl_wait_for_locks()). + @param lock_data [in] Lock request object for lock to be acquired + @param retry [out] Indicates that conflicting lock exists and another + attempt should be made after releasing all current + locks and waiting for conflicting lock go away + (using mdl_wait_for_locks()). @retval FALSE Success. @retval TRUE Failure. Either error occured or conflicting lock exists. In the latter case "retry" parameter is set to TRUE. */ -bool mdl_acquire_shared_lock(MDL_LOCK *l, bool *retry) +bool mdl_acquire_shared_lock(MDL_LOCK_DATA *lock_data, bool *retry) { - MDL_LOCK_DATA *lock_data; + MDL_LOCK *lock; *retry= FALSE; - DBUG_ASSERT(l->type == MDL_SHARED && l->state == MDL_PENDING); + DBUG_ASSERT(lock_data->type == MDL_SHARED && lock_data->state == MDL_PENDING); safe_mutex_assert_not_owner(&LOCK_open); - if (l->ctx->has_global_shared_lock && l->is_upgradable) + if (lock_data->ctx->has_global_shared_lock && lock_data->is_upgradable) { my_error(ER_CANT_UPDATE_WITH_READLOCK, MYF(0)); return TRUE; @@ -449,46 +449,46 @@ bool mdl_acquire_shared_lock(MDL_LOCK *l, bool *retry) pthread_mutex_lock(&LOCK_mdl); - if (l->is_upgradable && - (global_lock.shared_acquired || global_lock.shared_pending)) + if (lock_data->is_upgradable && + (global_lock.active_shared || global_lock.waiting_shared)) { pthread_mutex_unlock(&LOCK_mdl); *retry= TRUE; return TRUE; } - if (!(lock_data= (MDL_LOCK_DATA *)my_hash_search(&mdl_locks, (uchar*)l->key, - l->key_length))) + if (!(lock= (MDL_LOCK *)my_hash_search(&mdl_locks, (uchar*)lock_data->key, + lock_data->key_length))) { - lock_data= get_lock_data_object(); - lock_data->active_shared.push_front(l); - lock_data->lock_count= 1; - my_hash_insert(&mdl_locks, (uchar*)lock_data); - l->state= MDL_ACQUIRED; - l->lock_data= lock_data; - if (l->is_upgradable) - global_lock.intention_exclusive_acquired++; + lock= get_lock_object(); + lock->active_shared.push_front(lock_data); + lock->lock_data_count= 1; + my_hash_insert(&mdl_locks, (uchar*)lock); + lock_data->state= MDL_ACQUIRED; + lock_data->lock= lock; + if (lock_data->is_upgradable) + global_lock.active_intention_exclusive++; } else { - if ((lock_data->active_exclusive.is_empty() && - (l->prio == MDL_HIGH_PRIO || - lock_data->waiting_exclusive.is_empty() && - lock_data->active_shared_waiting_upgrade.is_empty())) || - (!lock_data->active_exclusive.is_empty() && - lock_data->active_exclusive.head()->ctx == l->ctx)) + if ((lock->active_exclusive.is_empty() && + (lock_data->prio == MDL_HIGH_PRIO || + lock->waiting_exclusive.is_empty() && + lock->active_shared_waiting_upgrade.is_empty())) || + (!lock->active_exclusive.is_empty() && + lock->active_exclusive.head()->ctx == lock_data->ctx)) { /* When exclusive lock comes from the same context we can satisfy our shared lock. This is required for CREATE TABLE ... SELECT ... and ALTER VIEW ... AS .... */ - lock_data->active_shared.push_front(l); - lock_data->lock_count++; - l->state= MDL_ACQUIRED; - l->lock_data= lock_data; - if (l->is_upgradable) - global_lock.intention_exclusive_acquired++; + lock->active_shared.push_front(lock_data); + lock->lock_data_count++; + lock_data->state= MDL_ACQUIRED; + lock_data->lock= lock; + if (lock_data->is_upgradable) + global_lock.active_intention_exclusive++; } else *retry= TRUE; @@ -499,7 +499,7 @@ bool mdl_acquire_shared_lock(MDL_LOCK *l, bool *retry) } -static void release_lock(MDL_LOCK *l); +static void release_lock(MDL_LOCK_DATA *lock_data); /** @@ -523,11 +523,11 @@ static void release_lock(MDL_LOCK *l); bool mdl_acquire_exclusive_locks(MDL_CONTEXT *context) { - MDL_LOCK *l, *lh; - MDL_LOCK_DATA *lock_data; + MDL_LOCK_DATA *lock_data, *conf_lock_data; + MDL_LOCK *lock; bool signalled= FALSE; const char *old_msg; - I_P_List_iterator<MDL_LOCK, MDL_LOCK_context> it(context->locks); + I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(context->locks); THD *thd= context->thd; DBUG_ASSERT(thd == current_thd); @@ -544,34 +544,35 @@ bool mdl_acquire_exclusive_locks(MDL_CONTEXT *context) old_msg= thd->enter_cond(&COND_mdl, &LOCK_mdl, "Waiting for table"); - while ((l= it++)) + while ((lock_data= it++)) { - DBUG_ASSERT(l->type == MDL_EXCLUSIVE && l->state == MDL_PENDING); - if (!(lock_data= (MDL_LOCK_DATA *)my_hash_search(&mdl_locks, (uchar*)l->key, - l->key_length))) + DBUG_ASSERT(lock_data->type == MDL_EXCLUSIVE && + lock_data->state == MDL_PENDING); + if (!(lock= (MDL_LOCK *) my_hash_search(&mdl_locks, (uchar*)lock_data->key, + lock_data->key_length))) { - lock_data= get_lock_data_object(); - lock_data->waiting_exclusive.push_front(l); - lock_data->lock_count= 1; - my_hash_insert(&mdl_locks, (uchar*)lock_data); - l->lock_data= lock_data; + lock= get_lock_object(); + lock->waiting_exclusive.push_front(lock_data); + lock->lock_data_count= 1; + my_hash_insert(&mdl_locks, (uchar*)lock); + lock_data->lock= lock; } else { - lock_data->waiting_exclusive.push_front(l); - lock_data->lock_count++; - l->lock_data= lock_data; + lock->waiting_exclusive.push_front(lock_data); + lock->lock_data_count++; + lock_data->lock= lock; } } while (1) { it.rewind(); - while ((l= it++)) + while ((lock_data= it++)) { - lock_data= l->lock_data; + lock= lock_data->lock; - if (global_lock.shared_acquired || global_lock.shared_pending) + if (global_lock.active_shared || global_lock.waiting_shared) { /* There is active or pending global shared lock we have @@ -580,8 +581,8 @@ bool mdl_acquire_exclusive_locks(MDL_CONTEXT *context) signalled= TRUE; break; } - else if (!lock_data->active_exclusive.is_empty() || - !lock_data->active_shared_waiting_upgrade.is_empty()) + else if (!lock->active_exclusive.is_empty() || + !lock->active_shared_waiting_upgrade.is_empty()) { /* Exclusive MDL owner won't wait on table-level lock the same @@ -591,13 +592,14 @@ bool mdl_acquire_exclusive_locks(MDL_CONTEXT *context) signalled= TRUE; break; } - else if ((lh= lock_data->active_shared.head())) + else if ((conf_lock_data= lock->active_shared.head())) { - signalled= notify_thread_having_shared_lock(thd, lh->ctx->thd); + signalled= notify_thread_having_shared_lock(thd, + conf_lock_data->ctx->thd); break; } } - if (!l) + if (!lock_data) break; if (signalled) pthread_cond_wait(&COND_mdl, &LOCK_mdl); @@ -617,15 +619,16 @@ bool mdl_acquire_exclusive_locks(MDL_CONTEXT *context) { /* Remove our pending lock requests from the locks. */ it.rewind(); - while ((l= it++)) + while ((lock_data= it++)) { - DBUG_ASSERT(l->type == MDL_EXCLUSIVE && l->state == MDL_PENDING); - release_lock(l); + DBUG_ASSERT(lock_data->type == MDL_EXCLUSIVE && + lock_data->state == MDL_PENDING); + release_lock(lock_data); /* Return lock request to its initial state. */ - l->type= MDL_SHARED; - l->prio= MDL_NORMAL_PRIO; - l->is_upgradable= FALSE; - context->locks.remove(l); + lock_data->type= MDL_SHARED; + lock_data->prio= MDL_NORMAL_PRIO; + lock_data->is_upgradable= FALSE; + context->locks.remove(lock_data); } /* Pending requests for shared locks can be satisfied now. */ pthread_cond_broadcast(&COND_mdl); @@ -634,20 +637,20 @@ bool mdl_acquire_exclusive_locks(MDL_CONTEXT *context) } } it.rewind(); - while ((l= it++)) + while ((lock_data= it++)) { - global_lock.intention_exclusive_acquired++; - lock_data= l->lock_data; - lock_data->waiting_exclusive.remove(l); - lock_data->active_exclusive.push_front(l); - l->state= MDL_ACQUIRED; - if (lock_data->cached_object) - (*lock_data->cached_object_release_hook)(lock_data->cached_object); - lock_data->cached_object= NULL; + global_lock.active_intention_exclusive++; + lock= lock_data->lock; + lock->waiting_exclusive.remove(lock_data); + lock->active_exclusive.push_front(lock_data); + lock_data->state= MDL_ACQUIRED; + if (lock->cached_object) + (*lock->cached_object_release_hook)(lock->cached_object); + lock->cached_object= NULL; } /* As a side-effect THD::exit_cond() unlocks LOCK_mdl. */ thd->exit_cond(old_msg); - return FALSE; + return FALSE; } @@ -676,9 +679,9 @@ bool mdl_upgrade_shared_lock_to_exclusive(MDL_CONTEXT *context, int type, char key[MAX_DBKEY_LENGTH]; uint key_length; bool signalled= FALSE; - MDL_LOCK *l, *lh; - MDL_LOCK_DATA *lock_data; - I_P_List_iterator<MDL_LOCK, MDL_LOCK_context> it(context->locks); + MDL_LOCK_DATA *lock_data, *conf_lock_data; + MDL_LOCK *lock; + I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(context->locks); const char *old_msg; THD *thd= context->thd; @@ -696,41 +699,43 @@ bool mdl_upgrade_shared_lock_to_exclusive(MDL_CONTEXT *context, int type, old_msg= thd->enter_cond(&COND_mdl, &LOCK_mdl, "Waiting for table"); - while ((l= it++)) - if (l->key_length == key_length && !memcmp(l->key, key, key_length) && - l->type == MDL_SHARED) + while ((lock_data= it++)) + if (lock_data->key_length == key_length && + !memcmp(lock_data->key, key, key_length) && + lock_data->type == MDL_SHARED) { DBUG_PRINT("info", ("found shared lock for upgrade")); - DBUG_ASSERT(l->state == MDL_ACQUIRED); - DBUG_ASSERT(l->is_upgradable); - l->state= MDL_PENDING_UPGRADE; - lock_data= l->lock_data; - lock_data->active_shared.remove(l); - lock_data->active_shared_waiting_upgrade.push_front(l); + DBUG_ASSERT(lock_data->state == MDL_ACQUIRED); + DBUG_ASSERT(lock_data->is_upgradable); + lock_data->state= MDL_PENDING_UPGRADE; + lock= lock_data->lock; + lock->active_shared.remove(lock_data); + lock->active_shared_waiting_upgrade.push_front(lock_data); } while (1) { DBUG_PRINT("info", ("looking at conflicting locks")); it.rewind(); - while ((l= it++)) + while ((lock_data= it++)) { - if (l->state == MDL_PENDING_UPGRADE) + if (lock_data->state == MDL_PENDING_UPGRADE) { - DBUG_ASSERT(l->type == MDL_SHARED); + DBUG_ASSERT(lock_data->type == MDL_SHARED); - lock_data= l->lock_data; + lock= lock_data->lock; - DBUG_ASSERT(global_lock.shared_acquired == 0 && - global_lock.intention_exclusive_acquired); + DBUG_ASSERT(global_lock.active_shared == 0 && + global_lock.active_intention_exclusive); - if ((lh= lock_data->active_shared.head())) + if ((conf_lock_data= lock->active_shared.head())) { DBUG_PRINT("info", ("found active shared locks")); - signalled= notify_thread_having_shared_lock(thd, lh->ctx->thd); + signalled= notify_thread_having_shared_lock(thd, + conf_lock_data->ctx->thd); break; } - else if (!lock_data->active_exclusive.is_empty()) + else if (!lock->active_exclusive.is_empty()) { DBUG_PRINT("info", ("found active exclusive locks")); signalled= TRUE; @@ -738,7 +743,7 @@ bool mdl_upgrade_shared_lock_to_exclusive(MDL_CONTEXT *context, int type, } } } - if (!l) + if (!lock_data) break; if (signalled) pthread_cond_wait(&COND_mdl, &LOCK_mdl); @@ -758,14 +763,14 @@ bool mdl_upgrade_shared_lock_to_exclusive(MDL_CONTEXT *context, int type, if (thd->killed) { it.rewind(); - while ((l= it++)) - if (l->state == MDL_PENDING_UPGRADE) + while ((lock_data= it++)) + if (lock_data->state == MDL_PENDING_UPGRADE) { - DBUG_ASSERT(l->type == MDL_SHARED); - l->state= MDL_ACQUIRED; - lock_data= l->lock_data; - lock_data->active_shared_waiting_upgrade.remove(l); - lock_data->active_shared.push_front(l); + DBUG_ASSERT(lock_data->type == MDL_SHARED); + lock_data->state= MDL_ACQUIRED; + lock= lock_data->lock; + lock->active_shared_waiting_upgrade.remove(lock_data); + lock->active_shared.push_front(lock_data); } /* Pending requests for shared locks can be satisfied now. */ pthread_cond_broadcast(&COND_mdl); @@ -775,18 +780,18 @@ bool mdl_upgrade_shared_lock_to_exclusive(MDL_CONTEXT *context, int type, } it.rewind(); - while ((l= it++)) - if (l->state == MDL_PENDING_UPGRADE) + while ((lock_data= it++)) + if (lock_data->state == MDL_PENDING_UPGRADE) { - DBUG_ASSERT(l->type == MDL_SHARED); - lock_data= l->lock_data; - lock_data->active_shared_waiting_upgrade.remove(l); - lock_data->active_exclusive.push_front(l); - l->type= MDL_EXCLUSIVE; - l->state= MDL_ACQUIRED; - if (lock_data->cached_object) - (*lock_data->cached_object_release_hook)(lock_data->cached_object); - lock_data->cached_object= 0; + DBUG_ASSERT(lock_data->type == MDL_SHARED); + lock= lock_data->lock; + lock->active_shared_waiting_upgrade.remove(lock_data); + lock->active_exclusive.push_front(lock_data); + lock_data->type= MDL_EXCLUSIVE; + lock_data->state= MDL_ACQUIRED; + if (lock->cached_object) + (*lock->cached_object_release_hook)(lock->cached_object); + lock->cached_object= 0; } /* As a side-effect THD::exit_cond() unlocks LOCK_mdl. */ @@ -817,40 +822,42 @@ bool mdl_upgrade_shared_lock_to_exclusive(MDL_CONTEXT *context, int type, it gives sligthly more false negatives. */ -bool mdl_try_acquire_exclusive_lock(MDL_CONTEXT *context, MDL_LOCK *l) +bool mdl_try_acquire_exclusive_lock(MDL_CONTEXT *context, + MDL_LOCK_DATA *lock_data) { - MDL_LOCK_DATA *lock_data; + MDL_LOCK *lock; - DBUG_ASSERT(l->type == MDL_EXCLUSIVE && l->state == MDL_PENDING); + DBUG_ASSERT(lock_data->type == MDL_EXCLUSIVE && + lock_data->state == MDL_PENDING); safe_mutex_assert_not_owner(&LOCK_open); pthread_mutex_lock(&LOCK_mdl); - if (!(lock_data= (MDL_LOCK_DATA *)my_hash_search(&mdl_locks, (uchar*)l->key, - l->key_length))) + if (!(lock= (MDL_LOCK *)my_hash_search(&mdl_locks, (uchar*)lock_data->key, + lock_data->key_length))) { - lock_data= get_lock_data_object(); - lock_data->active_exclusive.push_front(l); - lock_data->lock_count= 1; - my_hash_insert(&mdl_locks, (uchar*)lock_data); - l->state= MDL_ACQUIRED; - l->lock_data= lock_data; - lock_data= 0; - global_lock.intention_exclusive_acquired++; + lock= get_lock_object(); + lock->active_exclusive.push_front(lock_data); + lock->lock_data_count= 1; + my_hash_insert(&mdl_locks, (uchar*)lock); + lock_data->state= MDL_ACQUIRED; + lock_data->lock= lock; + lock= 0; + global_lock.active_intention_exclusive++; } pthread_mutex_unlock(&LOCK_mdl); /* FIXME: We can't leave pending MDL_EXCLUSIVE lock request in the list since - for such locks we assume that they have MDL_LOCK::lock properly set. + for such locks we assume that they have MDL_LOCK_DATA::lock properly set. Long term we should clearly define relation between lock types, - presence in the context lists and MDL_LOCK::lock values. + presence in the context lists and MDL_LOCK_DATA::lock values. */ - if (lock_data) - context->locks.remove(l); + if (lock) + context->locks.remove(lock_data); - return lock_data; + return lock; } @@ -859,7 +866,7 @@ bool mdl_try_acquire_exclusive_lock(MDL_CONTEXT *context, MDL_LOCK *l) Holding this lock will block all requests for exclusive locks and shared locks which can be potentially upgraded to exclusive - (see MDL_LOCK::is_upgradable). + (see MDL_LOCK_DATA::is_upgradable). @param context Current metadata locking context. @@ -878,20 +885,20 @@ bool mdl_acquire_global_shared_lock(MDL_CONTEXT *context) pthread_mutex_lock(&LOCK_mdl); - global_lock.shared_pending++; + global_lock.waiting_shared++; old_msg= thd->enter_cond(&COND_mdl, &LOCK_mdl, "Waiting for table"); - while (!thd->killed && global_lock.intention_exclusive_acquired) + while (!thd->killed && global_lock.active_intention_exclusive) pthread_cond_wait(&COND_mdl, &LOCK_mdl); - global_lock.shared_pending--; + global_lock.waiting_shared--; if (thd->killed) { /* As a side-effect THD::exit_cond() unlocks LOCK_mdl. */ thd->exit_cond(old_msg); return TRUE; } - global_lock.shared_acquired++; + global_lock.active_shared++; context->has_global_shared_lock= TRUE; /* As a side-effect THD::exit_cond() unlocks LOCK_mdl. */ thd->exit_cond(old_msg); @@ -916,9 +923,9 @@ bool mdl_acquire_global_shared_lock(MDL_CONTEXT *context) bool mdl_wait_for_locks(MDL_CONTEXT *context) { - MDL_LOCK *l; MDL_LOCK_DATA *lock_data; - I_P_List_iterator<MDL_LOCK, MDL_LOCK_context> it(context->locks); + MDL_LOCK *lock; + I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(context->locks); const char *old_msg; THD *thd= context->thd; @@ -941,24 +948,24 @@ bool mdl_wait_for_locks(MDL_CONTEXT *context) pthread_mutex_lock(&LOCK_mdl); old_msg= thd->enter_cond(&COND_mdl, &LOCK_mdl, "Waiting for table"); it.rewind(); - while ((l= it++)) + while ((lock_data= it++)) { - DBUG_ASSERT(l->state == MDL_PENDING); - if ((l->is_upgradable || l->type == MDL_EXCLUSIVE) && - (global_lock.shared_acquired || global_lock.shared_pending)) + DBUG_ASSERT(lock_data->state == MDL_PENDING); + if ((lock_data->is_upgradable || lock_data->type == MDL_EXCLUSIVE) && + (global_lock.active_shared || global_lock.waiting_shared)) break; /* To avoid starvation we don't wait if we have pending MDL_EXCLUSIVE lock. */ - if (l->type == MDL_SHARED && - (lock_data= (MDL_LOCK_DATA *)my_hash_search(&mdl_locks, (uchar*)l->key, - l->key_length)) && - !(lock_data->active_exclusive.is_empty() && - lock_data->active_shared_waiting_upgrade.is_empty() && - lock_data->waiting_exclusive.is_empty())) + if (lock_data->type == MDL_SHARED && + (lock= (MDL_LOCK *)my_hash_search(&mdl_locks, (uchar*)lock_data->key, + lock_data->key_length)) && + !(lock->active_exclusive.is_empty() && + lock->active_shared_waiting_upgrade.is_empty() && + lock->waiting_exclusive.is_empty())) break; } - if (!l) + if (!lock_data) { pthread_mutex_unlock(&LOCK_mdl); break; @@ -976,50 +983,51 @@ bool mdl_wait_for_locks(MDL_CONTEXT *context) ownership of which is represented by lock request object. */ -static void release_lock(MDL_LOCK *l) +static void release_lock(MDL_LOCK_DATA *lock_data) { - MDL_LOCK_DATA *lock_data; + MDL_LOCK *lock; DBUG_ENTER("release_lock"); - DBUG_PRINT("enter", ("db=%s name=%s", l->key + 4, - l->key + 4 + strlen(l->key + 4) + 1)); + DBUG_PRINT("enter", ("db=%s name=%s", lock_data->key + 4, + lock_data->key + 4 + strlen(lock_data->key + 4) + 1)); - lock_data= l->lock_data; - if (lock_data->has_one_lock()) + lock= lock_data->lock; + if (lock->has_one_lock_data()) { - my_hash_delete(&mdl_locks, (uchar *)lock_data); + my_hash_delete(&mdl_locks, (uchar *)lock); DBUG_PRINT("info", ("releasing cached_object cached_object=%p", - lock_data->cached_object)); - if (lock_data->cached_object) - (*lock_data->cached_object_release_hook)(lock_data->cached_object); - release_lock_data_object(lock_data); - if (l->type == MDL_EXCLUSIVE && l->state == MDL_ACQUIRED || - l->type == MDL_SHARED && l->state == MDL_ACQUIRED && l->is_upgradable) - global_lock.intention_exclusive_acquired--; + lock->cached_object)); + if (lock->cached_object) + (*lock->cached_object_release_hook)(lock->cached_object); + release_lock_object(lock); + if (lock_data->type == MDL_EXCLUSIVE && lock_data->state == MDL_ACQUIRED || + lock_data->type == MDL_SHARED && lock_data->state == MDL_ACQUIRED && + lock_data->is_upgradable) + global_lock.active_intention_exclusive--; } else { - switch (l->type) + switch (lock_data->type) { case MDL_SHARED: - lock_data->active_shared.remove(l); - if (l->is_upgradable) - global_lock.intention_exclusive_acquired--; + lock->active_shared.remove(lock_data); + if (lock_data->is_upgradable) + global_lock.active_intention_exclusive--; break; case MDL_EXCLUSIVE: - if (l->state == MDL_PENDING) - lock_data->waiting_exclusive.remove(l); + if (lock_data->state == MDL_PENDING) + lock->waiting_exclusive.remove(lock_data); else { - lock_data->active_exclusive.remove(l); - global_lock.intention_exclusive_acquired--; + lock->active_exclusive.remove(lock_data); + global_lock.active_intention_exclusive--; } break; default: /* TODO Really? How about problems during lock upgrade ? */ DBUG_ASSERT(0); } - lock_data->lock_count--; + lock->lock_data_count--; } DBUG_VOID_RETURN; @@ -1040,28 +1048,28 @@ static void release_lock(MDL_LOCK *l) void mdl_release_locks(MDL_CONTEXT *context) { - MDL_LOCK *l; - I_P_List_iterator<MDL_LOCK, MDL_LOCK_context> it(context->locks); + MDL_LOCK_DATA *lock_data; + I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(context->locks); DBUG_ENTER("mdl_release_locks"); safe_mutex_assert_not_owner(&LOCK_open); pthread_mutex_lock(&LOCK_mdl); - while ((l= it++)) + while ((lock_data= it++)) { - DBUG_PRINT("info", ("found lock to release l=%p", l)); + DBUG_PRINT("info", ("found lock to release lock_data=%p", lock_data)); /* We should not release locks which pending shared locks as these are not associated with lock object and don't present in its lists. Allows us to avoid problems in open_tables() in case of back-off */ - if (!(l->type == MDL_SHARED && l->state == MDL_PENDING)) + if (!(lock_data->type == MDL_SHARED && lock_data->state == MDL_PENDING)) { - release_lock(l); - l->state= MDL_PENDING; + release_lock(lock_data); + lock_data->state= MDL_PENDING; #ifndef DBUG_OFF - l->lock_data= 0; + lock_data->lock= 0; #endif } /* @@ -1091,28 +1099,28 @@ void mdl_release_locks(MDL_CONTEXT *context) void mdl_release_exclusive_locks(MDL_CONTEXT *context) { - MDL_LOCK *l; - I_P_List_iterator<MDL_LOCK, MDL_LOCK_context> it(context->locks); + MDL_LOCK_DATA *lock_data; + I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(context->locks); safe_mutex_assert_not_owner(&LOCK_open); pthread_mutex_lock(&LOCK_mdl); - while ((l= it++)) + while ((lock_data= it++)) { - if (l->type == MDL_EXCLUSIVE) + if (lock_data->type == MDL_EXCLUSIVE) { - DBUG_ASSERT(l->state == MDL_ACQUIRED); - release_lock(l); + DBUG_ASSERT(lock_data->state == MDL_ACQUIRED); + release_lock(lock_data); #ifndef DBUG_OFF - l->ctx= 0; - l->lock_data= 0; + lock_data->ctx= 0; + lock_data->lock= 0; #endif - l->state= MDL_PENDING; + lock_data->state= MDL_PENDING; /* Return lock request to its initial state. */ - l->type= MDL_SHARED; - l->prio= MDL_NORMAL_PRIO; - l->is_upgradable= FALSE; - context->locks.remove(l); + lock_data->type= MDL_SHARED; + lock_data->prio= MDL_NORMAL_PRIO; + lock_data->is_upgradable= FALSE; + context->locks.remove(lock_data); } } pthread_cond_broadcast(&COND_mdl); @@ -1124,29 +1132,29 @@ void mdl_release_exclusive_locks(MDL_CONTEXT *context) Release a lock. Removes the lock from the context. - @param context Context containing lock in question - @param lock Lock to be released + @param context Context containing lock in question + @param lock_data Lock to be released @note Resets lock request for lock released back to its initial state (i.e.sets type and priority to MDL_SHARED and MDL_NORMAL_PRIO). */ -void mdl_release_lock(MDL_CONTEXT *context, MDL_LOCK *lr) +void mdl_release_lock(MDL_CONTEXT *context, MDL_LOCK_DATA *lock_data) { safe_mutex_assert_not_owner(&LOCK_open); pthread_mutex_lock(&LOCK_mdl); - release_lock(lr); + release_lock(lock_data); #ifndef DBUG_OFF - lr->ctx= 0; - lr->lock_data= 0; + lock_data->ctx= 0; + lock_data->lock= 0; #endif - lr->state= MDL_PENDING; + lock_data->state= MDL_PENDING; /* Return lock request to its initial state. */ - lr->type= MDL_SHARED; - lr->prio= MDL_NORMAL_PRIO; - lr->is_upgradable= FALSE; - context->locks.remove(lr); + lock_data->type= MDL_SHARED; + lock_data->prio= MDL_NORMAL_PRIO; + lock_data->is_upgradable= FALSE; + context->locks.remove(lock_data); pthread_cond_broadcast(&COND_mdl); pthread_mutex_unlock(&LOCK_mdl); } @@ -1161,23 +1169,23 @@ void mdl_release_lock(MDL_CONTEXT *context, MDL_LOCK *lr) void mdl_downgrade_exclusive_locks(MDL_CONTEXT *context) { - MDL_LOCK *l; MDL_LOCK_DATA *lock_data; - I_P_List_iterator<MDL_LOCK, MDL_LOCK_context> it(context->locks); + MDL_LOCK *lock; + I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(context->locks); safe_mutex_assert_not_owner(&LOCK_open); pthread_mutex_lock(&LOCK_mdl); - while ((l= it++)) - if (l->type == MDL_EXCLUSIVE) + while ((lock_data= it++)) + if (lock_data->type == MDL_EXCLUSIVE) { - DBUG_ASSERT(l->state == MDL_ACQUIRED); - if (!l->is_upgradable) - global_lock.intention_exclusive_acquired--; - lock_data= l->lock_data; - lock_data->active_exclusive.remove(l); - l->type= MDL_SHARED; - lock_data->active_shared.push_front(l); + DBUG_ASSERT(lock_data->state == MDL_ACQUIRED); + if (!lock_data->is_upgradable) + global_lock.active_intention_exclusive--; + lock= lock_data->lock; + lock->active_exclusive.remove(lock_data); + lock_data->type= MDL_SHARED; + lock->active_shared.push_front(lock_data); } pthread_cond_broadcast(&COND_mdl); pthread_mutex_unlock(&LOCK_mdl); @@ -1196,7 +1204,7 @@ void mdl_release_global_shared_lock(MDL_CONTEXT *context) DBUG_ASSERT(context->has_global_shared_lock); pthread_mutex_lock(&LOCK_mdl); - global_lock.shared_acquired--; + global_lock.active_shared--; context->has_global_shared_lock= FALSE; pthread_cond_broadcast(&COND_mdl); pthread_mutex_unlock(&LOCK_mdl); @@ -1221,15 +1229,18 @@ bool mdl_is_exclusive_lock_owner(MDL_CONTEXT *context, int type, { char key[MAX_DBKEY_LENGTH]; uint key_length; - MDL_LOCK *l; - I_P_List_iterator<MDL_LOCK, MDL_LOCK_context> it(context->locks); + MDL_LOCK_DATA *lock_data; + I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(context->locks); int4store(key, type); key_length= (uint) (strmov(strmov(key+4, db)+1, name)-key)+1; - while ((l= it++) && (l->key_length != key_length || memcmp(l->key, key, key_length))) + while ((lock_data= it++) && + (lock_data->key_length != key_length || + memcmp(lock_data->key, key, key_length))) continue; - return (l && l->type == MDL_EXCLUSIVE && l->state == MDL_ACQUIRED); + return (lock_data && lock_data->type == MDL_EXCLUSIVE && + lock_data->state == MDL_ACQUIRED); } @@ -1251,18 +1262,18 @@ bool mdl_is_lock_owner(MDL_CONTEXT *context, int type, const char *db, { char key[MAX_DBKEY_LENGTH]; uint key_length; - MDL_LOCK *l; - I_P_List_iterator<MDL_LOCK, MDL_LOCK_context> it(context->locks); + MDL_LOCK_DATA *lock_data; + I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> it(context->locks); int4store(key, type); key_length= (uint) (strmov(strmov(key+4, db)+1, name)-key)+1; - while ((l= it++) && (l->key_length != key_length || - memcmp(l->key, key, key_length) || - l->state == MDL_PENDING)) + while ((lock_data= it++) && (lock_data->key_length != key_length || + memcmp(lock_data->key, key, key_length) || + lock_data->state == MDL_PENDING)) continue; - return l; + return lock_data; } @@ -1270,21 +1281,22 @@ bool mdl_is_lock_owner(MDL_CONTEXT *context, int type, const char *db, Check if we have any pending exclusive locks which conflict with existing shared lock. - @param l Shared lock against which check should be performed. + @param lock_data Shared lock against which check should be performed. @return TRUE if there are any conflicting locks, FALSE otherwise. */ -bool mdl_has_pending_conflicting_lock(MDL_LOCK *l) +bool mdl_has_pending_conflicting_lock(MDL_LOCK_DATA *lock_data) { bool result; - DBUG_ASSERT(l->type == MDL_SHARED && l->state == MDL_ACQUIRED); + DBUG_ASSERT(lock_data->type == MDL_SHARED && + lock_data->state == MDL_ACQUIRED); safe_mutex_assert_not_owner(&LOCK_open); pthread_mutex_lock(&LOCK_mdl); - result= !(l->lock_data->waiting_exclusive.is_empty() && - l->lock_data->active_shared_waiting_upgrade.is_empty()); + result= !(lock_data->lock->waiting_exclusive.is_empty() && + lock_data->lock->active_shared_waiting_upgrade.is_empty()); pthread_mutex_unlock(&LOCK_mdl); return result; } @@ -1293,7 +1305,7 @@ bool mdl_has_pending_conflicting_lock(MDL_LOCK *l) /** Associate pointer to an opaque object with a lock. - @param l Lock request for the lock with which the + @param lock_data Lock request for the lock with which the object should be associated. @param cached_object Pointer to the object @param release_hook Cleanup function to be called when MDL subsystem @@ -1318,15 +1330,16 @@ bool mdl_has_pending_conflicting_lock(MDL_LOCK *l) lock on this name is released. */ -void mdl_set_cached_object(MDL_LOCK *l, void *cached_object, +void mdl_set_cached_object(MDL_LOCK_DATA *lock_data, void *cached_object, mdl_cached_object_release_hook release_hook) { DBUG_ENTER("mdl_set_cached_object"); - DBUG_PRINT("enter", ("db=%s name=%s cached_object=%p", l->key + 4, - l->key + 4 + strlen(l->key + 4) + 1, + DBUG_PRINT("enter", ("db=%s name=%s cached_object=%p", lock_data->key + 4, + lock_data->key + 4 + strlen(lock_data->key + 4) + 1, cached_object)); - DBUG_ASSERT(l->state == MDL_ACQUIRED || l->state == MDL_PENDING_UPGRADE); + DBUG_ASSERT(lock_data->state == MDL_ACQUIRED || + lock_data->state == MDL_PENDING_UPGRADE); /* TODO: This assumption works now since we do mdl_get_cached_object() @@ -1334,10 +1347,10 @@ void mdl_set_cached_object(MDL_LOCK *l, void *cached_object, this becomes false we will have to call release_hook here and use additional mutex protecting 'cached_object' member. */ - DBUG_ASSERT(!l->lock_data->cached_object); + DBUG_ASSERT(!lock_data->lock->cached_object); - l->lock_data->cached_object= cached_object; - l->lock_data->cached_object_release_hook= release_hook; + lock_data->lock->cached_object= cached_object; + lock_data->lock->cached_object_release_hook= release_hook; DBUG_VOID_RETURN; } @@ -1346,14 +1359,15 @@ void mdl_set_cached_object(MDL_LOCK *l, void *cached_object, /** Get a pointer to an opaque object that associated with the lock. - @param l Lock request for the lock with which the object is - associated. + @param lock_data Lock request for the lock with which the object is + associated. @return Pointer to an opaque object associated with the lock. */ -void* mdl_get_cached_object(MDL_LOCK *l) +void* mdl_get_cached_object(MDL_LOCK_DATA *lock_data) { - DBUG_ASSERT(l->state == MDL_ACQUIRED || l->state == MDL_PENDING_UPGRADE); - return l->lock_data->cached_object; + DBUG_ASSERT(lock_data->state == MDL_ACQUIRED || + lock_data->state == MDL_PENDING_UPGRADE); + return lock_data->lock->cached_object; } diff --git a/sql/mdl.h b/sql/mdl.h index 2b144e250b1..74c90c01730 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -22,8 +22,8 @@ class THD; -struct MDL_LOCK; struct MDL_LOCK_DATA; +struct MDL_LOCK; struct MDL_CONTEXT; /** Type of metadata lock request. */ @@ -54,7 +54,7 @@ enum enum_mdl_prio {MDL_NORMAL_PRIO=0, MDL_HIGH_PRIO}; "key" or "name". */ -struct MDL_LOCK +struct MDL_LOCK_DATA { char *key; uint key_length; @@ -72,17 +72,17 @@ private: /** Pointers for participating in the list of lock requests for this context. */ - MDL_LOCK *next_context; - MDL_LOCK **prev_context; + MDL_LOCK_DATA *next_context; + MDL_LOCK_DATA **prev_context; /** Pointers for participating in the list of satisfied/pending requests for the lock. */ - MDL_LOCK *next_lock; - MDL_LOCK **prev_lock; + MDL_LOCK_DATA *next_lock; + MDL_LOCK_DATA **prev_lock; - friend struct MDL_LOCK_context; - friend struct MDL_LOCK_lock; + friend struct MDL_LOCK_DATA_context; + friend struct MDL_LOCK_DATA_lock; public: /* @@ -90,23 +90,23 @@ public: request is satisified or is present in the list of pending lock requests for particular lock. */ - MDL_LOCK_DATA *lock_data; + MDL_LOCK *lock; MDL_CONTEXT *ctx; }; /** - Helper class which specifies which members of MDL_LOCK are used for + Helper class which specifies which members of MDL_LOCK_DATA are used for participation in the list lock requests belonging to one context. */ -struct MDL_LOCK_context +struct MDL_LOCK_DATA_context { - static inline MDL_LOCK **next_ptr(MDL_LOCK *l) + static inline MDL_LOCK_DATA **next_ptr(MDL_LOCK_DATA *l) { return &l->next_context; } - static inline MDL_LOCK ***prev_ptr(MDL_LOCK *l) + static inline MDL_LOCK_DATA ***prev_ptr(MDL_LOCK_DATA *l) { return &l->prev_context; } @@ -114,17 +114,17 @@ struct MDL_LOCK_context /** - Helper class which specifies which members of MDL_LOCK are used for + Helper class which specifies which members of MDL_LOCK_DATA are used for participation in the list of satisfied/pending requests for the lock. */ -struct MDL_LOCK_lock +struct MDL_LOCK_DATA_lock { - static inline MDL_LOCK **next_ptr(MDL_LOCK *l) + static inline MDL_LOCK_DATA **next_ptr(MDL_LOCK_DATA *l) { return &l->next_lock; } - static inline MDL_LOCK ***prev_ptr(MDL_LOCK *l) + static inline MDL_LOCK_DATA ***prev_ptr(MDL_LOCK_DATA *l) { return &l->prev_lock; } @@ -138,7 +138,7 @@ struct MDL_LOCK_lock struct MDL_CONTEXT { - I_P_List <MDL_LOCK, MDL_LOCK_context> locks; + I_P_List <MDL_LOCK_DATA, MDL_LOCK_DATA_context> locks; bool has_global_shared_lock; THD *thd; }; @@ -153,21 +153,21 @@ void mdl_context_backup_and_reset(MDL_CONTEXT *ctx, MDL_CONTEXT *backup); void mdl_context_restore(MDL_CONTEXT *ctx, MDL_CONTEXT *backup); void mdl_context_merge(MDL_CONTEXT *target, MDL_CONTEXT *source); -void mdl_init_lock(MDL_LOCK *mdl, char *key, int type, const char *db, - const char *name); -MDL_LOCK *mdl_alloc_lock(int type, const char *db, const char *name, - MEM_ROOT *root); -void mdl_add_lock(MDL_CONTEXT *context, MDL_LOCK *lock); +void mdl_init_lock(MDL_LOCK_DATA *lock_data, char *key, 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); +void mdl_add_lock(MDL_CONTEXT *context, MDL_LOCK_DATA *lock_data); void mdl_remove_all_locks(MDL_CONTEXT *context); /** Set type of lock request. Can be only applied to pending locks. */ -inline void mdl_set_lock_type(MDL_LOCK *lock, enum_mdl_type lock_type) +inline void mdl_set_lock_type(MDL_LOCK_DATA *lock_data, enum_mdl_type lock_type) { - DBUG_ASSERT(lock->state == MDL_PENDING); - lock->type= lock_type; + DBUG_ASSERT(lock_data->state == MDL_PENDING); + lock_data->type= lock_type; } /** @@ -175,10 +175,10 @@ inline void mdl_set_lock_type(MDL_LOCK *lock, enum_mdl_type lock_type) for shared locks. */ -inline void mdl_set_lock_priority(MDL_LOCK *lock, enum_mdl_prio prio) +inline void mdl_set_lock_priority(MDL_LOCK_DATA *lock_data, enum_mdl_prio prio) { - DBUG_ASSERT(lock->type == MDL_SHARED && lock->state == MDL_PENDING); - lock->prio= prio; + DBUG_ASSERT(lock_data->type == MDL_SHARED && lock_data->state == MDL_PENDING); + lock_data->prio= prio; } /** @@ -186,24 +186,25 @@ inline void mdl_set_lock_priority(MDL_LOCK *lock, enum_mdl_prio prio) to pending locks. */ -inline void mdl_set_upgradable(MDL_LOCK *lock) +inline void mdl_set_upgradable(MDL_LOCK_DATA *lock_data) { - DBUG_ASSERT(lock->type == MDL_SHARED && lock->state == MDL_PENDING); - lock->is_upgradable= TRUE; + DBUG_ASSERT(lock_data->type == MDL_SHARED && lock_data->state == MDL_PENDING); + lock_data->is_upgradable= TRUE; } -bool mdl_acquire_shared_lock(MDL_LOCK *l, bool *retry); +bool mdl_acquire_shared_lock(MDL_LOCK_DATA *lock_data, bool *retry); bool mdl_acquire_exclusive_locks(MDL_CONTEXT *context); bool mdl_upgrade_shared_lock_to_exclusive(MDL_CONTEXT *context, int type, const char *db, const char *name); -bool mdl_try_acquire_exclusive_lock(MDL_CONTEXT *context, MDL_LOCK *lock); +bool mdl_try_acquire_exclusive_lock(MDL_CONTEXT *context, + MDL_LOCK_DATA *lock_data); bool mdl_acquire_global_shared_lock(MDL_CONTEXT *context); bool mdl_wait_for_locks(MDL_CONTEXT *context); void mdl_release_locks(MDL_CONTEXT *context); void mdl_release_exclusive_locks(MDL_CONTEXT *context); -void mdl_release_lock(MDL_CONTEXT *context, MDL_LOCK *lock); +void mdl_release_lock(MDL_CONTEXT *context, MDL_LOCK_DATA *lock_data); void mdl_downgrade_exclusive_locks(MDL_CONTEXT *context); void mdl_release_global_shared_lock(MDL_CONTEXT *context); @@ -212,7 +213,7 @@ bool mdl_is_exclusive_lock_owner(MDL_CONTEXT *context, int type, const char *db, bool mdl_is_lock_owner(MDL_CONTEXT *context, int type, const char *db, const char *name); -bool mdl_has_pending_conflicting_lock(MDL_LOCK *l); +bool mdl_has_pending_conflicting_lock(MDL_LOCK_DATA *lock_data); inline bool mdl_has_locks(MDL_CONTEXT *context) { @@ -224,9 +225,10 @@ inline bool mdl_has_locks(MDL_CONTEXT *context) Get iterator for walking through all lock requests in the context. */ -inline I_P_List_iterator<MDL_LOCK, MDL_LOCK_context> mdl_get_locks(MDL_CONTEXT *ctx) +inline I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> +mdl_get_locks(MDL_CONTEXT *ctx) { - I_P_List_iterator<MDL_LOCK, MDL_LOCK_context> result(ctx->locks); + I_P_List_iterator<MDL_LOCK_DATA, MDL_LOCK_DATA_context> result(ctx->locks); return result; } @@ -234,9 +236,9 @@ inline I_P_List_iterator<MDL_LOCK, MDL_LOCK_context> mdl_get_locks(MDL_CONTEXT * Give metadata lock request object for the table get table definition cache key corresponding to it. - @param l [in] Lock request object for the table. - @param key [out] LEX_STRING object where table definition cache key - should be put. + @param lock_data [in] Lock request object for the table. + @param key [out] LEX_STRING object where table definition cache key + should be put. @note This key will have the same life-time as this lock request object. @@ -245,16 +247,16 @@ inline I_P_List_iterator<MDL_LOCK, MDL_LOCK_context> mdl_get_locks(MDL_CONTEXT * and memory by avoiding generating these TDC keys from table list. */ -inline void mdl_get_tdc_key(MDL_LOCK *l, LEX_STRING *key) +inline void mdl_get_tdc_key(MDL_LOCK_DATA *lock_data, LEX_STRING *key) { - key->str= l->key + 4; - key->length= l->key_length - 4; + key->str= lock_data->key + 4; + key->length= lock_data->key_length - 4; } typedef void (* mdl_cached_object_release_hook)(void *); -void* mdl_get_cached_object(MDL_LOCK *l); -void mdl_set_cached_object(MDL_LOCK *l, void *cached_object, +void* mdl_get_cached_object(MDL_LOCK_DATA *lock_data); +void mdl_set_cached_object(MDL_LOCK_DATA *lock_data, void *cached_object, mdl_cached_object_release_hook release_hook); #endif diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 14573cd6884..fdf9909f85e 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -3984,9 +3984,10 @@ sp_head::add_used_tables_to_table_list(THD *thd, table->prelocking_placeholder= 1; table->belong_to_view= belong_to_view; table->trg_event_map= stab->trg_event_map; - table->mdl_lock= mdl_alloc_lock(0, table->db, table->table_name, - thd->mdl_el_root ? thd->mdl_el_root : - thd->mem_root); + table->mdl_lock_data= mdl_alloc_lock(0, table->db, table->table_name, + thd->mdl_el_root ? + thd->mdl_el_root : + thd->mem_root); /* Everyting else should be zeroed */ @@ -4028,9 +4029,9 @@ sp_add_to_query_tables(THD *thd, LEX *lex, table->lock_type= locktype; table->select_lex= lex->current_select; table->cacheable_table= 1; - table->mdl_lock= mdl_alloc_lock(0, table->db, table->table_name, - thd->mdl_el_root ? thd->mdl_el_root : - thd->mem_root); + table->mdl_lock_data= mdl_alloc_lock(0, table->db, table->table_name, + thd->mdl_el_root ? thd->mdl_el_root : + thd->mem_root); lex->add_to_query_tables(table); return table; } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 13218f3a193..44db7938caf 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1527,7 +1527,7 @@ bool close_thread_table(THD *thd, TABLE **table_ptr) if (table->child_l || table->parent) detach_merge_children(table, TRUE); - table->mdl_lock= 0; + table->mdl_lock_data= 0; if (table->needs_reopen() || thd->version != refresh_version || !table->db_stat) { @@ -2535,7 +2535,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, char key[MAX_DBKEY_LENGTH]; uint key_length; char *alias= table_list->alias; - MDL_LOCK *mdl_lock; + MDL_LOCK_DATA *mdl_lock_data; int error; TABLE_SHARE *share; DBUG_ENTER("open_table"); @@ -2717,8 +2717,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, This is the normal use case. */ - mdl_lock= table_list->mdl_lock; - mdl_add_lock(&thd->mdl_context, mdl_lock); + mdl_lock_data= table_list->mdl_lock_data; + mdl_add_lock(&thd->mdl_context, mdl_lock_data); if (table_list->open_type) { @@ -2731,7 +2731,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, shared locks. This invariant is preserved here and is also enforced by asserts in metadata locking subsystem. */ - mdl_set_lock_type(mdl_lock, MDL_EXCLUSIVE); + mdl_set_lock_type(mdl_lock_data, MDL_EXCLUSIVE); if (mdl_acquire_exclusive_locks(&thd->mdl_context)) DBUG_RETURN(0); } @@ -2740,10 +2740,10 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, bool retry; if (table_list->mdl_upgradable) - mdl_set_upgradable(mdl_lock); - mdl_set_lock_priority(mdl_lock, (flags & MYSQL_LOCK_IGNORE_FLUSH) ? - MDL_HIGH_PRIO : MDL_NORMAL_PRIO); - if (mdl_acquire_shared_lock(mdl_lock, &retry)) + mdl_set_upgradable(mdl_lock_data); + mdl_set_lock_priority(mdl_lock_data, (flags & MYSQL_LOCK_IGNORE_FLUSH) ? + MDL_HIGH_PRIO : MDL_NORMAL_PRIO); + if (mdl_acquire_shared_lock(mdl_lock_data, &retry)) { if (retry) *action= OT_BACK_OFF_AND_RETRY; @@ -2792,7 +2792,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, DBUG_RETURN(0); } - if (!(share= (TABLE_SHARE *)mdl_get_cached_object(mdl_lock))) + if (!(share= (TABLE_SHARE *)mdl_get_cached_object(mdl_lock_data))) { if (!(share= get_table_share_with_create(thd, table_list, key, key_length, OPEN_VIEW, @@ -2867,7 +2867,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, so we need to increase reference counter; */ reference_table_share(share); - mdl_set_cached_object(mdl_lock, share, table_share_release_hook); + mdl_set_cached_object(mdl_lock_data, share, table_share_release_hook); } else { @@ -2978,7 +2978,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (table_list->open_type == TABLE_LIST::OPEN_OR_CREATE) mdl_downgrade_exclusive_locks(&thd->mdl_context); - table->mdl_lock= mdl_lock; + table->mdl_lock_data= mdl_lock_data; table->next=thd->open_tables; /* Link into simple list */ thd->open_tables=table; @@ -3025,7 +3025,7 @@ err_unlock: release_table_share(share); err_unlock2: pthread_mutex_unlock(&LOCK_open); - mdl_release_lock(&thd->mdl_context, mdl_lock); + mdl_release_lock(&thd->mdl_context, mdl_lock_data); DBUG_RETURN(0); } @@ -3167,7 +3167,7 @@ bool reopen_table(TABLE *table) (void) closefrm(&tmp, 1); // close file, free everything goto end; } - tmp.mdl_lock= table->mdl_lock; + tmp.mdl_lock_data= table->mdl_lock_data; table_def_change_share(table, tmp.s); /* Avoid wiping out TABLE's position in new share's used tables list. */ @@ -3981,8 +3981,8 @@ static bool handle_failed_open_table_attempt(THD *thd, TABLE_LIST *table, mdl_remove_all_locks(&thd->mdl_context); break; case OT_DISCOVER: - mdl_set_lock_type(table->mdl_lock, MDL_EXCLUSIVE); - mdl_add_lock(&thd->mdl_context, table->mdl_lock); + mdl_set_lock_type(table->mdl_lock_data, MDL_EXCLUSIVE); + mdl_add_lock(&thd->mdl_context, table->mdl_lock_data); if (mdl_acquire_exclusive_locks(&thd->mdl_context)) return TRUE; pthread_mutex_lock(&LOCK_open); @@ -3995,8 +3995,8 @@ static bool handle_failed_open_table_attempt(THD *thd, TABLE_LIST *table, mdl_release_exclusive_locks(&thd->mdl_context); break; case OT_REPAIR: - mdl_set_lock_type(table->mdl_lock, MDL_EXCLUSIVE); - mdl_add_lock(&thd->mdl_context, table->mdl_lock); + mdl_set_lock_type(table->mdl_lock_data, MDL_EXCLUSIVE); + mdl_add_lock(&thd->mdl_context, table->mdl_lock_data); if (mdl_acquire_exclusive_locks(&thd->mdl_context)) return TRUE; pthread_mutex_lock(&LOCK_open); @@ -8518,7 +8518,7 @@ void expel_table_from_cache(THD *leave_thd, const char *db, const char *table_na static bool tdc_wait_for_old_versions(THD *thd, MDL_CONTEXT *context) { - MDL_LOCK *l; + MDL_LOCK_DATA *lock_data; TABLE_SHARE *share; const char *old_msg; LEX_STRING key; @@ -8534,17 +8534,18 @@ static bool tdc_wait_for_old_versions(THD *thd, MDL_CONTEXT *context) mysql_ha_flush(thd); pthread_mutex_lock(&LOCK_open); - I_P_List_iterator<MDL_LOCK, MDL_LOCK_context> it= mdl_get_locks(context); - while ((l= it++)) + I_P_List_iterator<MDL_LOCK_DATA, + MDL_LOCK_DATA_context> it= mdl_get_locks(context); + while ((lock_data= it++)) { - mdl_get_tdc_key(l, &key); + mdl_get_tdc_key(lock_data, &key); if ((share= (TABLE_SHARE*) my_hash_search(&table_def_cache, (uchar*) key.str, key.length)) && share->version != refresh_version && !share->used_tables.is_empty()) break; } - if (!l) + if (!lock_data) { pthread_mutex_unlock(&LOCK_open); break; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index fb48f32660b..f5c6dfd8986 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -1089,7 +1089,7 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) TABLE *table; bool error; uint path_length; - MDL_LOCK *mdl_lock= 0; + MDL_LOCK_DATA *mdl_lock_data= 0; DBUG_ENTER("mysql_truncate"); bzero((char*) &create_info,sizeof(create_info)); @@ -1164,10 +1164,10 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) tries to get table enging and therefore accesses table in some way without holding any kind of meta-data lock. */ - mdl_lock= mdl_alloc_lock(0, table_list->db, table_list->table_name, - thd->mem_root); - mdl_set_lock_type(mdl_lock, MDL_EXCLUSIVE); - mdl_add_lock(&thd->mdl_context, mdl_lock); + mdl_lock_data= mdl_alloc_lock(0, table_list->db, table_list->table_name, + thd->mem_root); + mdl_set_lock_type(mdl_lock_data, MDL_EXCLUSIVE); + mdl_add_lock(&thd->mdl_context, mdl_lock_data); if (mdl_acquire_exclusive_locks(&thd->mdl_context)) DBUG_RETURN(TRUE); pthread_mutex_lock(&LOCK_open); @@ -1197,13 +1197,13 @@ end: write_bin_log(thd, TRUE, thd->query(), thd->query_length()); my_ok(thd); // This should return record count } - if (mdl_lock) - mdl_release_lock(&thd->mdl_context, mdl_lock); + if (mdl_lock_data) + mdl_release_lock(&thd->mdl_context, mdl_lock_data); } else if (error) { - if (mdl_lock) - mdl_release_lock(&thd->mdl_context, mdl_lock); + if (mdl_lock_data) + mdl_release_lock(&thd->mdl_context, mdl_lock_data); } DBUG_RETURN(error); diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 87e9538b48f..15c73fcadfe 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -125,7 +125,7 @@ static void mysql_ha_hash_free(TABLE_LIST *tables) static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables) { TABLE **table_ptr; - MDL_LOCK *mdl_lock; + MDL_LOCK_DATA *mdl_lock_data; /* Though we could take the table pointer from hash_tables->table, @@ -141,7 +141,7 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables) if (*table_ptr) { (*table_ptr)->file->ha_index_or_rnd_end(); - mdl_lock= (*table_ptr)->mdl_lock; + mdl_lock_data= (*table_ptr)->mdl_lock_data; pthread_mutex_lock(&LOCK_open); if (close_thread_table(thd, table_ptr)) { @@ -149,7 +149,7 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables) broadcast_refresh(); } pthread_mutex_unlock(&LOCK_open); - mdl_release_lock(&thd->handler_mdl_context, mdl_lock); + mdl_release_lock(&thd->handler_mdl_context, mdl_lock_data); } else if (tables->table) { @@ -189,7 +189,7 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables) bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) { TABLE_LIST *hash_tables = NULL; - MDL_LOCK *mdl_lock; + MDL_LOCK_DATA *mdl_lock_data; char *db, *name, *alias, *mdlkey; uint dblen, namelen, aliaslen, counter; int error; @@ -245,7 +245,7 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) &db, (uint) dblen, &name, (uint) namelen, &alias, (uint) aliaslen, - &mdl_lock, sizeof(MDL_LOCK), + &mdl_lock_data, sizeof(MDL_LOCK_DATA), &mdlkey, MAX_DBKEY_LENGTH, NullS))) { @@ -260,8 +260,8 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen) memcpy(hash_tables->db, tables->db, dblen); memcpy(hash_tables->table_name, tables->table_name, namelen); memcpy(hash_tables->alias, tables->alias, aliaslen); - mdl_init_lock(mdl_lock, mdlkey, 0, db, name); - hash_tables->mdl_lock= mdl_lock; + mdl_init_lock(mdl_lock_data, mdlkey, 0, db, name); + hash_tables->mdl_lock_data= mdl_lock_data; /* add to hash */ if (my_hash_insert(&thd->handler_tables_hash, (uchar*) hash_tables)) @@ -798,10 +798,12 @@ void mysql_ha_flush(THD *thd) for (uint i= 0; i < thd->handler_tables_hash.records; i++) { hash_tables= (TABLE_LIST*) my_hash_element(&thd->handler_tables_hash, i); - /* TABLE::mdl_lock is 0 for temporary tables so we need extra check. */ + /* + TABLE::mdl_lock_data is 0 for temporary tables so we need extra check. + */ if (hash_tables->table && - (hash_tables->table->mdl_lock && - mdl_has_pending_conflicting_lock(hash_tables->table->mdl_lock) || + (hash_tables->table->mdl_lock_data && + mdl_has_pending_conflicting_lock(hash_tables->table->mdl_lock_data) || hash_tables->table->needs_reopen())) mysql_ha_close_table(thd, hash_tables); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 2c043922cc8..24939f1cd21 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6534,9 +6534,9 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd, ptr->next_name_resolution_table= NULL; /* Link table in global list (all used tables) */ lex->add_to_query_tables(ptr); - ptr->mdl_lock= mdl_alloc_lock(0 , ptr->db, ptr->table_name, - thd->mdl_el_root ? thd->mdl_el_root : - thd->mem_root); + ptr->mdl_lock_data= mdl_alloc_lock(0 , ptr->db, ptr->table_name, + thd->mdl_el_root ? thd->mdl_el_root : + thd->mem_root); DBUG_RETURN(ptr); } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 236bca76c7d..647f914d28c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3106,7 +3106,7 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table, char key[MAX_DBKEY_LENGTH]; uint key_length; char db_name_buff[NAME_LEN + 1], table_name_buff[NAME_LEN + 1]; - MDL_LOCK mdl_lock; + MDL_LOCK_DATA mdl_lock_data; char mdlkey[MAX_DBKEY_LENGTH]; bool retry; @@ -3133,10 +3133,10 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table, table_list.db= db_name->str; } - mdl_init_lock(&mdl_lock, mdlkey, 0, db_name->str, table_name->str); - table_list.mdl_lock= &mdl_lock; - mdl_add_lock(&thd->mdl_context, &mdl_lock); - mdl_set_lock_priority(&mdl_lock, MDL_HIGH_PRIO); + mdl_init_lock(&mdl_lock_data, mdlkey, 0, db_name->str, table_name->str); + table_list.mdl_lock_data= &mdl_lock_data; + mdl_add_lock(&thd->mdl_context, &mdl_lock_data); + mdl_set_lock_priority(&mdl_lock_data, MDL_HIGH_PRIO); /* TODO: investigate if in this particular situation we can get by @@ -3145,7 +3145,7 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table, */ while (1) { - if (mdl_acquire_shared_lock(&mdl_lock, &retry)) + if (mdl_acquire_shared_lock(&mdl_lock_data, &retry)) { if (!retry || mdl_wait_for_locks(&thd->mdl_context)) { @@ -3212,7 +3212,7 @@ err_unlock: pthread_mutex_unlock(&LOCK_open); err: - mdl_release_lock(&thd->mdl_context, &mdl_lock); + mdl_release_lock(&thd->mdl_context, &mdl_lock_data); thd->clear_error(); return res; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9888dceef54..2a41fe2008c 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4043,15 +4043,15 @@ warn: static bool lock_table_name_if_not_cached(THD *thd, const char *db, const char *table_name, - MDL_LOCK **lock) + MDL_LOCK_DATA **lock_data) { - if (!(*lock= 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; - mdl_set_lock_type(*lock, MDL_EXCLUSIVE); - mdl_add_lock(&thd->mdl_context, *lock); - if (mdl_try_acquire_exclusive_lock(&thd->mdl_context, *lock)) + mdl_set_lock_type(*lock_data, MDL_EXCLUSIVE); + mdl_add_lock(&thd->mdl_context, *lock_data); + if (mdl_try_acquire_exclusive_lock(&thd->mdl_context, *lock_data)) { - *lock= 0; + *lock_data= 0; } return FALSE; } @@ -4067,7 +4067,7 @@ bool mysql_create_table(THD *thd, const char *db, const char *table_name, bool internal_tmp_table, uint select_field_count) { - MDL_LOCK *target_lock= 0; + MDL_LOCK_DATA *target_lock_data= 0; bool result; DBUG_ENTER("mysql_create_table"); @@ -4090,12 +4090,12 @@ bool mysql_create_table(THD *thd, const char *db, const char *table_name, if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE)) { - if (lock_table_name_if_not_cached(thd, db, table_name, &target_lock)) + if (lock_table_name_if_not_cached(thd, db, table_name, &target_lock_data)) { result= TRUE; goto unlock; } - if (!target_lock) + if (!target_lock_data) { if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) { @@ -4121,7 +4121,7 @@ bool mysql_create_table(THD *thd, const char *db, const char *table_name, select_field_count); unlock: - if (target_lock) + if (target_lock_data) mdl_release_exclusive_locks(&thd->mdl_context); pthread_mutex_lock(&LOCK_lock_db); if (!--creating_table && creating_database) @@ -4359,7 +4359,7 @@ static int send_check_errmsg(THD *thd, TABLE_LIST* table, static int prepare_for_restore(THD* thd, TABLE_LIST* table, HA_CHECK_OPT *check_opt) { - MDL_LOCK *mdl_lock= 0; + MDL_LOCK_DATA *mdl_lock_data= 0; DBUG_ENTER("prepare_for_restore"); if (table->table) // do not overwrite existing tables on restore @@ -4383,10 +4383,10 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, build_table_filename(dst_path, sizeof(dst_path) - 1, db, table_name, reg_ext, 0); - mdl_lock= mdl_alloc_lock(0, table->db, table->table_name, - thd->mem_root); - mdl_set_lock_type(mdl_lock, MDL_EXCLUSIVE); - mdl_add_lock(&thd->mdl_context, mdl_lock); + mdl_lock_data= mdl_alloc_lock(0, table->db, table->table_name, + thd->mem_root); + mdl_set_lock_type(mdl_lock_data, MDL_EXCLUSIVE); + mdl_add_lock(&thd->mdl_context, mdl_lock_data); if (mdl_acquire_exclusive_locks(&thd->mdl_context)) DBUG_RETURN(TRUE); pthread_mutex_lock(&LOCK_open); @@ -4395,13 +4395,13 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, if (my_copy(src_path, dst_path, MYF(MY_WME))) { - mdl_release_lock(&thd->mdl_context, mdl_lock); + mdl_release_lock(&thd->mdl_context, mdl_lock_data); DBUG_RETURN(send_check_errmsg(thd, table, "restore", "Failed copying .frm file")); } if (mysql_truncate(thd, table, 1)) { - mdl_release_lock(&thd->mdl_context, mdl_lock); + mdl_release_lock(&thd->mdl_context, mdl_lock_data); DBUG_RETURN(send_check_errmsg(thd, table, "restore", "Failed generating table from .frm file")); } @@ -4415,8 +4415,8 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table, if (reopen_name_locked_table(thd, table)) { pthread_mutex_unlock(&LOCK_open); - if (mdl_lock) - mdl_release_lock(&thd->mdl_context, mdl_lock); + if (mdl_lock_data) + mdl_release_lock(&thd->mdl_context, mdl_lock_data); DBUG_RETURN(send_check_errmsg(thd, table, "restore", "Failed to open partially restored table")); } @@ -4436,7 +4436,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, char from[FN_REFLEN],tmp[FN_REFLEN+32]; const char **ext; MY_STAT stat_info; - MDL_LOCK *mdl_lock; + MDL_LOCK_DATA *mdl_lock_data; DBUG_ENTER("prepare_for_repair"); if (!(check_opt->sql_flags & TT_USEFRM)) @@ -4452,10 +4452,10 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, TODO: Check that REPAIR's code also conforms to meta-data locking protocol. Fix if it is not. */ - mdl_lock= mdl_alloc_lock(0, table_list->db, table_list->table_name, - thd->mem_root); - mdl_set_lock_type(mdl_lock, MDL_EXCLUSIVE); - mdl_add_lock(&thd->mdl_context, mdl_lock); + mdl_lock_data= mdl_alloc_lock(0, table_list->db, table_list->table_name, + thd->mem_root); + mdl_set_lock_type(mdl_lock_data, MDL_EXCLUSIVE); + mdl_add_lock(&thd->mdl_context, mdl_lock_data); if (mdl_acquire_exclusive_locks(&thd->mdl_context)) DBUG_RETURN(0); @@ -5303,7 +5303,7 @@ bool mysql_create_like_schema_frm(THD* thd, TABLE_LIST* schema_table, bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, HA_CREATE_INFO *create_info) { - MDL_LOCK *target_lock= 0; + MDL_LOCK_DATA *target_lock_data= 0; char src_path[FN_REFLEN], dst_path[FN_REFLEN + 1]; uint dst_path_length; char *db= table->db; @@ -5360,9 +5360,9 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, } else { - if (lock_table_name_if_not_cached(thd, db, table_name, &target_lock)) + if (lock_table_name_if_not_cached(thd, db, table_name, &target_lock_data)) goto err; - if (!target_lock) + if (!target_lock_data) goto table_exists; dst_path_length= build_table_filename(dst_path, sizeof(dst_path) - 1, db, table_name, reg_ext, 0); @@ -5538,7 +5538,7 @@ binlog: res= FALSE; err: - if (target_lock) + if (target_lock_data) mdl_release_exclusive_locks(&thd->mdl_context); DBUG_RETURN(res); } @@ -6477,7 +6477,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, uint order_num, ORDER *order, bool ignore) { TABLE *table, *new_table= 0; - MDL_LOCK *target_lock= 0; + MDL_LOCK_DATA *target_lock_data= 0; int error= 0; char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN + 1]; char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias; @@ -6700,9 +6700,10 @@ view_err: } else { - if (lock_table_name_if_not_cached(thd, new_db, new_name, &target_lock)) + if (lock_table_name_if_not_cached(thd, new_db, new_name, + &target_lock_data)) DBUG_RETURN(TRUE); - if (!target_lock) + if (!target_lock_data) { my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias); DBUG_RETURN(TRUE); @@ -7128,7 +7129,7 @@ view_err: #ifdef WITH_PARTITION_STORAGE_ENGINE if (fast_alter_partition) { - DBUG_ASSERT(!target_lock); + DBUG_ASSERT(!target_lock_data); DBUG_RETURN(fast_alter_partition_table(thd, table, alter_info, create_info, table_list, db, table_name, @@ -7632,7 +7633,7 @@ err: alter_info->datetime_field->field_name); thd->abort_on_warning= save_abort_on_warning; } - if (target_lock) + if (target_lock_data) mdl_release_exclusive_locks(&thd->mdl_context); DBUG_RETURN(TRUE); diff --git a/sql/table.cc b/sql/table.cc index c8814cff685..3943dc8e50b 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4832,8 +4832,9 @@ size_t max_row_length(TABLE *table, const uchar *data) void alloc_mdl_locks(TABLE_LIST *table_list, MEM_ROOT *root) { for ( ; table_list ; table_list= table_list->next_global) - table_list->mdl_lock= mdl_alloc_lock(0, table_list->db, - table_list->table_name, root); + table_list->mdl_lock_data= mdl_alloc_lock(0, table_list->db, + table_list->table_name, + root); } diff --git a/sql/table.h b/sql/table.h index e64111ef988..601f1e154c9 100644 --- a/sql/table.h +++ b/sql/table.h @@ -30,7 +30,7 @@ class st_select_lex; class partition_info; class COND_EQUAL; class Security_context; -struct MDL_LOCK; +struct MDL_LOCK_DATA; /*************************************************************************/ @@ -820,7 +820,7 @@ public: partition_info *part_info; /* Partition related information */ bool no_partitions_used; /* If true, all partitions have been pruned away */ #endif - MDL_LOCK *mdl_lock; + MDL_LOCK_DATA *mdl_lock_data; bool fill_item_list(List<Item> *item_list) const; void reset_item_list(List<Item> *item_list) const; @@ -1423,7 +1423,7 @@ struct TABLE_LIST uint table_open_method; enum enum_schema_table_state schema_table_state; - MDL_LOCK *mdl_lock; + MDL_LOCK_DATA *mdl_lock_data; void calc_md5(char *buffer); void set_underlying_merge(); |