MySQL 8.3.0
Source Code Documentation
MDL_lock Class Reference

The lock context. More...

Classes

struct  MDL_lock_strategy
 Helper struct which defines how different types of locks are handled for a specific MDL_lock. More...
 
class  Ticket_list
 

Public Types

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

Public Member Functions

const bitmap_tincompatible_granted_types_bitmap () const
 
const bitmap_tincompatible_waiting_types_bitmap () const
 
uint get_incompatible_waiting_types_bitmap_idx () const
 Get index of priority matrice in MDL_lock_strategy::m_waiting_incompatible array which corresponds to current values of the m_piglet_lock_count and m_hog_lock_count counters and the max_write_lock_count threshold. More...
 
bool switch_incompatible_waiting_types_bitmap_if_needed ()
 Switch priority matrice for the MDL_lock object if m_piglet_lock_count or/ and m_hog_lock_count counters have crossed max_write_lock_count threshold. More...
 
bool has_pending_conflicting_lock (enum_mdl_type type)
 Check if we have any pending locks which conflict with existing shared lock. More...
 
bool can_grant_lock (enum_mdl_type type, const MDL_context *requestor_ctx) const
 Check if request for the metadata lock can be satisfied given its current state. More...
 
void reschedule_waiters ()
 Determine waiting contexts which requests for the lock can be satisfied, grant lock to them and wake them up. More...
 
void remove_ticket (MDL_context *ctx, LF_PINS *pins, Ticket_list MDL_lock::*queue, MDL_ticket *ticket)
 Remove a ticket from waiting or pending queue and wakeup up waiters. More...
 
bool 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. More...
 
bool needs_notification (const MDL_ticket *ticket) const
 
void notify_conflicting_locks (MDL_context *ctx)
 
bool needs_connection_check () const
 
bool is_affected_by_max_write_lock_count () const
 
bool count_piglets_and_hogs (enum_mdl_type type)
 If we just have granted a lock of "piglet" or "hog" type and there are pending lower priority locks, increase the appropriate counter. More...
 
fast_path_state_t get_unobtrusive_lock_increment (enum_mdl_type type) const
 
bool is_obtrusive_lock (enum_mdl_type type) const
 Check if type of lock requested is "obtrusive" type of lock. More...
 
bitmap_t fast_path_granted_bitmap () const
 Return set of types of lock requests which were granted using "fast path" algorithm in the bitmap_t form. More...
 
 MDL_lock ()
 Do "expensive" part of MDL_lock object initialization, Called by LF_ALLOCATOR for each newly malloc()'ed MDL_lock object, is not called in cases when LF_ALLOCATOR decides to reuse object which was returned to it earlier. More...
 
void reinit (const MDL_key *mdl_key)
 Finalize initialization or re-initialize MDL_lock returned from LF_ALLOCATOR's cache to represent object identified by provided key. More...
 
 ~MDL_lock ()
 
MDL_contextget_lock_owner () const
 Return the first MDL_context which owns the lock. More...
 
bool fast_path_state_cas (fast_path_state_t *old_state, fast_path_state_t new_state)
 Wrapper for atomic compare-and-swap operation on m_fast_path_state member which enforces locking and other invariants. More...
 
fast_path_state_t fast_path_state_add (fast_path_state_t value)
 Wrapper for atomic add operation on m_fast_path_state member which enforces locking and other invariants. More...
 
void fast_path_state_reset ()
 Wrapper for resetting m_fast_path_state enforcing locking invariants. More...
 

Static Public Member Functions

static bool needs_hton_notification (MDL_key::enum_mdl_namespace mdl_namespace)
 Indicates whether object belongs to namespace which requires storage engine to be notified before acquiring and after releasing exclusive lock. More...
 
static fast_path_state_t get_unobtrusive_lock_increment (const MDL_request *request)
 
static MDL_lockcreate (const MDL_key *key)
 Auxiliary functions needed for creation/destruction of MDL_lock objects. More...
 
static void destroy (MDL_lock *lock)
 
static const MDL_lock_strategyget_strategy (const MDL_key &key)
 Get MDL lock strategy corresponding to MDL key. More...
 
static bitmap_t scoped_lock_fast_path_granted_bitmap (const MDL_lock &lock)
 Get bitmap of "unobtrusive" locks granted using "fast path" algorithm for scoped locks. More...
 
