Commit 19940fa7 authored by Dmitry Lenev's avatar Dmitry Lenev

Fix for sporadical crashes of lock_multi_bug38499.test

caused by patch which implemented new type-of-operation-aware
metadata locks and added a wait-for graph based deadlock
detector to the MDL subsystem (this patch fixed bug #46272
"MySQL 5.4.4, new MDL: unnecessary deadlock" and bug #37346
"innodb does not detect deadlock between update and alter
table").

Crashes were caused by a race in MDL_context::try_acquire_lock().
This method added MDL_ticket to the list of granted tickets and
released lock protecting list before setting MDL_ticket::m_lock.
Thus some other thread was able to see ticket without properly
set m_lock member for some short period of time. If this thread
called method involving this member during this period crash
happened.

This fix ensures that MDL_ticket::m_lock is set in all cases
when ticket is added to granted/pending lists in MDL_lock.
parent c5b48ab3
......@@ -838,6 +838,12 @@ void MDL_lock::Ticket_list::clear_bit_if_not_in_list(enum_mdl_type type)
void MDL_lock::Ticket_list::add_ticket(MDL_ticket *ticket)
{
/*
Ticket being added to the list must have MDL_ticket::m_lock set,
since for such tickets methods accessing this member might be
called by other threads.
*/
DBUG_ASSERT(ticket->get_lock());
m_list.push_front(ticket);
m_bitmap|= MDL_BIT(ticket->get_type());
}
......@@ -1317,11 +1323,10 @@ MDL_context::try_acquire_lock(MDL_request *mdl_request)
if (lock->can_grant_lock(mdl_request->type, this))
{
ticket->m_lock= lock;
lock->m_granted.add_ticket(ticket);
rw_unlock(&lock->m_rwlock);
ticket->m_lock= lock;
m_tickets.push_front(ticket);
mdl_request->ticket= ticket;
......
......@@ -397,6 +397,7 @@ class MDL_ticket
m_type == MDL_EXCLUSIVE;
}
enum_mdl_type get_type() const { return m_type; }
MDL_lock *get_lock() const { return m_lock; }
void downgrade_exclusive_lock(enum_mdl_type type);
bool has_stronger_or_equal_type(enum_mdl_type type) const;
......@@ -423,7 +424,9 @@ class MDL_ticket
*/
MDL_context *m_ctx;
/** Pointer to the lock object for this lock ticket. Context private. */
/**
Pointer to the lock object for this lock ticket. Externally accessible.
*/
MDL_lock *m_lock;
private:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment