MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MDL_lock Class Reference
Inheritance diagram for MDL_lock:
Collaboration diagram for MDL_lock:

Classes

class  Ticket_list

Public Types

typedef unsigned short bitmap_t
typedef Ticket_list::List::Iterator Ticket_iterator

Public Member Functions

bool is_empty () const
virtual const bitmap_t * incompatible_granted_types_bitmap () const =0
virtual const bitmap_t * incompatible_waiting_types_bitmap () const =0
bool has_pending_conflicting_lock (enum_mdl_type type)
bool can_grant_lock (enum_mdl_type type, MDL_context *requstor_ctx, bool ignore_lock_priority) const
void reschedule_waiters ()
void remove_ticket (Ticket_list MDL_lock::*queue, MDL_ticket *ticket)
bool visit_subgraph (MDL_ticket *waiting_ticket, MDL_wait_for_graph_visitor *gvisitor)
virtual bool needs_notification (const MDL_ticket *ticket) const =0
virtual void notify_conflicting_locks (MDL_context *ctx)=0
virtual bitmap_t hog_lock_types_bitmap () const =0
 MDL_lock (const MDL_key *key_arg, MDL_map_partition *map_part)

Static Public Member Functions

static MDL_lockcreate (const MDL_key *key, MDL_map_partition *map_part)
static void destroy (MDL_lock *lock)

Public Attributes

MDL_key key
mysql_prlock_t m_rwlock
Ticket_list m_granted
Ticket_list m_waiting
ulong m_hog_lock_count
uint m_ref_usage
uint m_ref_release
bool m_is_destroyed
ulonglong m_version
MDL_map_partitionm_map_part

Detailed Description

The lock context. Created internally for an acquired lock. For a given name, there exists only one MDL_lock instance, and it exists only when the lock has been granted. Can be seen as an MDL subsystem's version of TABLE_SHARE.

This is an abstract class which lacks information about compatibility rules for lock types. They should be specified in its descendants.

Definition at line 345 of file mdl.cc.

Member Function Documentation

bool MDL_lock::can_grant_lock ( enum_mdl_type  type_arg,
MDL_context requestor_ctx,
bool  ignore_lock_priority 
) const

Check if request for the metadata lock can be satisfied given its current state.

Parameters
type_argThe requested lock type.
requestor_ctxThe MDL context of the requestor.
ignore_lock_priorityIgnore lock priority.
Return values
TRUELock request can be satisfied
FALSEThere is some conflicting lock.
Note
In cases then current context already has "stronger" type of lock on the object it will be automatically granted thanks to usage of the MDL_context::find_ticket() method.

Definition at line 1709 of file mdl.cc.

Here is the caller graph for this function:

MDL_lock * MDL_lock::create ( const MDL_key mdl_key,
MDL_map_partition map_part 
)
inlinestatic

Auxiliary functions needed for creation/destruction of MDL_lock objects.

Note
Also chooses an MDL_lock descendant appropriate for object namespace.

Definition at line 1148 of file mdl.cc.

Here is the caller graph for this function:

bool MDL_lock::has_pending_conflicting_lock ( enum_mdl_type  type)

Check if we have any pending locks which conflict with existing shared lock.

Precondition
The ticket must match an acquired lock.
Returns
TRUE if there is a conflicting lock request, FALSE otherwise.

Definition at line 1787 of file mdl.cc.

void MDL_lock::remove_ticket ( Ticket_list MDL_lock::*  list,
MDL_ticket ticket 
)

Remove a ticket from waiting or pending queue and wakeup up waiters.

Definition at line 1750 of file mdl.cc.

Here is the call graph for this function:

Here is the caller graph for this function:

void MDL_lock::reschedule_waiters ( )

Determine waiting contexts which requests for the lock can be satisfied, grant lock to them and wake them up.

Note
Together with MDL_lock::add_ticket() this method implements fair scheduling among requests with the same priority. It tries to grant lock from the head of waiters list, while add_ticket() adds new requests to the back of this list.

Definition at line 1413 of file mdl.cc.

Here is the call graph for this function:

Here is the caller graph for this function:

bool MDL_lock::visit_subgraph ( MDL_ticket waiting_ticket,
MDL_wait_for_graph_visitor gvisitor 
)

