List:Commits« Previous MessageNext Message »
From:Dmitry Lenev Date:January 28 2010 1:20pm
Subject:bzr commit into mysql-5.6-next-mr branch (dlenev:3071) Bug#46272
View as plain text  
#At file:///home/dlenev/src/bzr/mysql-next-4284-nl-review/ based on revid:kostja@stripped

 3071 Dmitry Lenev	2010-01-28
      Tentative patch implementing new type-of-operation-aware metadata locks.
      Fixes bug #46272 "MySQL 5.4.4, new MDL: unnecessary deadlock" and bug
      #37346 "innodb does not detect deadlock between update and alter table".
      
      After-review fixes in progress. Do not rely on numeric values of
      enum_mdl_type elements in order to find out which lock type is stronger.

    modified:
      sql/mdl.cc
      sql/mdl.h
=== modified file 'sql/mdl.cc'
--- a/sql/mdl.cc	2010-01-28 12:45:11 +0000
+++ b/sql/mdl.cc	2010-01-28 13:19:52 +0000
@@ -1106,6 +1106,25 @@ bool MDL_lock::has_pending_conflicting_l
 }
 
 
+/**
+  Check if ticket represents metadata lock of "stronger" or equal type
+  than specified one. I.e. if metadata lock represented by ticket won't
+  allow any of locks which are not allowed by specified type of lock.
+
+  @return TRUE  if ticket has stronger or equal type
+          FALSE otherwise.
+*/
+
+bool MDL_ticket::has_stronger_or_equal_type(enum_mdl_type type) const
+{
+  const uchar *granted_incompatible_bitmap=
+                 m_lock->get_incompatible_granted_types_bitmap();
+
+  return ! (granted_incompatible_bitmap[type] &
+            ~(granted_incompatible_bitmap[m_type]));
+}
+
+
 bool MDL_ticket::is_incompatible_when_granted(enum_mdl_type type) const
 {
   return (MDL_BIT(m_type) &
@@ -1187,8 +1206,8 @@ MDL_context::find_ticket(MDL_request *md
     if (ticket == m_trans_sentinel)
       *is_transactional= FALSE;
 
-    if (mdl_request->type <= ticket->m_type &&
-        mdl_request->key.is_equal(&ticket->m_lock->key))
+    if (mdl_request->key.is_equal(&ticket->m_lock->key) &&
+        ticket->has_stronger_or_equal_type(mdl_request->type))
       break;
   }
 
@@ -1335,8 +1354,8 @@ MDL_context::try_acquire_lock(MDL_reques
   bool is_transactional;
 
   DBUG_ASSERT(mdl_request->type < MDL_SHARED_NO_WRITE ||
-              (is_lock_owner(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE)
-               && ! is_lock_owner(MDL_key::GLOBAL, "", "", MDL_SHARED)));
+              (is_lock_owner(MDL_key::GLOBAL, "", "",
+                             MDL_INTENTION_EXCLUSIVE)));
   DBUG_ASSERT(mdl_request->ticket == NULL);
 
   /* Don't take chances in production. */
@@ -1528,8 +1547,7 @@ bool MDL_context::acquire_exclusive_lock
     return FALSE;
   }
 
-  DBUG_ASSERT(is_lock_owner(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE)
-              && ! is_lock_owner(MDL_key::GLOBAL, "", "", MDL_SHARED));
+  DBUG_ASSERT(is_lock_owner(MDL_key::GLOBAL, "", "", MDL_INTENTION_EXCLUSIVE));
 
   /* Early allocation: ticket will be needed in any case. */
   if (!(ticket= MDL_ticket::create(this, mdl_request->type)))

=== modified file 'sql/mdl.h'
--- a/sql/mdl.h	2010-01-28 12:45:11 +0000
+++ b/sql/mdl.h	2010-01-28 13:19:52 +0000
@@ -33,10 +33,6 @@ class Deadlock_detection_context;
 
   @sa Comments for MDL_object_lock::can_grant_lock() and
       MDL_global_lock::can_grant_lock() for details.
-
-  @note Order of types of locks is important as MDL_context::find_ticket()
-        we assume that "stronger" lock types correspond to enum elements
-        with greater numeric values.
 */
 
 enum enum_mdl_type {
@@ -415,6 +411,8 @@ public:
     return m_needs_thr_lock_abort;
   }
 
+  bool has_stronger_or_equal_type(enum_mdl_type type) const;
+
   bool is_incompatible_when_granted(enum_mdl_type type) const;
   bool is_incompatible_when_waiting(enum_mdl_type type) const;
 


Attachment: [text/bzr-bundle] bzr/dlenev@mysql.com-20100128131952-z4v2qnpkilglxzxh.bundle
Thread
bzr commit into mysql-5.6-next-mr branch (dlenev:3071) Bug#46272Dmitry Lenev28 Jan