static bool object_lock_needs_notification (const MDL_ticket *ticket)
 Check if we are requesting X lock on the object, so threads holding conflicting S/SH metadata locks on it need to be notified. More...
 
static void object_lock_notify_conflicting_locks (MDL_context *ctx, MDL_lock *lock)
 Notify threads holding S/SH metadata locks on an object, which conflict with a pending X lock. More...
 
static bitmap_t object_lock_fast_path_granted_bitmap (const MDL_lock &lock)
 Get bitmap of "unobtrusive" locks granted using "fast path" algorithm for per-object locks. More...
 
static bool object_lock_needs_connection_check (const MDL_lock *lock)
 Check if MDL_lock object represents user-level lock,locking service lock or acl cache lock, so threads waiting for it need to check if connection is lost and abort waiting when it is. More...
 

Public Attributes

MDL_key key
 The key of the object (data) being protected. More...
 
mysql_prlock_t m_rwlock
 Read-write lock protecting this lock context. More...
 
Ticket_list m_granted
 List of granted tickets for this lock. More...
 
Ticket_list m_waiting
 Tickets for contexts waiting to acquire a lock. More...
 
uint m_obtrusive_locks_granted_waiting_count
 Number of granted or waiting lock requests of "obtrusive" type. More...
 
std::atomic< fast_path_state_tm_fast_path_state
 Combination of IS_DESTROYED/HAS_OBTRUSIVE/HAS_SLOW_PATH flags and packed counters of specific types of "unobtrusive" locks which were granted using "fast path". More...
 
const MDL_lock_strategym_strategy
 Pointer to strategy object which defines how different types of lock requests should be handled for the namespace to which this lock belongs. More...
 

Static Public Attributes

static const fast_path_state_t IS_DESTROYED = 1ULL << 62
 Flag in MDL_lock::m_fast_path_state that indicates that the MDL_lock object was marked for destruction and will be destroyed once all threads referencing to it through hazard pointers have unpinned it. More...
 
static const fast_path_state_t HAS_OBTRUSIVE = 1ULL << 61
 Flag in MDL_lock::m_fast_path_state that indicates that there are "obtrusive" locks which are granted, waiting or for which we are about to check if they can be granted. More...
 
static const fast_path_state_t HAS_SLOW_PATH = 1ULL << 60
 Flag in MDL_lock::m_fast_path_state that indicates that there are "slow" path locks which are granted, waiting or for which we are about to check if they can be granted. More...
 
static const bitmap_t MDL_OBJECT_HOG_LOCK_TYPES
 Bitmap with "hog" lock types for object locks. More...
 
static const MDL_lock_strategy m_scoped_lock_strategy
 Strategy instances to be used with scoped metadata locks (i.e. More...
 
static const MDL_lock_strategy m_object_lock_strategy
 Strategy instance for per-object locks. More...
 

Private Attributes

ulong m_hog_lock_count
 Number of times high priority, "hog" lock requests (X, SNRW, SNW) have been granted while lower priority lock requests (all other types) were waiting. More...
 
ulong m_piglet_lock_count
 Number of times high priority, "piglet" lock requests (SW) have been granted while locks requests with lower priority (SRO) were waiting. More...
 
uint m_current_waiting_incompatible_idx
 Index of one of the MDL_lock_strategy::m_waiting_incompatible arrays which represents the current priority matrice. More...
 

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.

Member Typedef Documentation

◆ bitmap_t

typedef unsigned short MDL_lock::bitmap_t

◆ fast_path_state_t

◆ Ticket_iterator

Constructor & Destructor Documentation

◆ MDL_lock()

MDL_lock::MDL_lock ( )
inline

Do "expensive" part of MDL_lock object initialization, Called by LF_ALLOCATOR for each newly malloc()'ed MDL_lock object, is not called in cases when LF_ALLOCATOR decides to reuse object which was returned to it earlier.

"Full" initialization happens later by calling MDL_lock::reinit(). So

See also
MDL_lock::reiniti()

◆ ~MDL_lock()

MDL_lock::~MDL_lock ( )
inline

Member Function Documentation

◆ can_grant_lock()

bool MDL_lock::can_grant_lock ( enum_mdl_type  type_arg,
const MDL_context requestor_ctx 
) 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.
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.

◆ count_piglets_and_hogs()

bool MDL_lock::count_piglets_and_hogs ( enum_mdl_type  type)
inline

If we just have granted a lock of "piglet" or "hog" type and there are pending lower priority locks, increase the appropriate counter.

If this counter now exceeds the max_write_lock_count threshold, switch priority matrice for the MDL_lock object.

Returns
true - if priority matrice has been changed, false - otherwise.

◆ create()

MDL_lock * MDL_lock::create ( const MDL_key key)
inlinestatic

Auxiliary functions needed for creation/destruction of MDL_lock objects.

◆ destroy()

void MDL_lock::destroy ( MDL_lock lock)
inlinestatic

◆ fast_path_granted_bitmap()

bitmap_t MDL_lock::fast_path_granted_bitmap ( ) const
inline

Return set of types of lock requests which were granted using "fast path" algorithm in the bitmap_t form.

This method is only called from MDL_lock::can_grant_lock() and its return value is only important when we are trying to figure out if we can grant an obtrusive lock. But this means that the HAS_OBTRUSIVE flag is set so all changes to m_fast_path_state happen under protection of MDL_lock::m_rwlock (see invariant [INV1]). Since can_grant_lock() is called only when MDL_lock::m_rwlock is held, it is safe to do an ordinary read of m_fast_path_state here.

◆ fast_path_state_add()

fast_path_state_t MDL_lock::fast_path_state_add ( fast_path_state_t  value)
inline

Wrapper for atomic add operation on m_fast_path_state member which enforces locking and other invariants.

◆ fast_path_state_cas()

bool MDL_lock::fast_path_state_cas ( fast_path_state_t old_state,
fast_path_state_t  new_state 
)
inline

Wrapper for atomic compare-and-swap operation on m_fast_path_state member which enforces locking and other invariants.

◆ fast_path_state_reset()

void MDL_lock::fast_path_state_reset ( )
inline

Wrapper for resetting m_fast_path_state enforcing locking invariants.

◆ get_incompatible_waiting_types_bitmap_idx()

uint MDL_lock::get_incompatible_waiting_types_bitmap_idx ( ) const
inline

Get index of priority matrice in MDL_lock_strategy::m_waiting_incompatible array which corresponds to current values of the m_piglet_lock_count and m_hog_lock_count counters and the max_write_lock_count threshold.

◆ get_lock_owner()

MDL_context * MDL_lock::get_lock_owner ( ) const
inline

Return the first MDL_context which owns the lock.

Returns
Pointer to the first MDL_context which has acquired the lock NULL if there are no such contexts.
Note
This method works properly only for locks acquired using "slow" path. It won't return context if it has used "fast" path to acquire the lock.

◆ get_strategy()

static const MDL_lock_strategy * MDL_lock::get_strategy ( const MDL_key key)
inlinestatic

Get MDL lock strategy corresponding to MDL key.

Parameters
keyReference to MDL_key object
Returns
the type of strategy scoped or object corresponding to MDL key.

◆ get_unobtrusive_lock_increment() [1/2]

MDL_lock::fast_path_state_t MDL_lock::get_unobtrusive_lock_increment ( const MDL_request request)
inlinestatic
Returns
"Fast path" increment for request for "unobtrusive" type of lock, 0 - if it is request for "obtrusive" type of lock.
Note
We split all lock types for each of MDL namespaces in two sets:

A) "unobtrusive" lock types 1) Each type from this set should be compatible with all other types from the set (including itself). 2) These types should be common for DML operations

Our goal is to optimize acquisition and release of locks of this type by avoiding complex checks and manipulations on m_waiting/ m_granted bitmaps/lists. We replace them with a check of and increment/decrement of integer counters. We call the latter type of acquisition/release "fast path". Use of "fast path" reduces the size of critical section associated with MDL_lock::m_rwlock lock in the common case and thus increases scalability.

The amount by which acquisition/release of specific type "unobtrusive" lock increases/decreases packed counter in MDL_lock::m_fast_path_state is returned by this function.

B) "obtrusive" lock types 1) Granted or pending lock of those type is incompatible with some other types of locks or with itself. 2) Not common for DML operations

These locks have to be always acquired involving manipulations on m_waiting/m_granted bitmaps/lists, i.e. we have to use "slow path" for them. Moreover in the presence of active/pending locks from "obtrusive" set we have to acquire using "slow path" even locks of "unobtrusive" type.

See also
MDL_scoped_lock::m_unobtrusive_lock_increment and
MDL_object_lock::m_unobtrusive_lock_increment for definitions of these sets for scoped and per-object locks.
Returns
"Fast path" increment for request for "unobtrusive" type of lock, 0 - if it is request for "obtrusive" type of lock.
See also
Description at method declaration for more details.

◆ get_unobtrusive_lock_increment() [2/2]

fast_path_state_t MDL_lock::get_unobtrusive_lock_increment ( enum_mdl_type  type) const
inline
Returns
"Fast path" increment if type of lock is "unobtrusive" type, 0 - if it is "obtrusive" type of lock.

◆ has_pending_conflicting_lock()

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.

◆ incompatible_granted_types_bitmap()

const bitmap_t * MDL_lock::incompatible_granted_types_bitmap ( ) const
inline

◆ incompatible_waiting_types_bitmap()

const bitmap_t * MDL_lock::incompatible_waiting_types_bitmap ( ) const
inline

◆ is_affected_by_max_write_lock_count()

bool MDL_lock::is_affected_by_max_write_lock_count ( ) const
inline

◆ is_obtrusive_lock()

bool MDL_lock::is_obtrusive_lock ( enum_mdl_type  type) const
inline

Check if type of lock requested is "obtrusive" type of lock.

See also
MDL_lock::get_unobtrusive_lock_increment() description.

◆ needs_connection_check()

bool MDL_lock::needs_connection_check ( ) const
inline

◆ needs_hton_notification()

bool MDL_lock::needs_hton_notification ( MDL_key::enum_mdl_namespace  mdl_namespace)
inlinestatic

Indicates whether object belongs to namespace which requires storage engine to be notified before acquiring and after releasing exclusive lock.

◆ needs_notification()

bool MDL_lock::needs_notification ( const MDL_ticket ticket) const
inline

◆ notify_conflicting_locks()

void MDL_lock::notify_conflicting_locks ( MDL_context ctx)
inline

◆ object_lock_fast_path_granted_bitmap()

static bitmap_t MDL_lock::object_lock_fast_path_granted_bitmap ( const MDL_lock lock)
inlinestatic

Get bitmap of "unobtrusive" locks granted using "fast path" algorithm for per-object locks.

See also
MDL_lock::fast_path_granted_bitmap() for explanation about why it is safe to use non-atomic read of MDL_lock::m_fast_path_state here.

◆ object_lock_needs_connection_check()

static bool MDL_lock::object_lock_needs_connection_check ( const MDL_lock lock)
inlinestatic

Check if MDL_lock object represents user-level lock,locking service lock or acl cache lock, so threads waiting for it need to check if connection is lost and abort waiting when it is.

◆ object_lock_needs_notification()

static bool MDL_lock::object_lock_needs_notification ( const MDL_ticket ticket)
inlinestatic

Check if we are requesting X lock on the object, so threads holding conflicting S/SH metadata locks on it need to be notified.

See also
MDL_lock::object_lock_notify_conflicting_locks.

◆ object_lock_notify_conflicting_locks()

void MDL_lock::object_lock_notify_conflicting_locks ( MDL_context ctx,
MDL_lock lock 
)
static

Notify threads holding S/SH metadata locks on an object, which conflict with a pending X lock.

Note
Currently this method is guaranteed to notify shared lock owners which have MDL_context::m_needs_thr_lock_abort flag set (as for others conficting locks might have been acquired on "fast path" and thus might be absent from list of granted locks). This is OK as notification for other contexts is anyway no-op now.
We don't notify threads holding other than S/SH types of conflicting locks on the object since notification should not be needed and anyway will be no-op for them (unless they also hold S/SH locks on the object).
Parameters
ctxMDL_context for current thread.
lockMDL_lock object representing lock which is to be acquired.

◆ reinit()

void MDL_lock::reinit ( const MDL_key mdl_key)
inline

Finalize initialization or re-initialize MDL_lock returned from LF_ALLOCATOR's cache to represent object identified by provided key.

