MySQL 8.3.0
Source Code Documentation
lock0lock.h File Reference

The transaction lock system. More...

#include "buf0types.h"
#include "dict0types.h"
#include "hash0hash.h"
#include "lock0types.h"
#include "mtr0types.h"
#include "que0types.h"
#include "rem0types.h"
#include "srv0srv.h"
#include "trx0types.h"
#include "univ.i"
#include "ut0vec.h"
#include "gis0rtree.h"
#include "lock0latches.h"
#include "lock0prdt.h"
#include "lock0lock.ic"
#include "lock0guards.h"

Go to the source code of this file.

Classes

class  locksys::Trx_locks_cache
 An object which can be passed to consecutive calls to rec_lock_has_to_wait(trx, mode, lock, is_supremum, trx_locks_cache) for the same trx and heap_no (which is implicitly the bit common to all lock objects passed) which can be used by this function to cache some partial results. More...
 
struct  lock_op_t
 Lock operation struct. More...
 
struct  lock_sys_t
 The lock system struct. More...
 

Namespaces

namespace  locksys
 

Typedefs

typedef ib_mutex_t Lock_mutex
 

Enumerations

enum class  lock_duration_t { REGULAR = 0 , AT_LEAST_STATEMENT = 1 }
 Used to specify the intended duration of a record lock. More...
 

Functions

ulint lock_get_size (void)
 Gets the size of a lock struct. More...
 
void lock_sys_create (ulint n_cells)
 Creates the lock system at database start. More...
 
void lock_sys_resize (ulint n_cells)
 Resize the lock hash tables. More...
 
void lock_sys_close (void)
 Closes the lock system at database shutdown. More...
 
static ulint lock_get_min_heap_no (const buf_block_t *block)
 Gets the heap_no of the smallest user record on a page. More...
 
void lock_move_reorganize_page (const buf_block_t *block, const buf_block_t *oblock)
 Updates the lock table when we have reorganized a page. More...
 
void lock_move_rec_list_end (const buf_block_t *new_block, const buf_block_t *block, const rec_t *rec)
 Moves the explicit locks on user records to another page if a record list end is moved to another page. More...
 
void lock_move_rec_list_start (const buf_block_t *new_block, const buf_block_t *block, const rec_t *rec, const rec_t *old_end)
 Moves the explicit locks on user records to another page if a record list start is moved to another page. More...
 
void lock_update_split_right (const buf_block_t *right_block, const buf_block_t *left_block)
 Updates the lock table when a page is split to the right. More...
 
void lock_update_merge_right (const buf_block_t *right_block, const rec_t *orig_succ, const buf_block_t *left_block)
 Updates the lock table when a page is merged to the right. More...
 
void lock_update_root_raise (const buf_block_t *block, const buf_block_t *root)
 Updates the lock table when the root page is copied to another in btr_root_raise_and_insert. More...
 
void lock_update_copy_and_discard (const buf_block_t *new_block, const buf_block_t *block)
 Updates the lock table when a page is copied to another and the original page is removed from the chain of leaf pages, except if page is the root! More...
 
void lock_update_split_point (const buf_block_t *right_block, const buf_block_t *left_block)
 Requests the Lock System to update record locks regarding the gap between the last record of the left_page and the first record of the right_page when the caller is about to prepended a new record as the first record on the right page, even though it should "naturally" be inserted as the last record of the left_page according to the information in the higher levels of the index. More...
 
void lock_update_split_left (const buf_block_t *right_block, const buf_block_t *left_block)
 Updates the lock table when a page is split to the left. More...
 
void lock_update_merge_left (const buf_block_t *left_block, const rec_t *orig_pred, const buf_block_t *right_block)
 Updates the lock table when a page is merged to the left. More...
 
void lock_rec_reset_and_inherit_gap_locks (const buf_block_t *heir_block, const buf_block_t *block, ulint heir_heap_no, ulint heap_no)
 Resets the original locks on heir and replaces them with gap type locks inherited from rec. More...
 
void lock_update_discard (const buf_block_t *heir_block, ulint heir_heap_no, const buf_block_t *block)
 Updates the lock table when a page is discarded. More...
 
void lock_update_insert (const buf_block_t *block, const rec_t *rec)
 Updates the lock table when a new user record is inserted. More...
 
void lock_update_delete (const buf_block_t *block, const rec_t *rec)
 Updates the lock table when a record is removed. More...
 
void lock_rec_store_on_page_infimum (const buf_block_t *block, const rec_t *rec)
 Stores on the page infimum record the explicit locks of another record. More...
 
void lock_rec_restore_from_page_infimum (const buf_block_t *block, const rec_t *rec, const buf_block_t *donator)
 Restores the state of explicit lock requests on a single record, where the state was stored on the infimum of the page. More...
 
bool lock_rec_expl_exist_on_page (const page_id_t &page_id)
 Determines if there are explicit record locks on a page. More...
 
dberr_t lock_rec_insert_check_and_lock (ulint flags, const rec_t *rec, buf_block_t *block, dict_index_t *index, que_thr_t *thr, mtr_t *mtr, bool *inherit)
 Checks if locks of other transactions prevent an immediate insert of a record. More...
 
dberr_t lock_clust_rec_modify_check_and_lock (ulint flags, const buf_block_t *block, const rec_t *rec, dict_index_t *index, const ulint *offsets, que_thr_t *thr)
 Checks if locks of other transactions prevent an immediate modify (update, delete mark, or delete unmark) of a clustered index record. More...
 
dberr_t lock_sec_rec_modify_check_and_lock (ulint flags, buf_block_t *block, const rec_t *rec, dict_index_t *index, que_thr_t *thr, mtr_t *mtr)
 Checks if locks of other transactions prevent an immediate modify (delete mark or delete unmark) of a secondary index record. More...
 
void lock_on_statement_end (trx_t *trx)
 Called to inform lock-sys that a statement processing for a trx has just finished. More...
 
dberr_t lock_sec_rec_read_check_and_lock (lock_duration_t duration, const buf_block_t *block, const rec_t *rec, dict_index_t *index, const ulint *offsets, select_mode sel_mode, lock_mode mode, ulint gap_mode, que_thr_t *thr)
 Like lock_clust_rec_read_check_and_lock(), but reads a secondary index record. More...
 
dberr_t lock_clust_rec_read_check_and_lock (lock_duration_t duration, const buf_block_t *block, const rec_t *rec, dict_index_t *index, const ulint *offsets, select_mode sel_mode, lock_mode mode, ulint gap_mode, que_thr_t *thr)
 Checks if locks of other transactions prevent an immediate read, or passing over by a read cursor, of a clustered index record. More...
 
dberr_t lock_clust_rec_read_check_and_lock_alt (const buf_block_t *block, const rec_t *rec, dict_index_t *index, lock_mode mode, ulint gap_mode, que_thr_t *thr)
 Checks if locks of other transactions prevent an immediate read, or passing over by a read cursor, of a clustered index record. More...
 
bool lock_clust_rec_cons_read_sees (const rec_t *rec, dict_index_t *index, const ulint *offsets, ReadView *view)
 Checks that a record is seen in a consistent read. More...
 
bool lock_sec_rec_cons_read_sees (const rec_t *rec, const dict_index_t *index, const ReadView *view)
 Checks that a non-clustered index record is seen in a consistent read. More...
 
dberr_t lock_table (ulint flags, dict_table_t *table, lock_mode mode, que_thr_t *thr)
 Locks the specified database table in the mode given. More...
 
void lock_table_ix_resurrect (dict_table_t *table, trx_t *trx)
 Creates a table IX lock object for a resurrected transaction. More...
 
dberr_t lock_table_for_trx (dict_table_t *table, trx_t *trx, enum lock_mode mode)
 Sets a lock on a table based on the given mode. More...
 
void lock_rec_unlock (trx_t *trx, const buf_block_t *block, const rec_t *rec, lock_mode lock_mode)
 Removes a granted record lock of a transaction from the queue and grants locks to other transactions waiting in the queue if they now are entitled to a lock. More...
 
void lock_trx_release_locks (trx_t *trx)
 Releases a transaction's locks, and releases possible other transactions waiting because of these locks. More...
 
void lock_trx_release_read_locks (trx_t *trx, bool only_gap)
 Release read locks of a transaction. More...
 
void lock_make_trx_hit_list (trx_t *trx, hit_list_t &hit_list)
 Iterate over the granted locks which conflict with trx->lock.wait_lock and prepare the hit list for ASYNC Rollback. More...
 
void lock_remove_all_on_table (dict_table_t *table, bool remove_also_table_sx_locks)
 Removes locks on a table to be dropped. More...
 
static uint64_t lock_rec_hash_value (const page_id_t &page_id)
 Calculates the hash value of a page file address: used in inserting or searching for a lock in the hash table or getting global shard index. More...
 
static hash_table_tlock_hash_get (ulint mode)
 Get the lock hash table. More...
 
ulint lock_rec_find_set_bit (const lock_t *lock)
 Looks for a set bit in a record lock bitmap. More...
 
ulint lock_rec_find_next_set_bit (const lock_t *lock, ulint heap_no)
 Looks for the next set bit in the record lock bitmap. More...
 
bool lock_has_to_wait (const lock_t *lock1, const lock_t *lock2)
 Checks if a lock request lock1 has to wait for request lock2. More...
 
bool locksys::has_to_wait (const lock_t *lock1, const lock_t *lock2, Trx_locks_cache &lock1_cache)
 Checks if a lock request lock1 has to wait for request lock2. More...
 
void lock_report_trx_id_insanity (trx_id_t trx_id, const rec_t *rec, const dict_index_t *index, const ulint *offsets, trx_id_t next_trx_id)
 Reports that a transaction id is insensible, i.e., in the future. More...
 
void lock_print_info_summary (FILE *file)
 Prints info of locks for all transactions. More...
 
void lock_trx_print_wait_and_mvcc_state (FILE *file, const trx_t *trx)
 Prints transaction lock wait and MVCC state. More...
 
void lock_print_info_all_transactions (FILE *file)
 Prints info of locks for each transaction. More...
 
ulint lock_number_of_rows_locked (const trx_lock_t *trx_lock)
 Return approximate number or record locks (bits set in the bitmap) for this transaction. More...
 
ulint lock_number_of_tables_locked (const trx_t *trx)
 Return the number of table locks for a transaction. More...
 
uint32_t lock_get_type (const lock_t *lock)
 Gets the type of a lock. More...
 
trx_id_t lock_get_trx_id (const lock_t *lock)
 Gets the id of the transaction owning a lock. More...
 
uint64_t lock_get_trx_immutable_id (const lock_t *lock)
 Gets the immutable id of the transaction owning a lock. More...
 
uint64_t lock_get_immutable_id (const lock_t *lock)
 Gets the immutable id of this lock. More...
 
void lock_get_psi_event (const lock_t *lock, ulonglong *thread_id, ulonglong *event_id)
 Get the performance schema event (thread_id, event_id) that created the lock. More...
 
const lock_tlock_get_first_trx_locks (const trx_lock_t *trx_lock)
 Get the first lock of a trx lock list. More...
 
const lock_tlock_get_next_trx_locks (const lock_t *lock)
 Get the next lock of a trx lock list. More...
 
const char * lock_get_mode_str (const lock_t *lock)
 Gets the mode of a lock in a human readable string. More...
 
const char * lock_get_type_str (const lock_t *lock)
 Gets the type of a lock in a human readable string. More...
 
table_id_t lock_get_table_id (const lock_t *lock)
 Gets the id of the table on which the lock is. More...
 
const table_name_tlock_get_table_name (const lock_t *lock)
 Determine which table a lock is associated with. More...
 
const dict_index_tlock_rec_get_index (const lock_t *lock)
 For a record lock, gets the index on which the lock is. More...
 
const char * lock_rec_get_index_name (const lock_t *lock)
 For a record lock, gets the name of the index on which the lock is. More...
 
page_id_t lock_rec_get_page_id (const lock_t *lock)
 For a record lock, gets the tablespace number and page number on which the lock is. More...
 
bool lock_table_has_locks (const dict_table_t *table)
 Check if there are any locks (table or rec) against table. More...
 
void lock_wait_timeout_thread ()
 A thread which wakes up threads whose lock wait may have lasted too long. More...
 
void lock_wait_request_check_for_cycles ()
 Notifies the thread which analyzes wait-for-graph that there was at least one new edge added or modified ( trx->blocking_trx has changed ), so that the thread will know it has to analyze it. More...
 
void lock_wait_suspend_thread (que_thr_t *thr)
 Puts a user OS thread to wait for a lock to be released. More...
 
void lock_unlock_table_autoinc (trx_t *trx)
 Unlocks AUTO_INC type locks that were possibly reserved by a trx. More...
 
bool lock_cancel_if_waiting_and_release (TrxVersion trx_version)
 Cancels the waiting lock request of the trx, if any. More...
 
void lock_set_timeout_event ()
 Set the lock system timeout event. More...
 
bool lock_check_trx_id_sanity (trx_id_t trx_id, const rec_t *rec, const dict_index_t *index, const ulint *offsets)
 Checks that a transaction id is sensible, i.e., not in the future. More...
 
bool lock_trx_has_rec_x_lock (que_thr_t *thr, const dict_table_t *table, const buf_block_t *block, ulint heap_no)
 Check if the transaction holds an exclusive lock on a record. More...
 
bool lock_validate ()
 Validates the lock system. More...
 
void lock_trx_alloc_locks (trx_t *trx)
 Allocate cached locks for the transaction. More...
 
void lock_rec_convert_impl_to_expl (const buf_block_t *block, const rec_t *rec, dict_index_t *index, const ulint *offsets)
 If a transaction has an implicit x-lock on a record, but no explicit x-lock set on the record, sets one for it. More...
 
void lock_rec_discard (lock_t *in_lock)
 Removes a record lock request, waiting or granted, from the queue. More...
 
void lock_rtr_move_rec_list (const buf_block_t *new_block, const buf_block_t *block, rtr_rec_move_t *rec_move, ulint num_move)
 Moves the explicit locks on user records to another page if a record list start is moved to another page. More...
 
void lock_rec_free_all_from_discard_page (const buf_block_t *block)
 Removes record lock objects set on an index page which is discarded. More...
 
void lock_rec_trx_wait (lock_t *lock, ulint i, ulint type)
 Reset the nth bit of a record lock. More...
 
static bool lock_wait_mutex_own ()
 Test if lock_sys->wait_mutex is owned. More...
 
static void lock_wait_mutex_enter ()
 Acquire the lock_sys->wait_mutex. More...
 
static void lock_wait_mutex_exit ()
 Release the lock_sys->wait_mutex. More...
 
bool locksys::owns_exclusive_global_latch ()
 Tests if lock_sys latch is exclusively owned by the current thread. More...
 
bool locksys::owns_shared_global_latch ()
 Tests if lock_sys latch is owned in shared mode by the current thread. More...
 
bool locksys::owns_page_shard (const page_id_t &page_id)
 Tests if given page shard can be safely accessed by the current thread. More...
 
bool locksys::owns_table_shard (const dict_table_t &table)
 Test if given table shard can be safely accessed by the current thread. More...
 
bool locksys::owns_lock_shard (const lock_t *lock)
 Checks if shard which contains lock is latched (or that an exclusive latch on whole lock_sys is held) by current thread. More...
 

Variables

bool innobase_deadlock_detect
 
lock_sys_tlock_sys
 The lock system. More...
 
constexpr uint32_t LOCK_MODE_MASK = 0xF
 Lock modes and types. More...
 
constexpr uint32_t LOCK_TABLE = 16
 Lock types. More...
 
constexpr uint32_t LOCK_REC = 32
 record lock More...
 
constexpr uint32_t LOCK_TYPE_MASK = 0xF0UL
 mask used to extract lock type from the type_mode field in a lock More...
 
constexpr uint32_t LOCK_WAIT = 256
 Waiting lock flag; when set, it means that the lock has not yet been granted, it is just waiting for its turn in the wait queue. More...
 
constexpr uint32_t LOCK_ORDINARY = 0
 this flag denotes an ordinary next-key lock in contrast to LOCK_GAP or LOCK_REC_NOT_GAP More...
 
constexpr uint32_t LOCK_GAP = 512
 when this bit is set, it means that the lock holds only on the gap before the record; for instance, an x-lock on the gap does not give permission to modify the record on which the bit is set; locks of this type are created when records are removed from the index chain of records More...
 
constexpr uint32_t LOCK_REC_NOT_GAP = 1024
 this bit means that the lock is only on the index record and does NOT block inserts to the gap before the index record; this is used in the case when we retrieve a record with a unique key, and is also used in locking plain SELECTs (not part of UPDATE or DELETE) when the user has set the READ COMMITTED isolation level More...
 
constexpr uint32_t LOCK_INSERT_INTENTION = 2048
 this bit is set when we place a waiting gap type record lock request in order to let an insert of an index record to wait until there are no conflicting locks by other transactions on the gap; note that this flag remains set when the waiting lock is granted, or if the lock is inherited to a neighboring record More...
 
constexpr uint32_t LOCK_PREDICATE = 8192
 Predicate lock. More...
 
constexpr uint32_t LOCK_PRDT_PAGE = 16384
 Page lock. More...
 

Detailed Description

The transaction lock system.

Created 5/7/1996 Heikki Tuuri

Typedef Documentation

◆ Lock_mutex

typedef ib_mutex_t Lock_mutex

Enumeration Type Documentation

◆ lock_duration_t

enum class lock_duration_t
strong

Used to specify the intended duration of a record lock.

Enumerator
REGULAR 

Keep the lock according to the rules of particular isolation level, in particular in case of READ COMMITTED or less restricive modes, do not inherit the lock if the record is purged.

AT_LEAST_STATEMENT 

Keep the lock around for at least the duration of the current statement, in particular make sure it is inherited as gap lock if the record is purged.

Function Documentation

◆ lock_cancel_if_waiting_and_release()

bool lock_cancel_if_waiting_and_release ( TrxVersion  trx_version)

Cancels the waiting lock request of the trx, if any.

If the transaction has already committed (trx->version has changed) or is no longer waiting for a lock (trx->lock.blocking_trx is nullptr) this function will not cancel the waiting lock.

Note
There is a possibility of ABA in which a waiting lock request was already granted or canceled and then the trx requested another lock and started waiting for it - in such case this function might either cancel or not the second request depending on timing. Currently all usages of this function ensure that this is impossible:
  • innodb_kill_connection ensures trx_is_interrupted(trx), thus upon first wake up it will realize it has to report an error and rollback
  • HP transaction marks the trx->in_innodb & TRX_FORCE_ROLLBACK flag which is checked when the trx attempts RecLock::add_to_waitq and reports DB_DEADLOCK
Parameters
[in]trx_versionThe trx we want to wake up and its expected version
Returns
true iff the function did release a waiting lock

◆ lock_check_trx_id_sanity()

bool lock_check_trx_id_sanity ( trx_id_t  trx_id,
const rec_t rec,
const dict_index_t index,
const ulint offsets 
)

Checks that a transaction id is sensible, i.e., not in the future.

Emits an error otherwise.

Parameters
[in]trx_idThe trx id to check, found in user record or secondary index page header
[in]recThe user record which contained the trx_id in its header or in header of its page
[in]indexThe index which contained the rec
[in]offsetsThe result of rec_get_offsets(rec, index)
Returns
true iff ok

◆ lock_clust_rec_cons_read_sees()

bool lock_clust_rec_cons_read_sees ( const rec_t rec,
dict_index_t index,
const ulint offsets,
ReadView view 
)

Checks that a record is seen in a consistent read.

Returns
true if sees, or false if an earlier version of the record should be retrieved in: consistent read view
true if sees, or false if an earlier version of the record should be retrieved
Parameters
recin: user record which should be read or passed over by a read cursor
indexin: clustered index
offsetsin: rec_get_offsets(rec, index)
viewin: consistent read view

◆ lock_clust_rec_modify_check_and_lock()

dberr_t lock_clust_rec_modify_check_and_lock ( ulint  flags,
const buf_block_t block,
const rec_t rec,
dict_index_t index,
const ulint offsets,
que_thr_t thr 
)

Checks if locks of other transactions prevent an immediate modify (update, delete mark, or delete unmark) of a clustered index record.

If they do, first tests if the query thread should anyway be suspended for some reason; if not, then puts the transaction and the query thread to the lock wait state and inserts a waiting request for a record x-lock to the lock queue.

Returns
DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK in: query thread

If they do, first tests if the query thread should anyway be suspended for some reason; if not, then puts the transaction and the query thread to the lock wait state and inserts a waiting request for a record x-lock to the lock queue.

Returns
DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK
Parameters
flagsin: if BTR_NO_LOCKING_FLAG bit is set, does nothing
blockin: buffer block of rec
recin: record which should be modified
indexin: clustered index
offsetsin: rec_get_offsets(rec, index)
thrin: query thread

◆ lock_clust_rec_read_check_and_lock()

dberr_t lock_clust_rec_read_check_and_lock ( lock_duration_t  duration,
const buf_block_t block,
const rec_t rec,
dict_index_t index,
const ulint offsets,
select_mode  sel_mode,
lock_mode  mode,
ulint  gap_mode,
que_thr_t thr 
)

Checks if locks of other transactions prevent an immediate read, or passing over by a read cursor, of a clustered index record.

If they do, first tests if the query thread should anyway be suspended for some reason; if not, then puts the transaction and the query thread to the lock wait state and inserts a waiting request for a record lock to the lock queue. Sets the requested mode lock on the record.

Parameters
[in]durationIf equal to AT_LEAST_STATEMENT, then makes sure that the lock will be kept around and inherited for at least the duration of current statement. If equal to REGULAR the life-cycle of the lock will depend on isolation level rules.
[in]blockbuffer block of rec
[in]recuser record or page supremum record which should be read or passed over by a read cursor
[in]indexsecondary index
[in]offsetsrec_get_offsets(rec, index)
[in]sel_modeselect mode: SELECT_ORDINARY, SELECT_SKIP_LOKCED, or SELECT_NO_WAIT
[in]modemode of the lock which the read cursor should set on records: LOCK_S or LOCK_X; the latter is possible in SELECT FOR UPDATE
[in]gap_modeLOCK_ORDINARY, LOCK_GAP, or LOCK_REC_NOT_GAP
[in,out]thrquery thread
Returns
DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK, DB_SKIP_LOCKED, or DB_LOCK_NOWAIT

◆ lock_clust_rec_read_check_and_lock_alt()

dberr_t lock_clust_rec_read_check_and_lock_alt ( const buf_block_t block,
const rec_t rec,
dict_index_t index,
lock_mode  mode,
ulint  gap_mode,
que_thr_t thr 
)

Checks if locks of other transactions prevent an immediate read, or passing over by a read cursor, of a clustered index record.

If they do, first tests if the query thread should anyway be suspended for some reason; if not, then puts the transaction and the query thread to the lock wait state and inserts a waiting request for a record lock to the lock queue. Sets the requested mode lock on the record. This is an alternative version of lock_clust_rec_read_check_and_lock() that does not require the parameter "offsets".

Returns
DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK in: query thread

If they do, first tests if the query thread should anyway be suspended for some reason; if not, then puts the transaction and the query thread to the lock wait state and inserts a waiting request for a record lock to the lock queue. Sets the requested mode lock on the record. This is an alternative version of lock_clust_rec_read_check_and_lock() that does not require the parameter "offsets".

Returns
DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK
Parameters
blockin: buffer block of rec
recin: user record or page supremum record which should be read or passed over by a read cursor
indexin: clustered index
modein: mode of the lock which the read cursor should set on records: LOCK_S or LOCK_X; the latter is possible in SELECT FOR UPDATE
gap_modein: LOCK_ORDINARY, LOCK_GAP, or LOCK_REC_NOT_GAP
thrin: query thread

◆ lock_get_first_trx_locks()

const lock_t * lock_get_first_trx_locks ( const trx_lock_t trx_lock)

Get the first lock of a trx lock list.

Parameters
[in]trx_lockthe trx lock
Returns
The first lock

◆ lock_get_immutable_id()

uint64_t lock_get_immutable_id ( const lock_t lock)

Gets the immutable id of this lock.

Parameters
[in]lockThe lock we are interested in
Returns
The lock's immutable id

◆ lock_get_min_heap_no()

static ulint lock_get_min_heap_no ( const buf_block_t block)
inlinestatic

Gets the heap_no of the smallest user record on a page.

Returns
heap_no of smallest user record, or PAGE_HEAP_NO_SUPREMUM in: buffer block

◆ lock_get_mode_str()

const char * lock_get_mode_str ( const lock_t lock)

Gets the mode of a lock in a human readable string.

The string should not be free()'d or modified.

Returns
lock mode in: lock

The string should not be free()'d or modified. This functions is a bit complex for following reasons:

  • the way it is used in performance schema requires that the memory pointed by the return value is accessible for a long time
  • the caller never frees the memory
  • so, we need to maintain a pool of these strings or use string literals
  • there are many possible combinations of flags and thus it is impractical to maintain the list of all possible literals and if/else logic
  • moreover, sometimes performance_schema.data_locks is used precisely to investigate some unexpected situation, thus limiting output of this function only to expected combinations of flags might be misleading
    Returns
    lock mode
Parameters
lockin: lock

◆ lock_get_next_trx_locks()

const lock_t * lock_get_next_trx_locks ( const lock_t lock)

Get the next lock of a trx lock list.

Parameters
[in]lockthe current lock
Returns
The next lock

◆ lock_get_psi_event()

void lock_get_psi_event ( const lock_t lock,
ulonglong thread_id,
ulonglong event_id 
)

Get the performance schema event (thread_id, event_id) that created the lock.

Parameters
[in]lockLock
[out]thread_idThread ID that created the lock
[out]event_idEvent ID that created the lock

◆ lock_get_size()

ulint lock_get_size ( void  )

Gets the size of a lock struct.

Returns
size in bytes

◆ lock_get_table_id()

table_id_t lock_get_table_id ( const lock_t lock)

Gets the id of the table on which the lock is.

Returns
id of the table in: lock
id of the table
Parameters
lockin: lock

◆ lock_get_table_name()

const table_name_t & lock_get_table_name ( const lock_t lock)

Determine which table a lock is associated with.

Parameters
[in]lockthe lock
Returns
name of the table

◆ lock_get_trx_id()

trx_id_t lock_get_trx_id ( const lock_t lock)

Gets the id of the transaction owning a lock.

Parameters
[in]lockA lock of the transaction we are interested in
Returns
the transaction's id

◆ lock_get_trx_immutable_id()

uint64_t lock_get_trx_immutable_id ( const lock_t lock)

Gets the immutable id of the transaction owning a lock.

Parameters
[in]lockA lock of the transaction we are interested in
Returns
the transaction's immutable id

◆ lock_get_type()

uint32_t lock_get_type ( const lock_t lock)

Gets the type of a lock.

Non-inline version for using outside of the lock module.

Returns
LOCK_TABLE or LOCK_REC in: lock

Non-inline version for using outside of the lock module.

Returns
LOCK_TABLE or LOCK_REC
Parameters
lockin: lock

◆ lock_get_type_str()

const char * lock_get_type_str ( const lock_t lock)

Gets the type of a lock in a human readable string.

The string should not be free()'d or modified.

Returns
lock type in: lock

The string should not be free()'d or modified.

Returns
lock type
Parameters
lockin: lock

◆ lock_has_to_wait()

bool lock_has_to_wait ( const lock_t lock1,
const lock_t lock2 
)

Checks if a lock request lock1 has to wait for request lock2.

Parameters
[in]lock1A waiting lock
[in]lock2Another lock; NOTE that it is assumed that this has a lock bit set on the same record as in lock1 if the locks are record lock
Returns
true if lock1 has to wait for lock2 to be removed

◆ lock_hash_get()

static hash_table_t * lock_hash_get ( ulint  mode)
inlinestatic

Get the lock hash table.

in: lock mode

◆ lock_make_trx_hit_list()

void lock_make_trx_hit_list ( trx_t trx,
hit_list_t hit_list 
)

Iterate over the granted locks which conflict with trx->lock.wait_lock and prepare the hit list for ASYNC Rollback.

If the transaction is waiting for some other lock then wake up with deadlock error. Currently we don't mark following transactions for ASYNC Rollback.

  1. Read only transactions
  2. Background transactions
  3. Other High priority transactions
    Parameters
    [in]trxHigh Priority transaction
    [in,out]hit_listList of transactions which need to be rolled back

◆ lock_move_rec_list_end()

void lock_move_rec_list_end ( const buf_block_t new_block,
const buf_block_t block,
const rec_t rec 
)

Moves the explicit locks on user records to another page if a record list end is moved to another page.

Parameters
[in]new_blockIndex page to move to
[in]blockIndex page
[in,out]recRecord on page: this is the first record moved

◆ lock_move_rec_list_start()

void lock_move_rec_list_start ( const buf_block_t new_block,
const buf_block_t block,
const rec_t rec,
const rec_t old_end 
)

Moves the explicit locks on user records to another page if a record list start is moved to another page.

Parameters
[in]new_blockIndex page to move to
[in]blockIndex page
[in,out]recRecord on page: this is the first record not copied
[in]old_endOld previous-to-last record on new_page before the records were copied

◆ lock_move_reorganize_page()

void lock_move_reorganize_page ( const buf_block_t block,
const buf_block_t oblock 
)

Updates the lock table when we have reorganized a page.

NOTE: we copy also the locks set on the infimum of the page; the infimum may carry locks if an update of a record is occurring on the page, and its locks were temporarily stored on the infimum. in: copy of the old, not reorganized page

NOTE: we copy also the locks set on the infimum of the page; the infimum may carry locks if an update of a record is occurring on the page, and its locks were temporarily stored on the infimum.

Parameters
blockin: old index page, now reorganized
oblockin: copy of the old, not reorganized page

◆ lock_number_of_rows_locked()

ulint lock_number_of_rows_locked ( const trx_lock_t trx_lock)

Return approximate number or record locks (bits set in the bitmap) for this transaction.

Since delete-marked records may be removed, the record count will not be precise. The caller must be holding exclusive global lock_sys latch.

Parameters
[in]trx_locktransaction locks

◆ lock_number_of_tables_locked()

ulint lock_number_of_tables_locked ( const trx_t trx)

Return the number of table locks for a transaction.

The caller must be holding trx->mutex.

Parameters
[in]trxthe transaction for which we want the number of table locks

◆ lock_on_statement_end()

void lock_on_statement_end ( trx_t trx)

Called to inform lock-sys that a statement processing for a trx has just finished.

Parameters
[in]trxtransaction which has finished processing a statement

◆ lock_print_info_all_transactions()

void lock_print_info_all_transactions ( FILE *  file)

Prints info of locks for each transaction.

This function assumes that the caller holds the exclusive global latch and more importantly it may release and reacquire it on behalf of the caller. (This should be fixed in the future).

Parameters
[in,out]filethe file where to print

◆ lock_print_info_summary()

void lock_print_info_summary ( FILE *  file)

Prints info of locks for all transactions.

Parameters
[in]filefile where to print

◆ lock_rec_convert_impl_to_expl()

void lock_rec_convert_impl_to_expl ( const buf_block_t block,
const rec_t rec,
dict_index_t index,
const ulint offsets 
)

If a transaction has an implicit x-lock on a record, but no explicit x-lock set on the record, sets one for it.

Parameters
[in]blockbuffer block of rec
[in]recuser record on page
[in]indexindex of record
[in]offsetsrec_get_offsets(rec, index)

◆ lock_rec_discard()

void lock_rec_discard ( lock_t in_lock)

Removes a record lock request, waiting or granted, from the queue.

in: record lock object: all record locks which are contained in this lock object are removed

Parameters
[in]in_lockrecord lock object: all record locks which are contained in this lock object are removed

◆ lock_rec_expl_exist_on_page()

bool lock_rec_expl_exist_on_page ( const page_id_t page_id)

Determines if there are explicit record locks on a page.

Parameters
[in]page_idspace id and page number
Returns
true iff an explicit record lock on the page exists

◆ lock_rec_find_next_set_bit()

ulint lock_rec_find_next_set_bit ( const lock_t lock,
ulint  heap_no 
)

Looks for the next set bit in the record lock bitmap.

Parameters
[in]lockrecord lock with at least one bit set
[in]heap_nocurrent set bit
Returns
The next bit index == heap number following heap_no, or ULINT_UNDEFINED if none found

◆ lock_rec_find_set_bit()

ulint lock_rec_find_set_bit ( const lock_t lock)

Looks for a set bit in a record lock bitmap.

Returns ULINT_UNDEFINED, if none found.

Parameters
[in]lockA record lock
Returns
bit index == heap number of the record, or ULINT_UNDEFINED if none found

◆ lock_rec_free_all_from_discard_page()

void lock_rec_free_all_from_discard_page ( const buf_block_t block)

Removes record lock objects set on an index page which is discarded.

This function does not move locks, or check for waiting locks, therefore the lock bitmaps must already be reset when this function is called. in: page to be discarded

This function does not move locks, or check for waiting locks, therefore the lock bitmaps must already be reset when this function is called.

Parameters
blockin: page to be discarded

◆ lock_rec_get_index()

const dict_index_t * lock_rec_get_index ( const lock_t lock)

For a record lock, gets the index on which the lock is.

Returns
index in: lock
index
Parameters
lockin: lock

◆ lock_rec_get_index_name()

const char * lock_rec_get_index_name ( const lock_t lock)

For a record lock, gets the name of the index on which the lock is.

The string should not be free()'d or modified.

Returns
name of the index in: lock

The string should not be free()'d or modified.

Returns
name of the index
Parameters
lockin: lock

◆ lock_rec_get_page_id()

page_id_t lock_rec_get_page_id ( const lock_t lock)

For a record lock, gets the tablespace number and page number on which the lock is.

Returns
tablespace number in: lock

◆ lock_rec_hash_value()

static uint64_t lock_rec_hash_value ( const page_id_t page_id)
inlinestatic

Calculates the hash value of a page file address: used in inserting or searching for a lock in the hash table or getting global shard index.

Parameters
page_idspecifies the page
Returns
hash value

◆ lock_rec_insert_check_and_lock()

dberr_t lock_rec_insert_check_and_lock ( ulint  flags,
const rec_t rec,
buf_block_t block,
dict_index_t index,
que_thr_t thr,
mtr_t mtr,
bool *  inherit 
)

Checks if locks of other transactions prevent an immediate insert of a record.

If they do, first tests if the query thread should anyway be suspended for some reason; if not, then puts the transaction and the query thread to the lock wait state and inserts a waiting request for a gap x-lock to the lock queue.

Returns
DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK out: set to true if the new inserted record maybe should inherit LOCK_GAP type locks from the successor record

If they do, first tests if the query thread should anyway be suspended for some reason; if not, then puts the transaction and the query thread to the lock wait state and inserts a waiting request for a gap x-lock to the lock queue.

Returns
DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK
Parameters
flagsin: if BTR_NO_LOCKING_FLAG bit is set, does nothing
recin: record after which to insert
blockin/out: buffer block of rec
indexin: index
thrin: query thread
mtrin/out: mini-transaction
inheritout: set to true if the new inserted record maybe should inherit LOCK_GAP type locks from the successor record

◆ lock_rec_reset_and_inherit_gap_locks()

void lock_rec_reset_and_inherit_gap_locks ( const buf_block_t heir_block,
const buf_block_t block,
ulint  heir_heap_no,
ulint  heap_no 
)

Resets the original locks on heir and replaces them with gap type locks inherited from rec.

Parameters
[in]heir_blockBlock containing the record which inherits
[in]blockBlock containing the record from which inherited; does not reset the locks on this record
[in]heir_heap_noHeap_no of the inheriting record
[in]heap_noHeap_no of the donating record

◆ lock_rec_restore_from_page_infimum()

void lock_rec_restore_from_page_infimum ( const buf_block_t block,
const rec_t rec,
const buf_block_t donator 
)

Restores the state of explicit lock requests on a single record, where the state was stored on the infimum of the page.

Parameters
[in]blockBuffer block containing rec
[in]recRecord whose lock state is restored
[in]donatorPage (rec is not necessarily on this page) whose infimum stored the lock state; lock bits are reset on the infimum

◆ lock_rec_store_on_page_infimum()

void lock_rec_store_on_page_infimum ( const buf_block_t block,
const rec_t rec 
)

Stores on the page infimum record the explicit locks of another record.

This function is used to store the lock state of a record when it is updated and the size of the record changes in the update. The record is in such an update moved, perhaps to another page. The infimum record acts as a dummy carrier record, taking care of lock releases while the actual record is being moved. in: record whose lock state is stored on the infimum record of the same page; lock bits are reset on the record

This function is used to store the lock state of a record when it is updated and the size of the record changes in the update. The record is moved in such an update, perhaps to another page. The infimum record acts as a dummy carrier record, taking care of lock releases while the actual record is being moved.

Parameters
blockin: buffer block containing rec
recin: record whose lock state is stored on the infimum record of the same page; lock bits are reset on the record

◆ lock_rec_trx_wait()

void lock_rec_trx_wait ( lock_t lock,
ulint  i,
ulint  type 
)

Reset the nth bit of a record lock.

Parameters
[in,out]lockrecord lock
[in]iindex of the bit that will be reset
[in]typewhether the lock is in wait mode

◆ lock_rec_unlock()

void lock_rec_unlock ( trx_t trx,
const buf_block_t block,
const rec_t rec,
lock_mode  lock_mode 
)

Removes a granted record lock of a transaction from the queue and grants locks to other transactions waiting in the queue if they now are entitled to a lock.

in: LOCK_S or LOCK_X

This function is meant to be used only by row_try_unlock, and it assumes that the lock we are looking for has LOCK_REC_NOT_GAP flag.

Parameters
trxin/out: transaction that has set a record lock
blockin: buffer block containing rec
recin: record
lock_modein: LOCK_S or LOCK_X

◆ lock_remove_all_on_table()

void lock_remove_all_on_table ( dict_table_t table,
bool  remove_also_table_sx_locks 
)

Removes locks on a table to be dropped.

If remove_also_table_sx_locks is true then table-level S and X locks are also removed in addition to other table-level and record-level locks. No lock, that is going to be removed, is allowed to be a wait lock. in: also removes table S and X locks

If remove_also_table_sx_locks is true then table-level S and X locks are also removed in addition to other table-level and record-level locks. No lock, that is going to be removed, is allowed to be a wait lock.

Parameters
tablein: table to be dropped or discarded
remove_also_table_sx_locksin: also removes table S and X locks

◆ lock_report_trx_id_insanity()

void lock_report_trx_id_insanity ( trx_id_t  trx_id,
const rec_t rec,
const dict_index_t index,
const ulint offsets,
trx_id_t  next_trx_id 
)

Reports that a transaction id is insensible, i.e., in the future.

Parameters
[in]trx_idTrx id
[in]recUser record
[in]indexIndex
[in]offsetsRec_get_offsets(rec, index)
[in]next_trx_idvalue received from trx_sys_get_next_trx_id_or_no()

◆ lock_rtr_move_rec_list()

void lock_rtr_move_rec_list ( const buf_block_t new_block,
const buf_block_t block,
rtr_rec_move_t rec_move,
ulint  num_move 
)

Moves the explicit locks on user records to another page if a record list start is moved to another page.

Parameters
[in]new_blockIndex page to move to
[in]blockIndex page
[in]rec_moveRecording records moved
[in]num_moveNum of rec to move

◆ lock_sec_rec_cons_read_sees()

bool lock_sec_rec_cons_read_sees ( const rec_t rec,
const dict_index_t index,
const ReadView view 
)

Checks that a non-clustered index record is seen in a consistent read.

NOTE that a non-clustered index page contains so little information on its modifications that also in the case false, the present version of rec may be the right, but we must check this from the clustered index record.

Returns
true if certainly sees, or false if an earlier version of the clustered index record might be needed in: consistent read view

NOTE that a non-clustered index page contains so little information on its modifications that also in the case false, the present version of rec may be the right, but we must check this from the clustered index record.

Returns
true if certainly sees, or false if an earlier version of the clustered index record might be needed
Parameters
recin: user record which should be read or passed over by a read cursor
indexin: index
viewin: consistent read view

◆ lock_sec_rec_modify_check_and_lock()

dberr_t lock_sec_rec_modify_check_and_lock ( ulint  flags,
buf_block_t block,
const rec_t rec,
dict_index_t index,
que_thr_t thr,
mtr_t mtr 
)

Checks if locks of other transactions prevent an immediate modify (delete mark or delete unmark) of a secondary index record.

Returns
DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK in/out: mini-transaction
DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK
Parameters
flagsin: if BTR_NO_LOCKING_FLAG bit is set, does nothing
blockin/out: buffer block of rec
recin: record which should be modified; NOTE: as this is a secondary index, we always have to modify the clustered index record first: see the comment below
indexin: secondary index
thrin: query thread (can be NULL if BTR_NO_LOCKING_FLAG)
mtrin/out: mini-transaction

◆ lock_sec_rec_read_check_and_lock()

dberr_t lock_sec_rec_read_check_and_lock ( lock_duration_t  duration,
const buf_block_t block,
const rec_t rec,
dict_index_t index,
const ulint offsets,
select_mode  sel_mode,
lock_mode  mode,
ulint  gap_mode,
que_thr_t thr 
)

Like lock_clust_rec_read_check_and_lock(), but reads a secondary index record.

Parameters
[in]durationIf equal to AT_LEAST_STATEMENT, then makes sure that the lock will be kept around and inherited for at least the duration of current statement. If equal to REGULAR the life-cycle of the lock will depend on isolation level rules.
[in]blockbuffer block of rec
[in]recuser record or page supremum record which should be read or passed over by a read cursor
[in]indexsecondary index
[in]offsetsrec_get_offsets(rec, index)
[in]sel_modeselect mode: SELECT_ORDINARY, SELECT_SKIP_LOKCED, or SELECT_NO_WAIT
[in]modemode of the lock which the read cursor should set on records: LOCK_S or LOCK_X; the latter is possible in SELECT FOR UPDATE
[in]gap_modeLOCK_ORDINARY, LOCK_GAP, or LOCK_REC_NOT_GAP
[in,out]thrquery thread
Returns
DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK, DB_SKIP_LOCKED, or DB_LOCK_NOWAIT

◆ lock_set_timeout_event()

void lock_set_timeout_event ( )

Set the lock system timeout event.

◆ lock_sys_close()

void lock_sys_close ( void  )

Closes the lock system at database shutdown.

◆ lock_sys_create()

void lock_sys_create ( ulint  n_cells)

Creates the lock system at database start.

in: number of slots in lock hash table

Parameters
n_cellsin: number of slots in lock hash table

◆ lock_sys_resize()

void lock_sys_resize ( ulint  n_cells)

Resize the lock hash tables.

Parameters
[in]n_cellsnumber of slots in lock hash table

◆ lock_table()

dberr_t lock_table ( ulint  flags,
dict_table_t table,
lock_mode  mode,
que_thr_t thr 
)

Locks the specified database table in the mode given.

If the lock cannot be granted immediately, the query thread is put to wait.

Returns
DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK in: query thread

If the lock cannot be granted immediately, the query thread is put to wait.

Returns
DB_SUCCESS, DB_LOCK_WAIT, or DB_DEADLOCK
Parameters
flagsin: if BTR_NO_LOCKING_FLAG bit is set, does nothing
tablein/out: database table in dictionary cache
modein: lock mode
thrin: query thread

◆ lock_table_for_trx()

dberr_t lock_table_for_trx ( dict_table_t table,
trx_t trx,
enum lock_mode  mode 
)

Sets a lock on a table based on the given mode.

Parameters
[in]tabletable to lock
[in,out]trxtransaction
[in]modeLOCK_X or LOCK_S
Returns
error code or DB_SUCCESS.

◆ lock_table_has_locks()

bool lock_table_has_locks ( const dict_table_t table)

Check if there are any locks (table or rec) against table.

Returned value might be obsolete.

Parameters
[in]tablethe table
Returns
true if there were any locks held on records in this table or on the table itself at some point in time during the call

The n_rec_locks field might be modified by operation on any page shard. This function is called in contexts where we believe that the number of locks should either be zero or decreasing. For such scenario of usage, we can read the n_rec_locks without any latch and restrict latch just to the table's shard and release it before return, which means true could be a false-positive, but false is certain.

◆ lock_table_ix_resurrect()

void lock_table_ix_resurrect ( dict_table_t table,
trx_t trx 
)

Creates a table IX lock object for a resurrected transaction.

Parameters
[in,out]tableTable
[in,out]trxTransaction

◆ lock_trx_alloc_locks()

void lock_trx_alloc_locks ( trx_t trx)

Allocate cached locks for the transaction.

Parameters
trxallocate cached record locks for this transaction

◆ lock_trx_has_rec_x_lock()

bool lock_trx_has_rec_x_lock ( que_thr_t thr,
const dict_table_t table,
const buf_block_t block,
ulint  heap_no 
)

Check if the transaction holds an exclusive lock on a record.

Parameters
[in]thrquery thread of the transaction
[in]tabletable to check
[in]blockbuffer block of the record
[in]heap_norecord heap number
Returns
whether the locks are held

◆ lock_trx_print_wait_and_mvcc_state()

void lock_trx_print_wait_and_mvcc_state ( FILE *  file,
const trx_t trx 
)

Prints transaction lock wait and MVCC state.

Parameters
[in,out]filefile where to print
[in]trxtransaction

◆ lock_trx_release_locks()

void lock_trx_release_locks ( trx_t trx)

Releases a transaction's locks, and releases possible other transactions waiting because of these locks.

Change the state of the transaction to TRX_STATE_COMMITTED_IN_MEMORY. in/out: transaction

Change the state of the transaction to TRX_STATE_COMMITTED_IN_MEMORY.

Doing an implicit to explicit conversion should not be expensive.

Parameters
trxin/out: transaction

◆ lock_trx_release_read_locks()

void lock_trx_release_read_locks ( trx_t trx,
bool  only_gap 
)

Release read locks of a transaction.

It is called during XA prepare to release locks early.

Parameters
[in,out]trxtransaction
[in]only_gaprelease only GAP locks

◆ lock_unlock_table_autoinc()

void lock_unlock_table_autoinc ( trx_t trx)

Unlocks AUTO_INC type locks that were possibly reserved by a trx.

This function should be called at the the end of an SQL statement, by the connection thread that owns the transaction (trx->mysql_thd). in/out: transaction

This function should be called at the the end of an SQL statement, by the connection thread that owns the transaction (trx->mysql_thd).

Parameters
trxin/out: transaction

◆ lock_update_copy_and_discard()

void lock_update_copy_and_discard ( const buf_block_t new_block,
const buf_block_t block 
)

Updates the lock table when a page is copied to another and the original page is removed from the chain of leaf pages, except if page is the root!

Parameters
[in]new_blockIndex page to which copied
[in]blockIndex page; not the root!

◆ lock_update_delete()

void lock_update_delete ( const buf_block_t block,
const rec_t rec 
)

Updates the lock table when a record is removed.

Parameters
[in]blockBuffer block containing rec
[in]recThe record to be removed

◆ lock_update_discard()

void lock_update_discard ( const buf_block_t heir_block,
ulint  heir_heap_no,
const buf_block_t block 
)

Updates the lock table when a page is discarded.

Parameters
[in]heir_blockIndex page which will inherit the locks
[in]heir_heap_noHeap_no of the record which will inherit the locks
[in]blockIndex page which will be discarded

◆ lock_update_insert()

void lock_update_insert ( const buf_block_t block,
const rec_t rec 
)

Updates the lock table when a new user record is inserted.

Parameters
[in]blockBuffer block containing rec
[in]recThe inserted record
Parameters
blockin: buffer block containing rec
recin: the inserted record

◆ lock_update_merge_left()

void lock_update_merge_left ( const buf_block_t left_block,
const rec_t orig_pred,
const buf_block_t right_block 
)

Updates the lock table when a page is merged to the left.

Parameters
[in]left_blockLeft page to which merged
[in]orig_predOriginal predecessor of supremum on the left page before merge
[in]right_blockMerged index page which will be discarded

◆ lock_update_merge_right()

void lock_update_merge_right ( const buf_block_t right_block,
const rec_t orig_succ,
const buf_block_t left_block 
)

Updates the lock table when a page is merged to the right.

Parameters
[in]right_blockRight page to which merged
[in]orig_succOriginal successor of infimum on the right page before merge
[in]left_blockMerged index page which will be discarded