A fragment of recursive traversal of the wait-for graph in search for deadlocks. Direct the deadlock visitor to all contexts that own the lock the current node in the wait-for graph is waiting for. As long as the initial node is remembered in the visitor, a deadlock is found when the same node is seen twice.

Definition at line 2445 of file mdl.cc.

Here is the call graph for this function:

Here is the caller graph for this function:

Member Data Documentation

MDL_key MDL_lock::key

The key of the object (data) being protected.

Definition at line 380 of file mdl.cc.

Ticket_list MDL_lock::m_granted

List of granted tickets for this lock.

Definition at line 445 of file mdl.cc.

ulong MDL_lock::m_hog_lock_count

Number of times high priority lock requests have been granted while low priority lock requests were waiting.

Definition at line 453 of file mdl.cc.

MDL_map_partition* MDL_lock::m_map_part

Partition of MDL_map where the lock is stored.

Definition at line 518 of file mdl.cc.

uint MDL_lock::m_ref_usage

These three members are used to make it possible to separate the MDL_map_partition::m_mutex mutex and MDL_lock::m_rwlock in MDL_map::find_or_insert() for increased scalability. The 'm_is_destroyed' member is only set by destroyers that have both the MDL_map_partition::m_mutex and MDL_lock::m_rwlock, thus holding any of the mutexes is sufficient to read it. The 'm_ref_usage; is incremented under protection by MDL_map_partition::m_mutex, but when 'm_is_destroyed' is set to TRUE, this member is moved to be protected by the MDL_lock::m_rwlock. This means that the MDL_map::find_or_insert() which only holds the MDL_lock::m_rwlock can compare it to 'm_ref_release' without acquiring MDL_map_partition::m_mutex again and if equal it can also destroy the lock object safely. The 'm_ref_release' is incremented under protection by MDL_lock::m_rwlock. Note since we are only interested in equality of these two counters we don't have to worry about overflows as long as their size is big enough to hold maximum number of concurrent threads on the system.

Definition at line 496 of file mdl.cc.

mysql_prlock_t MDL_lock::m_rwlock

Read-write lock protecting this lock context.

Note
The fact that we use read-write lock prefers readers here is important as deadlock detector won't work correctly otherwise.

For example, imagine that we have following waiters graph:

         ctxA -> obj1 -> ctxB -> obj1 -|
          ^                            |
          |----------------------------|

and both ctxA and ctxB start deadlock detection process:

ctxA read-locks obj1 ctxB read-locks obj2 ctxA goes deeper ctxB goes deeper

Now ctxC comes in who wants to start waiting on obj1, also ctxD comes in who wants to start waiting on obj2.

ctxC tries to write-lock obj1 ctxD tries to write-lock obj2 ctxC is blocked ctxD is blocked

Now ctxA and ctxB resume their search:

ctxA tries to read-lock obj2 ctxB tries to read-lock obj1

If m_rwlock prefers writes (or fair) both ctxA and ctxB would be blocked because of pending write locks from ctxD and ctxC correspondingly. Thus we will get a deadlock in deadlock detector. If m_wrlock prefers readers (actually ignoring pending writers is enough) ctxA and ctxB will continue and no deadlock will occur.

Definition at line 414 of file mdl.cc.

ulonglong MDL_lock::m_version

We use the same idea and an additional version counter to support caching of unused MDL_lock object for further re-use. This counter is incremented while holding both MDL_map_partition::m_mutex and MDL_lock::m_rwlock locks each time when a MDL_lock is moved from the partitioned hash to the paritioned unused objects list (or destroyed). A thread, which has found a MDL_lock object for the key in the hash and then released the MDL_map_partition::m_mutex before acquiring the MDL_lock::m_rwlock, can determine that this object was moved to the unused objects list (or destroyed) while it held no locks by comparing the version value which it read while holding the MDL_map_partition::m_mutex with the value read after acquiring the MDL_lock::m_rwlock. Note that since it takes several years to overflow this counter such theoretically possible overflows should not have any practical effects.

Definition at line 514 of file mdl.cc.

Ticket_list MDL_lock::m_waiting

Tickets for contexts waiting to acquire a lock.

Definition at line 447 of file mdl.cc.


The documentation for this class was generated from the following file: