MySQL 9.0.0
Source Code Documentation
lock0priv.h File Reference

Lock module internal structures and methods. More...

#include "dict0types.h"
#include "hash0hash.h"
#include "trx0types.h"
#include "univ.i"
#include <scope_guard.h>
#include <utility>
#include "lock0priv.ic"

Go to the source code of this file.

Classes

struct  lock_table_t
 A table lock. More...
 
struct  lock_rec_t
 Record lock for a page. More...
 
struct  lock_t
 Lock struct; protected by lock_sys latches. More...
 
struct  RecID
 Record lock ID. More...
 
class  RecLock
 Create record locks. More...
 
struct  Lock_iter
 Iterate over record locks matching <space, page_no, heap_no> More...
 
class  locksys::Unsafe_global_latch_manipulator
 

Namespaces

namespace  locksys
 

Enumerations

enum  lock_rec_req_status { LOCK_REC_FAIL , LOCK_REC_SUCCESS , LOCK_REC_SUCCESS_CREATED }
 Record locking request status. More...
 

Functions

std::ostream & operator<< (std::ostream &out, const lock_table_t &lock)
 The global output operator is overloaded to conveniently print the lock_table_t object into the given output stream. More...
 
std::ostream & operator<< (std::ostream &out, const lock_rec_t &lock)
 
static bool lock_mode_is_next_key_lock (ulint mode)
 Checks if the mode is LOCK_S or LOCK_X (possibly ORed with LOCK_WAIT or LOCK_REC) which means the lock is a Next Key Lock, a.k.a. More...
 
static bool lock_rec_get_nth_bit (const lock_t *lock, ulint i)
 Gets the nth bit of a record lock. More...
 
std::ostream & operator<< (std::ostream &out, const lock_t &lock)
 
static uint32_t lock_get_type_low (const lock_t *lock)
 Gets the type of a lock. More...
 
const lock_tlock_rec_get_prev (const lock_t *in_lock, ulint heap_no)
 Gets the previous record lock set on a record. More...
 
void lock_cancel_waiting_and_release (trx_t *trx)
 Cancels a waiting lock request and releases possible other transactions waiting behind it. More...
 
void lock_reset_wait_and_release_thread_if_suspended (lock_t *lock)
 This function is a wrapper around several functions which need to be called in particular order to wake up a transaction waiting for a lock. More...
 
static trx_id_t lock_clust_rec_some_has_impl (const rec_t *rec, const dict_index_t *index, const ulint *offsets)
 Checks if some transaction has an implicit x-lock on a record in a clustered index. More...
 
static const lock_tlock_rec_get_next_on_page_const (const lock_t *lock)
 Gets the first or next record lock on a page. More...
 
static uint32_t lock_rec_get_n_bits (const lock_t *lock)
 Gets the number of bits in a record lock bitmap. More...
 
static void lock_rec_set_nth_bit (lock_t *lock, ulint i)
 Sets the nth bit of a record lock to true. More...
 
static lock_tlock_rec_get_next_on_page (lock_t *lock)
 Gets the first or next record lock on a page. More...
 
static lock_tlock_rec_get_first_on_page_addr (hash_table_t *lock_hash, const page_id_t &page_id)
 Gets the first record lock on a page, where the page is identified by its file address. More...
 
static lock_tlock_rec_get_first_on_page (hash_table_t *lock_hash, const buf_block_t *block)
 Gets the first record lock on a page, where the page is identified by a pointer to it. More...
 
static lock_tlock_rec_get_next (ulint heap_no, lock_t *lock)
 Gets the next explicit lock request on a record. More...
 
static const lock_tlock_rec_get_next_const (ulint heap_no, const lock_t *lock)
 Gets the next explicit lock request on a record. More...
 
static lock_tlock_rec_get_first (hash_table_t *hash, const buf_block_t *block, ulint heap_no)
 Gets the first explicit lock request on a record. More...
 
static enum lock_mode lock_get_mode (const lock_t *lock)
 Gets the mode of a lock. More...
 
static ulint lock_mode_compatible (enum lock_mode mode1, enum lock_mode mode2)
 Calculates if lock mode 1 is compatible with lock mode 2. More...
 