Note
All non-static MDL_lock members: 1) either have to be reinitialized here (like IS_DESTROYED flag in MDL_lock::m_fast_path_state). 2) or need to be initialized in constructor AND returned to their pristine state once they are removed from MDL_map container (like MDL_lock::m_granted or MDL_lock::m_rwlock). Otherwise it is possible that we will end up in situation when "new" (actually reused) MDL_lock object inserted in LF_HASH will inherit some values from old object.

◆ remove_ticket()

void MDL_lock::remove_ticket ( MDL_context ctx,
LF_PINS pins,
Ticket_list MDL_lock::*  queue,
MDL_ticket ticket 
)

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

◆ reschedule_waiters()

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.

◆ scoped_lock_fast_path_granted_bitmap()

static bitmap_t MDL_lock::scoped_lock_fast_path_granted_bitmap ( const MDL_lock lock)
inlinestatic

Get bitmap of "unobtrusive" locks granted using "fast path" algorithm for scoped locks.

See also
MDL_lock::fast_path_granted_bitmap() for explanation about why it is safe to use non-atomic read of MDL_lock::m_fast_path_state here.

◆ switch_incompatible_waiting_types_bitmap_if_needed()

bool MDL_lock::switch_incompatible_waiting_types_bitmap_if_needed ( )
inline

Switch priority matrice for the MDL_lock object if m_piglet_lock_count or/ and m_hog_lock_count counters have crossed max_write_lock_count threshold.

Returns
true - if priority matrice has been changed, false - otherwise.

◆ visit_subgraph()

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.

Member Data Documentation

◆ HAS_OBTRUSIVE

const fast_path_state_t MDL_lock::HAS_OBTRUSIVE = 1ULL << 61
static

Flag in MDL_lock::m_fast_path_state that indicates that there are "obtrusive" locks which are granted, waiting or for which we are about to check if they can be granted.

Corresponds to "MDL_lock::m_obtrusive_locks_granted_waiting_count == 0" predicate. Set using atomic compare-and-swap AND under protection of MDL_lock::m_rwlock lock. Thanks to this can be read either by using atomic compare-and-swap OR using ordinary read under protection of MDL_lock::m_rwlock lock.

Invariant [INV1]: When this flag is set all changes to m_fast_path_state member has to be done under protection of m_rwlock lock.

◆ HAS_SLOW_PATH

const fast_path_state_t MDL_lock::HAS_SLOW_PATH = 1ULL << 60
static

Flag in MDL_lock::m_fast_path_state that indicates that there are "slow" path locks which are granted, waiting or for which we are about to check if they can be granted.

Corresponds to MDL_lock::m_granted/m_waiting lists being non-empty (except special case in MDL_context::try_acquire_lock()). Set using atomic compare-and-swap AND under protection of m_rwlock lock. The latter is necessary because value of this flag needs to be synchronized with contents of MDL_lock::m_granted/m_waiting lists.

◆ IS_DESTROYED

const fast_path_state_t MDL_lock::IS_DESTROYED = 1ULL << 62
static

Flag in MDL_lock::m_fast_path_state that indicates that the MDL_lock object was marked for destruction and will be destroyed once all threads referencing to it through hazard pointers have unpinned it.

Set using atomic compare-and-swap AND under protection of MDL_lock::m_rwlock lock. Thanks to this can be read either by using atomic compare-and-swap OR using ordinary read under protection of MDL_lock::m_rwlock lock.

◆ key

MDL_key MDL_lock::key

The key of the object (data) being protected.

◆ m_current_waiting_incompatible_idx

uint MDL_lock::m_current_waiting_incompatible_idx
private

Index of one of the MDL_lock_strategy::m_waiting_incompatible arrays which represents the current priority matrice.

◆ m_fast_path_state

std::atomic<fast_path_state_t> MDL_lock::m_fast_path_state

Combination of IS_DESTROYED/HAS_OBTRUSIVE/HAS_SLOW_PATH flags and packed counters of specific types of "unobtrusive" locks which were granted using "fast path".

See also
MDL_scoped_lock::m_unobtrusive_lock_increment and
MDL_object_lock::m_unobtrusive_lock_increment for details about how counts of different types of locks are packed into this field.
Note
Doesn't include "unobtrusive" locks granted using "slow path".
We use combination of atomic operations and protection by MDL_lock::m_rwlock lock to work with this member:

