#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#46272 | Dmitry Lenev | 28 Jan |