static bool lock_mode_stronger_or_eq (enum lock_mode mode1, enum lock_mode mode2)
 Calculates if lock mode 1 is stronger or equal to lock mode 2. More...
 
static ulint lock_get_wait (const lock_t *lock)
 Gets the wait flag of a lock. More...
 
static bool lock_table_has (const trx_t *trx, const dict_table_t *table, enum lock_mode mode)
 Checks if a transaction has the specified table lock, or stronger. More...
 
void lock_notify_about_deadlock (const ut::vector< const trx_t * > &trxs_on_cycle, const trx_t *victim_trx)
 Handles writing the information about found deadlock to the log files and caches it for future lock_latest_err_file() calls (for example used by SHOW ENGINE INNODB STATUS) More...
 
template<typename F >
auto locksys::latch_peeked_shard_and_do (const lock_t *peeked_lock, F &&f)
 Temporarily releases trx->mutex, latches the lock-sys shard containing peeked_lock and latches trx->mutex again and calls f under protection of both latches. More...
 
template<typename F >
void locksys::run_if_waiting (const TrxVersion trx_version, F &&f)
 Given a pointer to trx (which the caller guarantees will not be freed) and the expected value of trx->version, will call the provided function f, only if the trx is still in expected version and waiting for a lock, within a critical section which holds latches on the trx, and the shard containing the waiting lock. More...
 

Variables

bool lock_print_waits
 
static const ulint LOCK_PAGE_BITMAP_MARGIN = 64
 
static const byte lock_compatibility_matrix [5][5]
 
static const byte lock_strength_matrix [5][5]
 
constexpr uint32_t MAX_STACK_SIZE = 4096
 Maximum depth of the DFS stack. More...
 
constexpr uint32_t PRDT_HEAPNO = PAGE_HEAP_NO_INFIMUM
 
static const ulint lock_types = UT_ARR_SIZE(lock_compatibility_matrix)
 The count of the types of locks. More...
 

Detailed Description

Lock module internal structures and methods.

Created July 12, 2007 Vasil Dimov

Enumeration Type Documentation

◆ lock_rec_req_status

Record locking request status.

Enumerator
LOCK_REC_FAIL 

Failed to acquire a lock.

LOCK_REC_SUCCESS 

Succeeded in acquiring a lock (implicit or already acquired)

LOCK_REC_SUCCESS_CREATED 

Explicitly created a new lock.

Function Documentation

◆ lock_cancel_waiting_and_release()

void lock_cancel_waiting_and_release ( trx_t trx)

Cancels a waiting lock request and releases possible other transactions waiting behind it.

Parameters
[in,out]trxThe transaction waiting for a lock

◆ lock_clust_rec_some_has_impl()

static trx_id_t lock_clust_rec_some_has_impl ( const rec_t rec,
const dict_index_t index,
const ulint offsets 
)
inlinestatic

Checks if some transaction has an implicit x-lock on a record in a clustered index.

Parameters
[in]recUser record.
[in]indexClustered index.
[in]offsetsrec_get_offsets(rec, index)
Returns
transaction id of the transaction which has the x-lock, or 0

◆ lock_get_mode()

static enum lock_mode lock_get_mode ( const lock_t lock)
inlinestatic

Gets the mode of a lock.

Returns
mode in: lock

◆ lock_get_type_low()

static uint32_t lock_get_type_low ( const lock_t lock)
inlinestatic

Gets the type of a lock.

Returns
LOCK_TABLE or LOCK_REC in: lock

◆ lock_get_wait()

static ulint lock_get_wait ( const lock_t lock)
inlinestatic

Gets the wait flag of a lock.

Returns
LOCK_WAIT if waiting, 0 if not in: lock

◆ lock_mode_compatible()

static ulint lock_mode_compatible ( enum lock_mode  mode1,
enum lock_mode  mode2 
)
inlinestatic

Calculates if lock mode 1 is compatible with lock mode 2.

Parameters
[in]mode1lock mode
[in]mode2lock mode
Returns
nonzero if mode1 compatible with mode2

◆ lock_mode_is_next_key_lock()

static bool lock_mode_is_next_key_lock ( ulint  mode)
inlinestatic

Checks if the mode is LOCK_S or LOCK_X (possibly ORed with LOCK_WAIT or LOCK_REC) which means the lock is a Next Key Lock, a.k.a.

LOCK_ORDINARY, as opposed to Predicate Lock, GAP lock, Insert Intention or Record Lock.

Parameters
modeA mode and flags, of a lock.
Returns
true iff the only bits set in mode are LOCK_S or LOCK_X and optionally LOCK_WAIT or LOCK_REC

◆ lock_mode_stronger_or_eq()

static bool lock_mode_stronger_or_eq ( enum lock_mode  mode1,
enum lock_mode  mode2 
)
inlinestatic

Calculates if lock mode 1 is stronger or equal to lock mode 2.

Parameters
[in]mode1lock mode 1
[in]mode2lock mode 2
Returns
true iff mode1 stronger or equal to mode2

◆ lock_notify_about_deadlock()

void lock_notify_about_deadlock ( const ut::vector< const trx_t * > &  trxs_on_cycle,
const trx_t victim_trx 
)

Handles writing the information about found deadlock to the log files and caches it for future lock_latest_err_file() calls (for example used by SHOW ENGINE INNODB STATUS)

Parameters
[in]trxs_on_cycletrxs causing deadlock, i-th waits for i+1-th
[in]victim_trxthe trx from trx_on_cycle which will be rolled back

◆ lock_rec_get_first()

static lock_t * lock_rec_get_first ( hash_table_t hash,
const buf_block_t block,
ulint  heap_no 
)
inlinestatic

Gets the first explicit lock request on a record.

Parameters
[in]hashhash chain the lock on
[in]blockblock containing the record
[in]heap_noheap number of the record
Returns
first lock, NULL if none exists

◆ lock_rec_get_first_on_page()

static lock_t * lock_rec_get_first_on_page ( hash_table_t lock_hash,
const buf_block_t block 
)
inlinestatic

Gets the first record lock on a page, where the page is identified by a pointer to it.

Parameters
[in]lock_hashlock hash table
[in]blockbuffer block
Returns
first lock, NULL if none exists

◆ lock_rec_get_first_on_page_addr()

static lock_t * lock_rec_get_first_on_page_addr ( hash_table_t lock_hash,
const page_id_t page_id 
)
inlinestatic

Gets the first record lock on a page, where the page is identified by its file address.

Parameters
[in]lock_hashlock hash table
[in]page_idspecifies space id and page number of the page
Returns
first lock, NULL if none exists

◆ lock_rec_get_n_bits()

static uint32_t lock_rec_get_n_bits ( const lock_t lock)
inlinestatic

Gets the number of bits in a record lock bitmap.

Parameters
[in]lockThe record lock
Returns
number of bits

◆ lock_rec_get_next()

static lock_t * lock_rec_get_next ( ulint  heap_no,
lock_t lock 
)
inlinestatic

Gets the next explicit lock request on a record.

Parameters
[in]heap_noheap number of the record
[in]locklock
Returns
next lock, NULL if none exists or if heap_no == ULINT_UNDEFINED

◆ lock_rec_get_next_const()

static const lock_t * lock_rec_get_next_const ( ulint  heap_no,
const lock_t lock 
)
inlinestatic

Gets the next explicit lock request on a record.

Parameters
[in]heap_noheap number of the record
[in]locklock
Returns
next lock, NULL if none exists or if heap_no == ULINT_UNDEFINED

◆ lock_rec_get_next_on_page()

static lock_t * lock_rec_get_next_on_page ( lock_t lock)
inlinestatic

Gets the first or next record lock on a page.

Returns
next lock, NULL if none exists in: a record lock

◆ lock_rec_get_next_on_page_const()

static const lock_t * lock_rec_get_next_on_page_const ( const lock_t lock)
inlinestatic

Gets the first or next record lock on a page.

Returns
next lock, NULL if none exists in: a record lock

◆ lock_rec_get_nth_bit()

static bool lock_rec_get_nth_bit ( const lock_t lock,
ulint  i 
)
inlinestatic

Gets the nth bit of a record lock.

Parameters
[in]lockrecord lock
[in]iindex of the bit
Returns
true if bit set also if i == ULINT_UNDEFINED return false

◆ lock_rec_get_prev()

const lock_t * lock_rec_get_prev ( const lock_t in_lock,
ulint  heap_no 
)

Gets the previous record lock set on a record.

Returns
previous lock on the same record, NULL if none exists in: heap number of the record
previous lock on the same record, NULL if none exists
Parameters
in_lockin: record lock
heap_noin: heap number of the record

◆ lock_rec_set_nth_bit()

static void lock_rec_set_nth_bit ( lock_t lock,
ulint  i 
)
inlinestatic

Sets the nth bit of a record lock to true.

Parameters
[in]lockrecord lock
[in]iindex of the bit

◆ lock_reset_wait_and_release_thread_if_suspended()

void lock_reset_wait_and_release_thread_if_suspended ( lock_t lock)

This function is a wrapper around several functions which need to be called in particular order to wake up a transaction waiting for a lock.

You should not call lock_wait_release_thread_if_suspended(thr) directly, but rather use this wrapper, as this makes it much easier to reason about all possible states in which lock, trx, and thr can be. It makes sure that trx is woken up exactly once, and only if it already went to sleep.

Parameters
[in,out]lockThe lock for which lock->trx is waiting

◆ lock_table_has()

static bool lock_table_has ( const trx_t trx,
const dict_table_t table,
enum lock_mode  mode 
)
inlinestatic

Checks if a transaction has the specified table lock, or stronger.

This function should only be called by the thread that owns the transaction. This function acquires trx->mutex which protects trx->lock.trx_locks, but you should understand that this only makes it easier to argue against races at the level of access to the data structure, yet does not buy us any protection at the higher level of making actual decisions based on the result of this call - it may happen that another thread is removing a table lock, and even though lock_table_has returned true to the caller, the lock is no longer in possession of trx once the caller gets to evaluate if/else condition based on the result. Therefore it is up to caller to make sure that the context of the call to this function and making any decisions based on the result is protected from any concurrent modifications. This in turn makes the whole trx_mutex_enter/exit a bit redundant, but it does not affect performance yet makes the reasoning about data structure a bit easier and protects trx->lock.trx_locks data structure from corruption in case our high level reasoning about absence of parallel modifications turns out wrong.

Parameters
[in]trxtransaction
[in]tabletable
[in]modelock mode
Returns
lock or NULL

◆ operator<<() [1/3]

std::ostream & operator<< ( std::ostream &  out,
const lock_rec_t lock 
)
inline

◆ operator<<() [2/3]

std::ostream & operator<< ( std::ostream &  out,
const lock_t lock 
)
inline

◆ operator<<() [3/3]

std::ostream & operator<< ( std::ostream &  out,
const lock_table_t lock 
)
inline

The global output operator is overloaded to conveniently print the lock_table_t object into the given output stream.

Parameters
[in,out]outthe output stream
[in]lockthe table lock
Returns
the given output stream

Variable Documentation

◆ lock_compatibility_matrix

const byte lock_compatibility_matrix[5][5]
static
Initial value:
= {
{true, true, true, false, true},
{true, true, false, false, true},
{true, false, true, false, false},
{false, false, false, false, false},
{true, true, false, false, false}}

◆ LOCK_PAGE_BITMAP_MARGIN

const ulint LOCK_PAGE_BITMAP_MARGIN = 64
static

◆ lock_print_waits

bool lock_print_waits
extern

◆ lock_strength_matrix

const byte lock_strength_matrix[5][5]
static
Initial value:
= {
{true, false, false, false, false},
{true, true, false, false, false},
{true, false, true, false, false},
{true, true, true, true, true},
{false, false, false, false, true}}

◆ lock_types

const ulint lock_types = UT_ARR_SIZE(lock_compatibility_matrix)
static

The count of the types of locks.

◆ MAX_STACK_SIZE

constexpr uint32_t MAX_STACK_SIZE = 4096
constexpr

Maximum depth of the DFS stack.

◆ PRDT_HEAPNO

constexpr uint32_t PRDT_HEAPNO = PAGE_HEAP_NO_INFIMUM
constexpr