Write and Read-Modify-Write operations are always carried out atomically. This is necessary to avoid lost updates on 32-bit platforms among other things. In some cases Reads can be done non-atomically because we don't really care about value which they will return (for example, if further down the line there will be an atomic compare-and-swap operation, which will validate this value and provide the correct value if the validation will fail). In other cases Reads can be done non-atomically since they happen under protection of MDL_lock::m_rwlock and there is some invariant which ensures that concurrent updates of the m_fast_path_state member can't happen while MDL_lock::m_rwlock is held (

See also
IS_DESTROYED, HAS_OBTRUSIVE, HAS_SLOW_PATH).
Note
IMPORTANT!!! In order to enforce the above rules and other invariants, MDL_lock::m_fast_path_state should not be updated directly. Use fast_path_state_cas()/add()/reset() wrapper methods instead.

◆ m_granted

Ticket_list MDL_lock::m_granted

List of granted tickets for this lock.

◆ m_hog_lock_count

ulong MDL_lock::m_hog_lock_count
private

Number of times high priority, "hog" lock requests (X, SNRW, SNW) have been granted while lower priority lock requests (all other types) were waiting.

Currently used only for object locks. Protected by m_rwlock lock.

◆ m_object_lock_strategy

const MDL_lock::MDL_lock_strategy MDL_lock::m_object_lock_strategy
static

Strategy instance for per-object locks.

Supports all locked modes except INTENTION EXCLUSIVE locks.

◆ m_obtrusive_locks_granted_waiting_count

uint MDL_lock::m_obtrusive_locks_granted_waiting_count

Number of granted or waiting lock requests of "obtrusive" type.

Also includes "obtrusive" lock requests for which we about to check if they can be granted.

See also
MDL_lock::get_unobtrusive_lock_increment() description.
Note
This number doesn't include "unobtrusive" locks which were acquired using "slow path".

◆ m_piglet_lock_count

ulong MDL_lock::m_piglet_lock_count
private

Number of times high priority, "piglet" lock requests (SW) have been granted while locks requests with lower priority (SRO) were waiting.

Currently used only for object locks. Protected by m_rwlock lock.

◆ m_rwlock

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.

◆ m_scoped_lock_strategy

const MDL_lock::MDL_lock_strategy MDL_lock::m_scoped_lock_strategy
static
Initial value:
= {
0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}},
{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
false,
{true, true, false, false, false, false, false, false, false, false, true},
nullptr,
nullptr,
nullptr}
static bitmap_t scoped_lock_fast_path_granted_bitmap(const MDL_lock &lock)
Get bitmap of "unobtrusive" locks granted using "fast path" algorithm for scoped locks.
Definition: mdl.cc:993
#define MDL_BIT(A)
Get a bit corresponding to enum_mdl_type value in a granted/waiting bitmaps and compatibility matrice...
Definition: mdl.cc:413
@ MDL_SHARED
Definition: sql_lexer_yacc_state.h:140
@ MDL_EXCLUSIVE
Definition: sql_lexer_yacc_state.h:235
@ MDL_INTENTION_EXCLUSIVE
Definition: sql_lexer_yacc_state.h:117

Strategy instances to be used with scoped metadata locks (i.e.

locks from GLOBAL, COMMIT, TABLESPACE, BACKUP_LOCK and SCHEMA namespaces). The only locking modes which are supported at the moment are SHARED and INTENTION EXCLUSIVE and EXCLUSIVE.

◆ m_strategy

const MDL_lock_strategy* MDL_lock::m_strategy

Pointer to strategy object which defines how different types of lock requests should be handled for the namespace to which this lock belongs.

See also
MDL_lock::m_scoped_lock_strategy and MDL_lock:m_object_lock_strategy.

◆ m_waiting

Ticket_list MDL_lock::m_waiting

Tickets for contexts waiting to acquire a lock.

◆ MDL_OBJECT_HOG_LOCK_TYPES

const bitmap_t MDL_lock::MDL_OBJECT_HOG_LOCK_TYPES
static
Initial value:
=
@ MDL_SHARED_NO_WRITE
Definition: sql_lexer_yacc_state.h:215
@ MDL_SHARED_NO_READ_WRITE
Definition: sql_lexer_yacc_state.h:227

Bitmap with "hog" lock types for object locks.

Locks of these types can easily starve out lower priority locks. To prevent this we only grant them max_write_lock_count times in a row while other lock types are waiting.


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