◆ lock_update_root_raise()

void lock_update_root_raise ( const buf_block_t block,
const buf_block_t root 
)

Updates the lock table when the root page is copied to another in btr_root_raise_and_insert.

Note that we leave lock structs on the root page, even though they do not make sense on other than leaf pages: the reason is that in a pessimistic update the infimum record of the root page will act as a dummy carrier of the locks of the record to be updated. in: root page

Note that we leave lock structs on the root page, even though they do not make sense on other than leaf pages: the reason is that in a pessimistic update the infimum record of the root page will act as a dummy carrier of the locks of the record to be updated.

Parameters
blockin: index page to which copied
rootin: root page

◆ lock_update_split_left()

void lock_update_split_left ( const buf_block_t right_block,
const buf_block_t left_block 
)

Updates the lock table when a page is split to the left.

Parameters
[in]right_blockRight page
[in]left_blockLeft page

◆ lock_update_split_point()

void lock_update_split_point ( const buf_block_t right_block,
const buf_block_t left_block 
)

Requests the Lock System to update record locks regarding the gap between the last record of the left_page and the first record of the right_page when the caller is about to prepended a new record as the first record on the right page, even though it should "naturally" be inserted as the last record of the left_page according to the information in the higher levels of the index.

That is, we assume that the lowest common ancestor of the left_page and the right_page routes the key of the new record to the left_page, but a heuristic which tries to avoid overflowing the left_page has chosen to prepend the new record to the right_page instead. Said ancestor performs this routing by comparing the key of the record to a "split point" - the key associated with the right_page's subtree, such that all records larger than that split point are to be found in the right_page (or some even further page). Ideally this should be the minimum key in this whole subtree, however due to the way we optimize the DELETE and INSERT operations, we often do not update this information, so that such "split point" can actually be smaller than the real minimum. Still, even if not up-to-date, its value is always correct, in that it really separates the subtrees (keys smaller than "split point" are not in left_page and larger are not in right_page).

The reason this is important to Lock System, is that the gap between the last record on the left_page and the first record on the right_page is represented as two gaps:

  1. The gap between the last record on the left_page and the "split point", represented as the gap before the supremum pseudo-record of the left_page.
  2. The gap between the "split point" and the first record of the right_page, represented as the gap before the first user record of the right_page.

Thus, inserting the new record, and subsequently adjusting "split points" in its ancestors to values smaller or equal to the new records' key, will mean that gap will be sliced at a different place ("moved to the left"): fragment of the 1st gap will now become treated as 2nd. Therefore, Lock System must copy any GRANTED locks from 1st gap to the 2nd gap. Any WAITING locks must be of INSERT_INTENTION type (as no other GAP locks ever wait for anything) and can stay at 1st gap, as their only purpose is to notify the requester they can retry insertion, and there's no correctness requirement to avoid waking them up too soon.

Parameters
[in]right_blockRight page
[in]left_blockLeft page

◆ lock_update_split_right()

void lock_update_split_right ( const buf_block_t right_block,
const buf_block_t left_block 
)

Updates the lock table when a page is split to the right.

Parameters
[in]right_blockRight page
[in]left_blockLeft page

◆ lock_validate()

bool lock_validate ( )

Validates the lock system.

Returns
true if ok

◆ lock_wait_mutex_enter()

static void lock_wait_mutex_enter ( )
inlinestatic

Acquire the lock_sys->wait_mutex.

◆ lock_wait_mutex_exit()

static void lock_wait_mutex_exit ( )
inlinestatic

Release the lock_sys->wait_mutex.

◆ lock_wait_mutex_own()

static bool lock_wait_mutex_own ( )
inlinestatic

Test if lock_sys->wait_mutex is owned.

◆ lock_wait_request_check_for_cycles()

void lock_wait_request_check_for_cycles ( )

Notifies the thread which analyzes wait-for-graph that there was at least one new edge added or modified ( trx->blocking_trx has changed ), so that the thread will know it has to analyze it.

◆ lock_wait_suspend_thread()

void lock_wait_suspend_thread ( que_thr_t thr)

Puts a user OS thread to wait for a lock to be released.

If an error occurs during the wait trx->error_state associated with thr is != DB_SUCCESS when we return. DB_INTERRUPTED, DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK are possible errors. DB_DEADLOCK is returned if selective deadlock resolution chose this transaction as a victim. in: query thread associated with the user OS thread

◆ lock_wait_timeout_thread()

void lock_wait_timeout_thread ( )

A thread which wakes up threads whose lock wait may have lasted too long.

A thread which wakes up threads whose lock wait may have lasted too long.

The last time we've checked for timeouts.

Variable Documentation

◆ innobase_deadlock_detect

bool innobase_deadlock_detect
extern

◆ LOCK_GAP

constexpr uint32_t LOCK_GAP = 512
constexpr

when this bit is set, it means that the lock holds only on the gap before the record; for instance, an x-lock on the gap does not give permission to modify the record on which the bit is set; locks of this type are created when records are removed from the index chain of records

◆ LOCK_INSERT_INTENTION

constexpr uint32_t LOCK_INSERT_INTENTION = 2048
constexpr

this bit is set when we place a waiting gap type record lock request in order to let an insert of an index record to wait until there are no conflicting locks by other transactions on the gap; note that this flag remains set when the waiting lock is granted, or if the lock is inherited to a neighboring record

◆ LOCK_MODE_MASK

constexpr uint32_t LOCK_MODE_MASK = 0xF
constexpr

Lock modes and types.

mask used to extract mode from the type_mode field in a lock

◆ LOCK_ORDINARY

constexpr uint32_t LOCK_ORDINARY = 0
constexpr

this flag denotes an ordinary next-key lock in contrast to LOCK_GAP or LOCK_REC_NOT_GAP

◆ LOCK_PRDT_PAGE

constexpr uint32_t LOCK_PRDT_PAGE = 16384
constexpr

Page lock.

◆ LOCK_PREDICATE

constexpr uint32_t LOCK_PREDICATE = 8192
constexpr

Predicate lock.

◆ LOCK_REC

constexpr uint32_t LOCK_REC = 32
constexpr

record lock

◆ LOCK_REC_NOT_GAP

constexpr uint32_t LOCK_REC_NOT_GAP = 1024
constexpr

this bit means that the lock is only on the index record and does NOT block inserts to the gap before the index record; this is used in the case when we retrieve a record with a unique key, and is also used in locking plain SELECTs (not part of UPDATE or DELETE) when the user has set the READ COMMITTED isolation level

◆ lock_sys

lock_sys_t* lock_sys
extern

The lock system.

◆ LOCK_TABLE

constexpr uint32_t LOCK_TABLE = 16
constexpr

Lock types.

table lock

◆ LOCK_TYPE_MASK

constexpr uint32_t LOCK_TYPE_MASK = 0xF0UL
constexpr

mask used to extract lock type from the type_mode field in a lock

◆ LOCK_WAIT

constexpr uint32_t LOCK_WAIT = 256
constexpr

Waiting lock flag; when set, it means that the lock has not yet been granted, it is just waiting for its turn in the wait queue.