diff options
author | Konstantin Osipov <kostja@sun.com> | 2009-12-01 18:20:43 +0300 |
---|---|---|
committer | Konstantin Osipov <kostja@sun.com> | 2009-12-01 18:20:43 +0300 |
commit | f7ba9dafd5f92863ffd9a0b3ebee7147d73bbb21 (patch) | |
tree | 861487d2be89b022dcce6bfc3f0fae919ee697e6 | |
parent | db3f97c3fb2f0e39d56fc813877ff9d38b61af2f (diff) | |
download | mariadb-git-f7ba9dafd5f92863ffd9a0b3ebee7147d73bbb21.tar.gz |
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.
sql/mdl.cc:
Changed mdl_acquire_shared_lock() signature to accept MDL_CONTEXT
as one of arguments as described in specification.
sql/mdl.h:
Changed mdl_acquire_shared_lock() signature to accept MDL_CONTEXT
as one of arguments as described in specification.
sql/sql_base.cc:
Changed mdl_acquire_shared_lock() signature to accept MDL_CONTEXT
as one of arguments as described in specification.
Renamed handle_failed_open_table_attempt() to
recover_from_failed_open_table_attempt() as suggested by review.
Added comment clarifying why we need to check TABLE::db_stat
while looking at TABLE instances open by other threads.
sql/sql_show.cc:
Changed mdl_acquire_shared_lock() signature to accept MDL_CONTEXT
as one of arguments as described in specification.
-rw-r--r-- | sql/mdl.cc | 8 | ||||
-rw-r--r-- | sql/mdl.h | 3 | ||||
-rw-r--r-- | sql/sql_base.cc | 23 | ||||
-rw-r--r-- | sql/sql_show.cc | 2 |
4 files changed, 25 insertions, 11 deletions
diff --git a/sql/mdl.cc b/sql/mdl.cc index dbf08101159..d3d067cfb9b 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -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. + @param context [in] Context containing request for lock @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 @@ -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. */ -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; *retry= FALSE; DBUG_ASSERT(is_shared(lock_data) && lock_data->state == MDL_PENDING); + DBUG_ASSERT(lock_data->ctx == context); + 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) { my_error(ER_CANT_UPDATE_WITH_READLOCK, MYF(0)); diff --git a/sql/mdl.h b/sql/mdl.h index f99f38d6285..b192980ebaa 100644 --- a/sql/mdl.h +++ b/sql/mdl.h @@ -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; } -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_upgrade_shared_lock_to_exclusive(MDL_CONTEXT *context, MDL_LOCK_DATA *lock_data); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 8665cebc4ed..633184cde79 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2837,7 +2837,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (flags & MYSQL_LOCK_IGNORE_FLUSH) 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) *action= OT_BACK_OFF_AND_RETRY; @@ -4044,18 +4044,21 @@ end_with_lock_open: /** - 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 table Table list element for table that caused problem @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 TRUE - Error */ -static bool handle_failed_open_table_attempt(THD *thd, TABLE_LIST *table, - enum_open_table_action action) +static bool +recover_from_failed_open_table_attempt(THD *thd, TABLE_LIST *table, + enum_open_table_action action) { bool result= FALSE; @@ -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 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; goto err; @@ -4997,7 +5000,7 @@ retry: might have been acquired successfully. */ 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; } @@ -8530,7 +8533,13 @@ bool notify_thread_having_shared_lock(THD *thd, THD *in_use) thd_table ; 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) signalled|= mysql_lock_abort_for_thread(thd, thd_table); } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 3d4c0a5aaf7..9df31c7c2ad 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3145,7 +3145,7 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table, */ 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)) { |