From e3b3907c4f6f6dbfd650272e7c65880d04e5789e Mon Sep 17 00:00:00 2001 From: Konstantin Osipov Date: Wed, 2 Dec 2009 19:15:40 +0300 Subject: Backport of: ------------------------------------------------------------ revno: 2630.4.32 committer: Dmitry Lenev 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. sql/lock.cc: mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible for removal of metadata lock requests from the context. One should explicitly call mdl_remove_all_locks() and mdl_remove_lock() to do this. sql/mdl.cc: Ensured that metadata locking subsystem properly handles out-of-memory conditions. Introduced new MDL_INITIALIZED state for metadata lock request which is used in all cases when lock is not acquired and we have not associated request with object respesenting lock. MDL_PENDING is now only used for requests for exclusive locks which are added to the MDL_LOCK::waiting_exclusive queue. mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible for removal of metadata lock requests from the context. One should explicitly call mdl_remove_all_locks() and newly introduced mdl_remove_lock() to do this. Also renamed mdl_release_all_locks_for_name() to emphasize that it also actually removes lock requests from the context. Finally mdl_try_acquire_exclusive_lock() is now returs information about encountered lock conflict in separate out parameter since its return value is used for distinguishing between error (e.g. due to OOM) and success. sql/mdl.h: Introduced new MDL_INITIALIZED state for metadata lock request which is used in all cases when lock is not acquired and we have not associated request with object respesenting lock. MDL_PENDING is now only used for requests for exclusive locks which are added to the MDL_LOCK::waiting_exclusive queue. mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible for removal of metadata lock requests from the context. One should explicitly call mdl_remove_all_locks() and newly introduced mdl_remove_lock() to do this. Also renamed mdl_release_all_locks_for_name() to emphasize that it also actually removes lock requests from the context. Finally mdl_try_acquire_exclusive_lock() is now returs information about encountered lock conflict in separate out parameter since its return value is used for distinguishing between error (e.g. due to OOM) and success. sql/sql_base.cc: mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible for removal of metadata lock requests from the context. One should explicitly call mdl_remove_all_locks() and mdl_remove_lock() to do this. Also adjusted open_table() to ensure that it releases/removes metadata locks in case of error after adding/acquiring them (unless keeping these lock requests is required for recovering action). sql/sql_delete.cc: mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible for removal of metadata lock requests from the context. One should explicitly call mdl_remove_all_locks() and mdl_remove_lock() to do this. sql/sql_handler.cc: mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible for removal of metadata lock requests from the context. One should explicitly call mdl_remove_all_locks() and mdl_remove_lock() to do this. sql/sql_show.cc: mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible for removal of metadata lock requests from the context. One should explicitly call mdl_remove_all_locks() and mdl_remove_lock() to do this. sql/sql_table.cc: Renamed mdl_release_all_locks_for_name() to emphasize that it also actually removes lock requests from the context. mdl_release_lock(), mdl_acquire_exclusive_locks() and mdl_try_acquire_exclusive_lock() are no longer responsible for removal of metadata lock requests from the context. One should explicitly call mdl_remove_all_locks() and mdl_remove_lock() to do this. Finally mdl_try_acquire_exclusive_lock() is now returs information about encountered lock conflict in separate out parameter since its return value is used for distinguishing between error (e.g. due to OOM) and success. --- sql/sql_delete.cc | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'sql/sql_delete.cc') diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 630cf73076c..4827d48e1c5 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -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_add_lock(&thd->mdl_context, mdl_lock_data); if (mdl_acquire_exclusive_locks(&thd->mdl_context)) + { + mdl_remove_lock(&thd->mdl_context, mdl_lock_data); DBUG_RETURN(TRUE); + } pthread_mutex_lock(&LOCK_open); tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table_list->db, table_list->table_name); @@ -1200,12 +1203,18 @@ end: my_ok(thd); // This should return record count } if (mdl_lock_data) + { mdl_release_lock(&thd->mdl_context, mdl_lock_data); + mdl_remove_lock(&thd->mdl_context, mdl_lock_data); + } } else if (error) { if (mdl_lock_data) + { mdl_release_lock(&thd->mdl_context, mdl_lock_data); + mdl_remove_lock(&thd->mdl_context, mdl_lock_data); + } } DBUG_RETURN(error); -- cgit v1.2.1