MySQL 9.1.0
Source Code Documentation
lock0lock.cc File Reference

The transaction lock system. More...

#include <mysql/service_thd_engine_lock.h>
#include <sys/types.h>
#include <algorithm>
#include <bit>
#include <set>
#include <unordered_map>
#include <vector>
#include "btr0btr.h"
#include "current_thd.h"
#include "debug_sync.h"
#include "dict0boot.h"
#include "dict0mem.h"
#include "ha_prototypes.h"
#include "lock0lock.h"
#include "lock0priv.h"
#include "os0thread.h"
#include "pars0pars.h"
#include "row0mysql.h"
#include "row0sel.h"
#include "srv0mon.h"
#include "trx0purge.h"
#include "trx0sys.h"
#include "usr0sess.h"
#include "ut0bitset.h"
#include "ut0new.h"
#include "ut0vec.h"
#include "my_dbug.h"
#include "my_psi_config.h"
#include "mysql/plugin.h"
#include "mysql/psi/psi_thread.h"

Classes

class  Deadlock_notifier
 A static class for reporting notifications about deadlocks. More...
 
struct  locksys::Conflicting
 
struct  PrintNotStarted
 Functor to print not-started transaction from the mysql_trx_list. More...
 
class  TrxLockIterator
 Iterate over a transaction's locks. More...
 
class  TrxListIterator
 This iterates over RW trx_sys lists only. More...
 

Namespaces

namespace  locksys
 

Macros

#define LOCK_MODULE_IMPLEMENTATION
 
#define PRINT_NUM_OF_LOCK_STRUCTS
 

Typedefs

template<typename T >
using Locks = std::vector< T, mem_heap_allocator< T > >
 

Enumerations

enum class  locksys::Conflict { locksys::HAS_TO_WAIT , locksys::NO_CONFLICT , locksys::CAN_BYPASS }
 

Functions

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...
 
static void lock_rec_validate_page (const buf_block_t *block)
 Validates the record lock queues on a page. 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...
 
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_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...
 
void lock_sys_create (ulint n_cells)
 Creates the lock system at database start. More...
 
static uint64_t lock_rec_lock_hash_value (const lock_t *lock)
 Calculates the hash value of a lock: used in migrating the hash table. 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...
 
ulint lock_get_size (void)
 Gets the size of a lock struct. More...
 
bool lock_is_waiting (const lock_t &lock)
 Checks if the lock is waiting (as opposed to granted). More...
 
static void lock_set_lock_and_trx_wait (lock_t *lock)
 Sets the wait flag of a lock and the back pointer in trx to lock. More...
 
static ulint lock_rec_get_gap (const lock_t *lock)
 Gets the gap flag of a record lock. More...
 
static ulint lock_rec_get_rec_not_gap (const lock_t *lock)
 Gets the LOCK_REC_NOT_GAP flag of a record lock. More...
 
static ulint lock_rec_get_insert_intention (const lock_t *lock)
 Gets the waiting insert flag of a record lock. More...
 
static Conflict locksys::rec_lock_check_conflict (const trx_t *trx, ulint type_mode, const lock_t *lock2, bool lock_is_on_supremum, Trx_locks_cache &trx_locks_cache)
 Checks if a new request for a record lock has to wait for existing request. More...
 
static bool locksys::rec_lock_has_to_wait (const lock_t *lock1, const lock_t *lock2, Trx_locks_cache &lock1_cache)
 Checks if a record 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...
 
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...
 
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...
 
static byte lock_rec_reset_nth_bit (lock_t *lock, ulint i)
 Reset the nth bit of a record lock. More...
 
bool lock_rec_clear_request_no_wakeup (lock_t *lock, uint16_t heap_no)
 Reset the nth bit of a record lock. More...
 
static bool lock_rec_has_any (Locks_hashtable &hash, page_id_t page_id)
 
static bool lock_rec_has_any (Locks_hashtable &hash, page_id_t page_id, uint16_t heap_no)
 
bool lock_rec_expl_exist_on_page (const page_id_t &page_id)
 Determines if there are explicit record locks on a page. More...
 
static void lock_rec_bitmap_reset (lock_t *lock)
 Resets the record lock bitmap to zero. More...
 
static lock_tlock_rec_copy (const lock_t *lock, mem_heap_t *heap)
 Copies a record lock to heap. More...
 
static const lock_tlock_rec_has_expl (ulint precise_mode, const page_id_t page_id, uint32_t heap_no, const trx_t *trx)
 Checks if a transaction has a GRANTED explicit lock on rec stronger or equal to precise_mode. More...
 
static const lock_tlock_rec_has_expl (ulint precise_mode, const buf_block_t *block, ulint heap_no, const trx_t *trx)
 
static const lock_tlock_rec_other_has_expl_req (lock_mode mode, const buf_block_t *block, bool wait, ulint heap_no, const trx_t *trx)
 Checks if some other transaction has a lock request in the queue. More...
 
static locksys::Conflicting lock_rec_other_has_conflicting (ulint mode, const buf_block_t *block, ulint heap_no, const trx_t *trx)
 Checks if some other transaction has a conflicting explicit lock request in the queue, so that we have to wait. More...
 
static bool can_older_trx_be_still_active (trx_id_t max_old_active_id)
 Checks if the (-infinity,max_old_active_id] range contains an id of a currently active transaction which has modified a record. More...
 
static trx_tlock_sec_rec_some_has_impl (const rec_t *rec, dict_index_t *index, const ulint *offsets)
 Checks if some transaction has an implicit x-lock on a record in a secondary index. More...
 
static bool lock_rec_other_trx_holds_expl (ulint precise_mode, const trx_t *trx, const rec_t *rec, const buf_block_t *block)
 Checks if some transaction, other than given trx_id, has an explicit lock on the given rec, in the given precise_mode. 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...
 
static void lock_rec_insert_to_waiting (Locks_hashtable &lock_hash, lock_t *lock, const RecID &rec_id)
 Insert lock record to the tail of the queue where the WAITING locks reside. More...
 
static void lock_rec_insert_to_granted (Locks_hashtable &lock_hash, lock_t *lock, const RecID &rec_id)
 Insert lock record to the head of the queue where the GRANTED locks reside. More...
 
static void locksys::add_to_trx_locks (lock_t *lock)
 Adds the lock to the list of trx's locks. More...
 
static void locksys::remove_from_trx_locks (lock_t *lock)
 Removes the lock from the list of trx's locks. More...
 
static void lock_mark_trx_for_rollback (hit_list_t &hit_list, trx_id_t hp_trx_id, trx_t *trx)
 Collect the transactions that will need to be rolled back asynchronously. More...
 
static bool lock_edge_may_survive_prepare (const lock_t *waiting_lock, const lock_t *blocking_lock)
 Checks if the waits-for edge between waiting_lock and blocking_lock may survive PREPARE of the blocking_lock->trx. More...
 
static void lock_report_wait_for_edge_to_server (const lock_t *waiting_lock, const lock_t *blocking_lock)
 
static void lock_create_wait_for_edge (const lock_t *waiting_lock, const lock_t *blocking_lock)
 Creates a new edge in wait-for graph, from waiter to blocker. More...
 
static void lock_rec_move_granted_to_front (lock_t *lock, const RecID &rec_id)
 Moves a granted lock to the front of the queue for a given record by removing it adding it to the front. More...
 
static void lock_rec_add_to_queue (ulint type_mode, const buf_block_t *block, const ulint heap_no, dict_index_t *index, trx_t *trx, const bool we_own_trx_mutex=false)
 Adds a record lock request in the record queue. More...
 
static lock_rec_req_status lock_rec_lock_fast (bool impl, ulint mode, const buf_block_t *block, ulint heap_no, dict_index_t *index, que_thr_t *thr)
 This is a fast routine for locking a record in the most common cases: there are no explicit locks on the page, or there is just one lock, owned by this transaction, and of the right type_mode. More...
 
static void lock_reuse_for_next_key_lock (const lock_t *held_lock, ulint mode, const buf_block_t *block, ulint heap_no, dict_index_t *index, trx_t *trx)
 A helper function for lock_rec_lock_slow(), which grants a Next Key Lock (either LOCK_X or LOCK_S as specified by mode) on <block,heap_no> in the index to the trx, assuming that it already has a granted held_lock, which is at least as strong as mode|LOCK_REC_NOT_GAP. More...
 
static dberr_t lock_rec_lock_slow (bool impl, select_mode sel_mode, ulint mode, const buf_block_t *block, ulint heap_no, dict_index_t *index, que_thr_t *thr)
 This is the general, and slower, routine for locking a record. More...
 
static dberr_t lock_rec_lock (bool impl, select_mode sel_mode, ulint mode, const buf_block_t *block, ulint heap_no, dict_index_t *index, que_thr_t *thr)
 Tries to lock the specified record in the mode requested. More...
 
static const lock_tlock_rec_has_to_wait_in_queue (const lock_t *wait_lock, const trx_t *blocking_trx=nullptr)
 Checks if a waiting record lock request still has to wait in a queue. More...
 
static void lock_grant (lock_t *lock)
 Grants a lock to a waiting lock request and releases the waiting transaction. More...
 
void lock_make_trx_hit_list (trx_t *hp_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...
 
static void lock_rec_cancel (lock_t *lock)
 Cancels a waiting record lock request and releases the waiting transaction that requested it. More...
 
static void lock_update_wait_for_edge (const lock_t *waiting_lock, const lock_t *blocking_lock)
 Given a waiting_lock, and blocking_lock which is the reason it has to wait, makes sure that the (only) edge in the wait-for graph outgoing from the waiting_lock->trx points to blocking_lock->trx. More...
 
template<typename Container >
static const lock_tlock_rec_has_to_wait_for_granted (const typename Container::value_type &wait_lock, const Container &granted, const size_t new_granted_index)
 Checks if a waiting record lock request still has to wait for granted locks. More...
 
static void lock_rec_grant_by_heap_no (lock_t *in_lock, ulint heap_no)
 Grant a lock to waiting transactions. More...
 
static const lock_tlock_has_to_wait_in_queue (const lock_t *wait_lock, const trx_t *blocking_trx)
 Checks if a waiting lock request still has to wait in a queue. More...
 
static void lock_grant_or_update_wait_for_edge (lock_t *lock)
 Given a lock, which was found in waiting queue, checks if it still has to wait in queue, and either grants it, or makes sure that the reason it has to wait is reflected in the wait-for graph. More...
 
static void lock_grant_or_update_wait_for_edge_if_waiting (lock_t *lock, const trx_t *releasing_trx)
 Given a lock, and a transaction which is releasing another lock from the same queue, makes sure that if the lock was waiting for this transaction, then it will either be granted, or another reason for waiting is reflected in the wait-for graph. More...
 
static void lock_rec_grant (lock_t *in_lock)
 Grant lock to waiting requests that no longer conflicts. More...
 
static void lock_rec_dequeue_from_page (lock_t *in_lock)
 Removes a record lock request, waiting or granted, from the queue and grants locks to other transactions in the queue if they now are entitled to a lock. More...
 
void lock_rec_discard (lock_t *in_lock)
 Removes a record lock request, waiting or granted, from the queue. More...
 
static const lock_tlock_find_record_lock_by_guid (Locks_hashtable &lock_hash, page_id_t page_id, const lock_guid_t &guid)
 
const lock_tlock_find_record_lock_by_guid (page_id_t page_id, const lock_guid_t &guid)
 Inspect the lock queues associated with the given page_id in search for a lock which has guid equal to the given one. More...
 
static void lock_rec_free_all_from_discard_page_low (page_id_t page_id, Locks_hashtable &lock_hash)
 Removes record lock objects set on an index page which is discarded. 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...
 
static void lock_rec_reset_and_release_wait_low (Locks_hashtable &hash, const buf_block_t *block, ulint heap_no)
 Resets the lock bits for a single record. More...
 
static void lock_rec_reset_and_release_wait (const buf_block_t *block, ulint heap_no)
 Resets the lock bits for a single 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...
 
static void lock_protect_locks_till_statement_end (que_thr_t *thr)
 
static void lock_rec_inherit_to_gap (const buf_block_t *heir_block, const buf_block_t *block, ulint heir_heap_no, ulint heap_no)
 Makes a record to inherit the locks (except LOCK_INSERT_INTENTION type) of another record as gap type locks, but does not reset the lock bits of the other record. More...
 
static void lock_rec_inherit_to_gap_if_gap_lock (const buf_block_t *block, uint16_t heir_heap_no, uint16_t heap_no)
 Makes a record to inherit the gap locks (except LOCK_INSERT_INTENTION type) of another record as gap type locks, but does not reset the lock bits of the other record. More...
 
static void lock_rec_move (const buf_block_t *receiver, const buf_block_t *donator, ulint receiver_heap_no, ulint donator_heap_no)
 Moves the locks of a record to another record and resets the lock bits of the donating record. More...
 
static void lock_move_granted_locks_to_front (trx_lock_list_t &lock_list)
 Move all the granted locks to the front of the given lock list. 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_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_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...
 
static lock_tlock_table_create (dict_table_t *table, ulint type_mode, trx_t *trx)
 Creates a table lock object and adds it as the last in the lock queue of the table. More...
 
static void lock_table_pop_autoinc_locks (trx_t *trx)
 Pops autoinc lock requests from the transaction's autoinc_locks. More...
 
static void lock_table_remove_autoinc_lock (lock_t *lock, trx_t *trx)
 Removes an autoinc lock request from the transaction's autoinc_locks. More...
 
const lock_tlock_find_table_lock_by_guid (const dict_table_t *table, const lock_guid_t &guid)
 Inspect the lock queue associated with the given table in search for a lock which has guid equal to the given one. More...
 
static void lock_table_remove_low (lock_t *lock)
 Removes a table lock request from the queue and the trx list of locks; this is a low-level function which does NOT check if waiting requests can now be granted. More...
 
static dberr_t lock_table_enqueue_waiting (ulint mode, dict_table_t *table, que_thr_t *thr, const lock_t *blocking_lock)
 Enqueues a waiting request for a table lock which cannot be granted immediately. More...
 
static const lock_tlock_table_other_has_incompatible (const trx_t *trx, ulint wait, const dict_table_t *table, lock_mode mode)
 Checks if other transactions have an incompatible mode lock request in the lock queue. 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...
 
static const lock_tlock_table_has_to_wait_in_queue (const lock_t *wait_lock, const trx_t *blocking_trx=nullptr)
 Checks if a waiting table lock request still has to wait in a queue. More...
 
static void lock_table_dequeue (lock_t *in_lock)
 Removes a table lock request, waiting or granted, from the queue and grants locks to other transactions in the queue, if they now are entitled to a lock. 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...
 
static void lock_rec_release (lock_t *lock, ulint heap_no)
 Grant a lock to waiting transactions. 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...
 
static void lock_release_gap_lock (lock_t *lock)
 Unlock the GAP Lock part of a Next Key Lock and grant it to waiters (if any) More...
 
static bool lock_release_read_lock (lock_t *lock, bool only_gap)
 Used to release a lock during PREPARE. More...
 
template<typename F >
static bool locksys::try_relatch_trx_and_shard_and_do (const lock_t *lock, F &&f)
 A helper function which solves a chicken-and-egg problem occurring when one needs to iterate over trx's locks and perform some actions on them. More...
 
static bool locksys::try_release_read_locks_in_s_mode (trx_t *trx, bool only_gap)
 Tries to release read locks of a transaction without latching the whole lock sys. More...
 
static bool locksys::try_release_read_locks_in_x_mode (trx_t *trx, bool only_gap)
 Release read locks of a transaction latching the whole lock-sys in exclusive mode, which is a bit too expensive to do by default. More...
 
void lock_trx_release_read_locks (trx_t *trx, bool only_gap)
 Release read locks of a transaction. More...
 
static bool locksys::try_release_all_locks (trx_t *trx)
 Releases transaction locks, and releases possible other transactions waiting because of these locks. More...
 
static bool IS_LOCK_S_OR_X (lock_t *lock)
 
static void lock_remove_all_on_table_for_trx (dict_table_t *table, trx_t *trx, bool remove_also_table_sx_locks)
 Removes locks of a transaction on a table to be dropped. More...
 
static ulint lock_remove_recovered_trx_record_locks (dict_table_t *table)
 Remove any explicit record locks held by recovering transactions on the table. 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 void lock_table_print (FILE *file, const lock_t *lock)
 Prints info of a table lock. More...
 
static void lock_rec_print (FILE *file, const lock_t *lock)
 Prints info of a record lock. More...
 
static size_t lock_get_n_rec_locks (void)
 Calculates the number of record lock structs in the record lock hash table. 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...
 
static bool lock_rec_fetch_page (const lock_t *lock)
 Reads the page containing the record protected by the given lock. More...
 
static bool lock_trx_print_locks (FILE *file, const trx_t *trx, TrxLockIterator &iter, bool load_block)
 Prints info of locks for a transaction. More...
 
void lock_print_info_all_transactions (FILE *file)
 Prints info of locks for each transaction. More...
 
static bool lock_table_queue_validate (const dict_table_t *table)
 Validates the lock queue on a table. More...
 
static void locksys::rec_queue_validate_latched (const buf_block_t *block, const rec_t *rec, const dict_index_t *index, const ulint *offsets)
 Validates the lock queue on a single record. More...
 
static void locksys::rec_queue_latch_and_validate (const buf_block_t *block, const rec_t *rec, const dict_index_t *index, const ulint *offsets)
 Validates the lock queue on a single record. More...
 
static void locksys::rec_queue_latch_and_validate (const buf_block_t *block, const rec_t *rec, const dict_index_t *index)
 Validates the lock queue on a single record. More...
 
static void lock_validate_table_locks ()
 Validates the table locks. More...
 
static void lock_rec_block_validate (const page_id_t &page_id)
 Validate a record lock's block. More...
 
bool lock_validate ()
 Validates the lock system. 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...
 
static void lock_rec_convert_impl_to_expl_for_trx (const buf_block_t *block, const rec_t *rec, dict_index_t *index, const ulint *offsets, trx_t *trx, ulint heap_no)
 Creates an explicit record lock for a running transaction that currently only has an implicit lock on the record. 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...
 
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...
 
dberr_t lock_sec_rec_read_check_and_lock (const lock_duration_t duration, const buf_block_t *block, const rec_t *rec, dict_index_t *index, const ulint *offsets, const select_mode sel_mode, const lock_mode mode, const 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 (const lock_duration_t duration, const buf_block_t *block, const rec_t *rec, dict_index_t *index, const ulint *offsets, const select_mode sel_mode, const lock_mode mode, const 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...
 
static void lock_release_autoinc_last_lock (trx_t *trx)
 Release the last lock from the transaction's autoinc locks. More...
 
static bool lock_trx_holds_autoinc_locks (const trx_t *trx)
 Check if a transaction holds any autoinc locks. More...
 
static void lock_release_autoinc_locks (trx_t *trx)
 Release all the transaction's autoinc locks. 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...
 
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 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...
 
static dict_table_tlock_get_table (const lock_t *lock)
 Gets the table on which the lock is. 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...
 
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_unlock_table_autoinc (trx_t *trx)
 Unlocks AUTO_INC type locks that were possibly reserved by a trx. 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...
 
bool lock_cancel_if_waiting_and_release (const TrxVersion trx_version)
 Cancels the waiting lock request of the trx, if any. More...
 
static const lock_tlock_table_locks_lookup (const dict_table_t *table)
 Scans all locks of all transactions in the rw_trx_list searching for any lock (table or rec) against the table. 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_set_timeout_event ()
 Set the lock system timeout event. 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...
 
void lock_trx_alloc_locks (trx_t *trx)
 Allocate cached locks for the transaction. 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...
 

Variables

bool innobase_deadlock_detect = true
 
static const ulint REC_LOCK_CACHE = 8
 Total number of cached record locks. More...
 
static const ulint REC_LOCK_SIZE = sizeof(ib_lock_t) + 256
 Maximum record lock size in bytes. More...
 
static const ulint TABLE_LOCK_CACHE = 8
 Total number of cached table locks. More...
 
static const ulint TABLE_LOCK_SIZE = sizeof(ib_lock_t)
 Size in bytes, of the table lock instance. More...
 
static const std::map< uint, const char * > lock_constant_names
 Used by lock_get_mode_str to build a lock mode description. More...
 
static std::unordered_map< uint, const char * > lock_cached_lock_mode_names
 Used by lock_get_mode_str to cache results. More...
 
static std::mutex lock_cached_lock_mode_names_mutex
 Mutex protecting access to lock_cached_lock_mode_names. More...
 
lock_sys_tlock_sys = nullptr
 The lock system. More...
 
static bool lock_deadlock_found = false
 We store info on the latest deadlock error to this buffer. More...
 
static FILE * lock_latest_err_file
 Only created if !srv_read_only_mode. More...
 
constexpr auto locksys::MAX_CS_DURATION = std::chrono::seconds{1}
 We don't want to hold the Global latch for too long, even in S mode, not to starve threads waiting for X-latch on it such as lock_wait_timeout_thread(). More...
 

Detailed Description

The transaction lock system.

Created 5/7/1996 Heikki Tuuri

Macro Definition Documentation

◆ LOCK_MODULE_IMPLEMENTATION

#define LOCK_MODULE_IMPLEMENTATION

◆ PRINT_NUM_OF_LOCK_STRUCTS

#define PRINT_NUM_OF_LOCK_STRUCTS

Typedef Documentation

◆ Locks

template<typename T >
using Locks = std::vector<T, mem_heap_allocator<T> >

Function Documentation

◆ can_older_trx_be_still_active()

static bool can_older_trx_be_still_active ( trx_id_t  max_old_active_id)
static

Checks if the (-infinity,max_old_active_id] range contains an id of a currently active transaction which has modified a record.

The premise is that the caller has seen a record modified by a trx with trx->id <= max_old_active_id, and wants to know if it might be still active. It may err on the safe side.

Remarks
The difficulties to keep in mind here:
  • the caller doesn't hold trx_sys mutex, nor can prevent any transaction from committing or starting before the start and after the end of execution of this function. Thus the result of this function has to be interpreted as if it could have a "one sided error", even if the return value is exact during the execution
  • the transactions are assigned ids from increasing sequence, but they are added to various structures like lists and shards out of order. This means that the answer this function gives only makes sense in the context that the caller already saw an effect of the trx modifying some row, which means it had to be already added to these structures. In other words, calling this function twice for the same number can give false then true. Still the false from the first call is "correct" for the purpose of the caller (as it must mean that the trx which modified the record had to be removed from the structures already, hence is not active anymore). Also the true from the second call is "correct" in that indeed some smaller transaction id had to be added to the structures meanwhile, even if it's not the one which modified the record in question - error on the safe side.
Parameters
[in]max_old_active_idThe end of the range inclusive. For example found in the PAGE_MAX_TRX_ID field of a header of a secondary index page.
Return values
falsethe caller may assume that if before the call it saw a record modified by trx_id, and trx_id < max_old_active_id, then it is no longer active
truethe caller should double check in a synchronized way if the seen trx_id is still active or not

◆ IS_LOCK_S_OR_X()

static bool IS_LOCK_S_OR_X ( lock_t lock)
inlinestatic

◆ 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_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_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
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
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
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_create_wait_for_edge()

static void lock_create_wait_for_edge ( const lock_t waiting_lock,
const lock_t blocking_lock 
)
static

Creates a new edge in wait-for graph, from waiter to blocker.

Parameters
[in]waiting_lockA lock waiting in queue, blocked by blocking_lock
[in]blocking_lockA lock which is a reason the waiting_lock has to wait

◆ lock_edge_may_survive_prepare()

static bool lock_edge_may_survive_prepare ( const lock_t waiting_lock,
const lock_t blocking_lock 
)
static

Checks if the waits-for edge between waiting_lock and blocking_lock may survive PREPARE of the blocking_lock->trx.

For transactions in low isolation levels we release some of the locks during PREPARE.

Parameters
[in]waiting_lockA lock waiting in queue, blocked by blocking_lock
[in]blocking_lockA lock which is a reason the waiting_lock has to wait
Returns
if the waiting_lock->trx MAY have to wait for blocking_lock->trx even if blocking_lock->trx PREPAREs. The nondeterminism comes from situations like when X lock conflicts with S lock on a delete-marked record - purgining it might convert both to non-conflicitng gap locks
Return values
truethe waiting_lock->trx MAY have to wait for blocking_lock->trx even if blocking_lock->trx PREPAREs.
falsethe waiting_lock->trx CERTAINLY will not have to wait for blocking_lock->trx for this particular reason.

◆ lock_find_record_lock_by_guid() [1/2]

static const lock_t * lock_find_record_lock_by_guid ( Locks_hashtable lock_hash,
page_id_t  page_id,
const lock_guid_t guid 
)
static

◆ lock_find_record_lock_by_guid() [2/2]

const lock_t * lock_find_record_lock_by_guid ( page_id_t  page_id,
const lock_guid_t guid 
)

Inspect the lock queues associated with the given page_id in search for a lock which has guid equal to the given one.

Caller should hold a latch on shard containing locks for this page.

Parameters
[in]page_idthe id of the page, for which we expect the lock
[in]guidthe guid of the lock we seek for
Returns
the lock with a given guid or nullptr if no such lock

◆ lock_find_table_lock_by_guid()

const lock_t * lock_find_table_lock_by_guid ( const dict_table_t table,
const lock_guid_t guid 
)

Inspect the lock queue associated with the given table in search for a lock which has guid equal to the given one.

Caller should hold a latch on the shard containing this table's locks.

Parameters
[in]tablethe table, for which we expect the lock
[in]guidthe guid of the lock we seek for
Returns
the lock with a given guid or nullptr if no such lock

◆ 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. 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_n_rec_locks()

static size_t lock_get_n_rec_locks ( void  )
static

Calculates the number of record lock structs in the record lock hash table.

Returns
number of record locks

◆ 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()

static dict_table_t * lock_get_table ( const lock_t lock)
inlinestatic

Gets the table on which the lock is.

Returns
table
Parameters
lockin: lock

◆ 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
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_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
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
Parameters
lockin: lock

◆ lock_grant()

static void lock_grant ( lock_t lock)
static

Grants a lock to a waiting lock request and releases the waiting transaction.

The caller must hold lock_sys latch for the shard containing the lock, but not the lock->trx->mutex.

Parameters
[in,out]lockwaiting lock request

◆ lock_grant_or_update_wait_for_edge()

static void lock_grant_or_update_wait_for_edge ( lock_t lock)
static

Given a lock, which was found in waiting queue, checks if it still has to wait in queue, and either grants it, or makes sure that the reason it has to wait is reflected in the wait-for graph.

Parameters
[in]lockA lock in WAITING state, which perhaps can be granted now

◆ lock_grant_or_update_wait_for_edge_if_waiting()

static void lock_grant_or_update_wait_for_edge_if_waiting ( lock_t lock,
const trx_t releasing_trx 
)
static

Given a lock, and a transaction which is releasing another lock from the same queue, makes sure that if the lock was waiting for this transaction, then it will either be granted, or another reason for waiting is reflected in the wait-for graph.

◆ 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_has_to_wait_in_queue()

static const lock_t * lock_has_to_wait_in_queue ( const lock_t wait_lock,
const trx_t blocking_trx 
)
static

Checks if a waiting lock request still has to wait in a queue.

Parameters
[in]wait_lockWaiting lock
[in]blocking_trxIf not nullptr, it restricts the search to only the locks held by the blocking_trx, which is useful in case when there might be multiple reasons for waiting in queue, but we need to report the specific one. Useful when reporting a deadlock cycle.
Returns
The conflicting lock which is the reason wait_lock has to wait or nullptr if it can be granted now

◆ lock_is_waiting()

bool lock_is_waiting ( const lock_t lock)

Checks if the lock is waiting (as opposed to granted).

Caller should hold a latch on shard containging the lock in order for this check to be meaningful.

Parameters
[in]lockthe lock to inspect
Returns
true iff the lock is waiting

◆ 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_mark_trx_for_rollback()

static void lock_mark_trx_for_rollback ( hit_list_t hit_list,
trx_id_t  hp_trx_id,
trx_t trx 
)
static

Collect the transactions that will need to be rolled back asynchronously.

Parameters
[in,out]hit_listThe list of transactions to be rolled back, to which the trx should be appended.
[in]hp_trx_idThe id of the blocked High Priority Transaction
[in,out]trxThe blocking transaction to be rolled back

◆ lock_move_granted_locks_to_front()

static void lock_move_granted_locks_to_front ( trx_lock_list_t &  lock_list)
static

Move all the granted locks to the front of the given lock list.

All the waiting locks will be at the end of the list.

Parameters
[in,out]lock_listthe given lock list.

◆ 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.

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

◆ 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_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_protect_locks_till_statement_end()

static void lock_protect_locks_till_statement_end ( que_thr_t thr)
inlinestatic

◆ lock_rec_add_to_queue()

static void lock_rec_add_to_queue ( ulint  type_mode,
const buf_block_t block,
const ulint  heap_no,
dict_index_t index,
trx_t trx,
const bool  we_own_trx_mutex = false 
)
static

Adds a record lock request in the record queue.

The request is normally added as the last in the queue, but if the request to be added is not a waiting request, we can reuse a suitable record lock object already existing on the same page, just setting the appropriate bit in its bitmap. This is a low-level function which does NOT check for deadlocks or lock compatibility!

Parameters
[in]type_modelock mode, wait, gap etc. flags; type is ignored and replaced by LOCK_REC
[in]blockbuffer block containing the record
[in]heap_noheap number of the record
[in]indexindex of record
[in,out]trxtransaction
[in]we_own_trx_mutextrue iff the caller own trx->mutex (optional). Defaults to false.

◆ lock_rec_bitmap_reset()

static void lock_rec_bitmap_reset ( lock_t lock)
static

Resets the record lock bitmap to zero.

NOTE: does not touch the wait_lock pointer in the transaction! This function is used in lock object creation and resetting.

Parameters
lockin: record lock

◆ lock_rec_block_validate()

static void lock_rec_block_validate ( const page_id_t page_id)
static

Validate a record lock's block.

◆ lock_rec_cancel()

static void lock_rec_cancel ( lock_t lock)
static

Cancels a waiting record lock request and releases the waiting transaction that requested it.

NOTE: does NOT check if waiting lock requests behind this one can now be granted!

Parameters
lockin: waiting record lock request

◆ lock_rec_clear_request_no_wakeup()

bool lock_rec_clear_request_no_wakeup ( lock_t lock,
uint16_t  heap_no 
)

Reset the nth bit of a record lock.

If this was a wait lock clears the wait flag on it, and marks that the trx no longer waits on it, but doesn't wake up the transaction. This function is meant to be used when lock requests are moved from one place to another, and thus a new (equivalent) lock request will be soon created for the transaction, so there's no point in waking it up.

Parameters
[in,out]lockrecord lock
[in]heap_noindex of the bit that will be reset
Returns
false iff the bit was already cleared before the call

◆ 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_convert_impl_to_expl_for_trx()

static void lock_rec_convert_impl_to_expl_for_trx ( const buf_block_t block,
const rec_t rec,
dict_index_t index,
const ulint offsets,
trx_t trx,
ulint  heap_no 
)
static

Creates an explicit record lock for a running transaction that currently only has an implicit lock on the record.

The transaction instance must have a reference count > 0 so that it can't be committed and freed before this function has completed.

Parameters
blockin: buffer block of rec
recin: user record on page
indexin: index of record
offsetsin: rec_get_offsets(rec, index)
trxin/out: active transaction
heap_noin: rec heap number to lock

◆ lock_rec_copy()

static lock_t * lock_rec_copy ( const lock_t lock,
mem_heap_t heap 
)
static

Copies a record lock to heap.

Returns
copy of lock
Parameters
lockin: record lock
heapin: memory heap

◆ lock_rec_dequeue_from_page()

static void lock_rec_dequeue_from_page ( lock_t in_lock)
static

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

NOTE: all record locks contained in in_lock are removed.

Parameters
[in,out]in_lockrecord lock object: all record locks which are contained in this lock object are removed; transactions waiting behind will get their lock requests granted, if they are now qualified to it

◆ lock_rec_discard()

void lock_rec_discard ( lock_t in_lock)

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

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_fetch_page()

static bool lock_rec_fetch_page ( const lock_t lock)
static

Reads the page containing the record protected by the given lock.

This function will temporarily release the exclusive global latch and the trx_sys_t::mutex if the page was read from disk.

Parameters
[in]lockthe record lock
Returns
true if a page was successfully read from the tablespace

◆ 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.

Parameters
blockin: page to be discarded

◆ lock_rec_free_all_from_discard_page_low()

static void lock_rec_free_all_from_discard_page_low ( page_id_t  page_id,
Locks_hashtable lock_hash 
)
static

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.

◆ lock_rec_get_gap()

static ulint lock_rec_get_gap ( const lock_t lock)
inlinestatic

Gets the gap flag of a record lock.

Returns
LOCK_GAP or 0
Parameters
lockin: record lock

◆ 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
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
Parameters
lockin: lock

◆ lock_rec_get_insert_intention()

static ulint lock_rec_get_insert_intention ( const lock_t lock)
inlinestatic

Gets the waiting insert flag of a record lock.

Returns
LOCK_INSERT_INTENTION or 0
Parameters
lockin: record 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_get_rec_not_gap()

static ulint lock_rec_get_rec_not_gap ( const lock_t lock)
inlinestatic

Gets the LOCK_REC_NOT_GAP flag of a record lock.

Returns
LOCK_REC_NOT_GAP or 0
Parameters
lockin: record lock

◆ lock_rec_grant()

static void lock_rec_grant ( lock_t in_lock)
static

Grant lock to waiting requests that no longer conflicts.

The in_lock might be modified before call to this function by clearing some flag (see for example lock_trx_release_read_locks). It also might already be removed from the hash cell (a.k.a. waiting queue) or still reside in it. However the content of bitmap should not be changed prior to calling this function, as the bitmap will be inspected to see which heap_no at all were blocked by this in_lock, and only locks waiting for those heap_no's will be checked.

Parameters
[in,out]in_lockrecord lock object: grant all non-conflicting locks waiting behind this lock object

◆ lock_rec_grant_by_heap_no()

static void lock_rec_grant_by_heap_no ( lock_t in_lock,
ulint  heap_no 
)
static

Grant a lock to waiting transactions.

This function scans the queue of locks in which in_lock resides (or resided) paying attention only to locks on heap_no-th bit. For each waiting lock which was blocked by in_lock->trx it checks if it can be granted now. It iterates on waiting locks in order favoring high-priority transactions and then transactions of high trx->lock.schedule_weight.

Parameters
[in]in_lockLock which was released, or partially released by modifying its type/mode (see lock_trx_release_read_locks) or resetting heap_no-th bit in the bitmap (see lock_rec_release)
[in]heap_noHeap number within the page on which the lock was (or still is) held

◆ lock_rec_has_any() [1/2]

static bool lock_rec_has_any ( Locks_hashtable hash,
page_id_t  page_id 
)
static

◆ lock_rec_has_any() [2/2]

static bool lock_rec_has_any ( Locks_hashtable hash,
page_id_t  page_id,
uint16_t  heap_no 
)
static

◆ lock_rec_has_expl() [1/2]

static const lock_t * lock_rec_has_expl ( ulint  precise_mode,
const buf_block_t block,
ulint  heap_no,
const trx_t trx 
)
inlinestatic

◆ lock_rec_has_expl() [2/2]

static const lock_t * lock_rec_has_expl ( ulint  precise_mode,
const page_id_t  page_id,
uint32_t  heap_no,
const trx_t trx 
)
inlinestatic

Checks if a transaction has a GRANTED explicit lock on rec stronger or equal to precise_mode.

Parameters
[in]precise_modeLOCK_S or LOCK_X possibly ORed to LOCK_GAP or LOCK_REC_NOT_GAP, for a supremum record we regard this always a gap type request
[in]page_idid of the page containing the record
[in]heap_noheap number of the record
[in]trxtransaction
Returns
lock or NULL

◆ lock_rec_has_to_wait_for_granted()

template<typename Container >
static const lock_t * lock_rec_has_to_wait_for_granted ( const typename Container::value_type &  wait_lock,
const Container &  granted,
const size_t  new_granted_index 
)
static

Checks if a waiting record lock request still has to wait for granted locks.

Parameters
[in]wait_lockWaiting record lock
[in]grantedGranted record locks
[in]new_granted_indexStart of new granted locks
Returns
The conflicting lock which is the reason wait_lock has to wait or nullptr if it can be granted now

◆ lock_rec_has_to_wait_in_queue()

static const lock_t * lock_rec_has_to_wait_in_queue ( const lock_t wait_lock,
const trx_t blocking_trx = nullptr 
)
static

Checks if a waiting record lock request still has to wait in a queue.

Parameters
[in]wait_lockWaiting record lock
[in]blocking_trxIf not nullptr, it restricts the search to only the locks held by the blocking_trx, which is useful in case when there might be multiple reasons for waiting in queue, but we need to report the specific one. Useful when reporting a deadlock cycle. (optional)
Returns
The conflicting lock which is the reason wait_lock has to wait or nullptr if it can be granted now

◆ lock_rec_inherit_to_gap()

static void lock_rec_inherit_to_gap ( const buf_block_t heir_block,
const buf_block_t block,
ulint  heir_heap_no,
ulint  heap_no 
)
static

Makes a record to inherit the locks (except LOCK_INSERT_INTENTION type) of another record as gap type locks, but does not reset the lock bits of the other record.

Also waiting lock requests on rec are inherited as GRANTED gap locks.

Parameters
heir_blockin: block containing the record which inherits
blockin: block containing the record from which inherited; does NOT reset the locks on this record
heir_heap_noin: heap_no of the inheriting record
heap_noin: heap_no of the donating record

◆ lock_rec_inherit_to_gap_if_gap_lock()

static void lock_rec_inherit_to_gap_if_gap_lock ( const buf_block_t block,
uint16_t  heir_heap_no,
uint16_t  heap_no 
)
static

Makes a record to inherit the gap locks (except LOCK_INSERT_INTENTION type) of another record as gap type locks, but does not reset the lock bits of the other record.

Also waiting lock requests are inherited as GRANTED gap locks.

Parameters
blockin: buffer block
heir_heap_noin: heap_no of record which inherits
heap_noin: heap_no of record from which inherited; does NOT reset the locks on this record

◆ 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
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_insert_to_granted()

static void lock_rec_insert_to_granted ( Locks_hashtable lock_hash,
lock_t lock,
const RecID rec_id 
)
static

Insert lock record to the head of the queue where the GRANTED locks reside.

Parameters
[in,out]lock_hashHash table containing the locks
[in,out]lockRecord lock instance to insert
[in]rec_idRecord being locked

◆ lock_rec_insert_to_waiting()

static void lock_rec_insert_to_waiting ( Locks_hashtable lock_hash,
lock_t lock,
const RecID rec_id 
)
static

Insert lock record to the tail of the queue where the WAITING locks reside.

Parameters
[in,out]lock_hashHash table containing the locks
[in,out]lockRecord lock instance to insert
[in]rec_idRecord being locked

◆ lock_rec_lock()

static dberr_t lock_rec_lock ( bool  impl,
select_mode  sel_mode,
ulint  mode,
const buf_block_t block,
ulint  heap_no,
dict_index_t index,
que_thr_t thr 
)
static

Tries to lock the specified record in the mode requested.

If not immediately possible, enqueues a waiting lock request. This is a low-level function which does NOT look at implicit locks! Checks lock compatibility within explicit locks. This function sets a normal next-key lock, or in the case of a page supremum record, a gap type lock.

Parameters
[in]implif true, no lock is set if no wait is necessary: we assume that the caller will set an implicit lock
[in]sel_modeselect mode: SELECT_ORDINARY, SELECT_SKIP_LOCKED, or SELECT_NO_WAIT
[in]modelock mode: LOCK_X or LOCK_S possibly ORed to either LOCK_GAP or LOCK_REC_NOT_GAP
[in]blockbuffer block containing the record
[in]heap_noheap number of record
[in]indexindex of record
[in,out]thrquery thread
Returns
DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK, DB_SKIP_LOCKED, or DB_LOCK_NOWAIT

◆ lock_rec_lock_fast()

static lock_rec_req_status lock_rec_lock_fast ( bool  impl,
ulint  mode,
const buf_block_t block,
ulint  heap_no,
dict_index_t index,
que_thr_t thr 
)
inlinestatic

This is a fast routine for locking a record in the most common cases: there are no explicit locks on the page, or there is just one lock, owned by this transaction, and of the right type_mode.

This is a low-level function which does NOT look at implicit locks! Checks lock compatibility within explicit locks. This function sets a normal next-key lock, or in the case of a page supremum record, a gap type lock.

Returns
whether the locking succeeded LOCK_REC_SUCCESS, LOCK_REC_SUCCESS_CREATED, LOCK_REC_FAIL
Parameters
implin: if true, no lock is set if no wait is necessary: we assume that the caller will set an implicit lock
modein: lock mode: LOCK_X or LOCK_S possibly ORed to either LOCK_GAP or LOCK_REC_NOT_GAP
blockin: buffer block containing the record
heap_noin: heap number of record
indexin: index of record
thrin: query thread

◆ lock_rec_lock_hash_value()

static uint64_t lock_rec_lock_hash_value ( const lock_t lock)
static

Calculates the hash value of a lock: used in migrating the hash table.

Parameters
[in]lockrecord lock object
Returns
hashed value

◆ lock_rec_lock_slow()

static dberr_t lock_rec_lock_slow ( bool  impl,
select_mode  sel_mode,
ulint  mode,
const buf_block_t block,
ulint  heap_no,
dict_index_t index,
que_thr_t thr 
)
static

This is the general, and slower, routine for locking a record.

This is a low-level function which does NOT look at implicit locks! Checks lock compatibility within explicit locks. This function sets a normal next-key lock, or in the case of a page supremum record, a gap type lock.

Parameters
[in]implif true, no lock might be set if no wait is necessary: we assume that the caller will set an implicit lock
[in]sel_modeselect mode: SELECT_ORDINARY, SELECT_SKIP_LOCKED, or SELECT_NO_WAIT
[in]modelock mode: LOCK_X or LOCK_S possibly ORed to either LOCK_GAP or LOCK_REC_NOT_GAP
[in]blockbuffer block containing the record
[in]heap_noheap number of record
[in]indexindex of record
[in,out]thrquery thread
Returns
DB_SUCCESS, DB_SUCCESS_LOCKED_REC, DB_LOCK_WAIT, DB_DEADLOCK, DB_SKIP_LOCKED, or DB_LOCK_NOWAIT

◆ lock_rec_move()

static void lock_rec_move ( const buf_block_t receiver,
const buf_block_t donator,
ulint  receiver_heap_no,
ulint  donator_heap_no 
)
static

Moves the locks of a record to another record and resets the lock bits of the donating record.

Parameters
receiverin: buffer block containing the receiving record
donatorin: buffer block containing the donating record
receiver_heap_noin: heap_no of the record which gets the locks; there must be no lock requests on it!
donator_heap_noin: heap_no of the record which gives the locks

◆ lock_rec_move_granted_to_front()

static void lock_rec_move_granted_to_front ( lock_t lock,
const RecID rec_id 
)
static

Moves a granted lock to the front of the queue for a given record by removing it adding it to the front.

As a single lock can correspond to multiple rows (and thus: queues) this function moves it to the front of whole hash cell.

Parameters
[in]locka granted lock to be moved
[in]rec_idrecord id which specifies particular queue and hash cell

◆ lock_rec_other_has_conflicting()

static locksys::Conflicting lock_rec_other_has_conflicting ( ulint  mode,
const buf_block_t block,
ulint  heap_no,
const trx_t trx 
)
static

Checks if some other transaction has a conflicting explicit lock request in the queue, so that we have to wait.

Parameters
[in]modeLOCK_S or LOCK_X, possibly ORed to LOCK_GAP or LOC_REC_NOT_GAP, LOCK_INSERT_INTENTION
[in]blockbuffer block containing the record
[in]heap_noheap number of the record
[in]trxour transaction
Returns
a pair, where: the first element is a conflicting lock or null if no conflicting lock found, the second element indicates if the trx has bypassed one of waiting locks.

◆ lock_rec_other_has_expl_req()

static const lock_t * lock_rec_other_has_expl_req ( lock_mode  mode,
const buf_block_t block,
bool  wait,
ulint  heap_no,
const trx_t trx 
)
static

Checks if some other transaction has a lock request in the queue.

Returns
lock or NULL
Parameters
modein: LOCK_S or LOCK_X
blockin: buffer block containing the record
waitin: whether also waiting locks are taken into account
heap_noin: heap number of the record
trxin: transaction, or NULL if requests by all transactions are taken into account

◆ lock_rec_other_trx_holds_expl()

static bool lock_rec_other_trx_holds_expl ( ulint  precise_mode,
const trx_t trx,
const rec_t rec,
const buf_block_t block 
)
static

Checks if some transaction, other than given trx_id, has an explicit lock on the given rec, in the given precise_mode.

Parameters
[in]precise_modeLOCK_S or LOCK_X possibly ORed to LOCK_GAP or LOCK_REC_NOT_GAP.
[in]trxthe trx holding implicit lock on rec
[in]recuser record
[in]blockbuffer block containing the record
Returns
true iff there's a transaction, whose id is not equal to trx_id, that has an explicit lock on the given rec, in the given precise_mode.

◆ lock_rec_print()

static void lock_rec_print ( FILE *  file,
const lock_t lock 
)
static

Prints info of a record lock.

Parameters
filein: file where to print
lockin: record type lock

◆ lock_rec_release()

static void lock_rec_release ( lock_t lock,
ulint  heap_no 
)
static

Grant a lock to waiting transactions.

Parameters
[in]lockLock that was unlocked
[in]heap_noHeap no within the page for the lock.

◆ 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_reset_and_release_wait()

static void lock_rec_reset_and_release_wait ( const buf_block_t block,
ulint  heap_no 
)
static

Resets the lock bits for a single record.

Releases transactions waiting for lock requests here.

Parameters
blockin: buffer block containing the record
heap_noin: heap number of record

◆ lock_rec_reset_and_release_wait_low()

static void lock_rec_reset_and_release_wait_low ( Locks_hashtable hash,
const buf_block_t block,
ulint  heap_no 
)
static

Resets the lock bits for a single record.

Releases transactions waiting for lock requests here.

Parameters
hashin: hash table
blockin: buffer block containing the record
heap_noin: heap number of record

◆ lock_rec_reset_nth_bit()

static byte lock_rec_reset_nth_bit ( lock_t lock,
ulint  i 
)
inlinestatic

Reset the nth bit of a record lock.

Parameters
[in,out]lockrecord lock
[in]iindex of the bit that will be reset
Returns
previous value of the bit

◆ 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 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_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.

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_rec_validate_page()

static void lock_rec_validate_page ( const buf_block_t block)
static

Validates the record lock queues on a page.

Parameters
[in]blockA (possibly freed) block for which we want to validate all lock queues. If any of the queues is non-empty we additionally assert that the block was not freed.
Parameters
blockin: buffer block

◆ lock_release_autoinc_last_lock()

static void lock_release_autoinc_last_lock ( trx_t trx)
inlinestatic

Release the last lock from the transaction's autoinc locks.

Parameters
[in]trxtrx which vector of AUTOINC locks to modify

◆ lock_release_autoinc_locks()

static void lock_release_autoinc_locks ( trx_t trx)
static

Release all the transaction's autoinc locks.

Parameters
trxin/out: transaction

◆ lock_release_gap_lock()

static void lock_release_gap_lock ( lock_t lock)
static

Unlock the GAP Lock part of a Next Key Lock and grant it to waiters (if any)

Parameters
[in,out]locklock object

◆ lock_release_read_lock()

static bool lock_release_read_lock ( lock_t lock,
bool  only_gap 
)
static

Used to release a lock during PREPARE.

The lock is only released if rules permit it.

Parameters
[in]lockthe lock that we consider releasing
[in]only_gaptrue if we don't want to release records, just the gaps between them
Returns
true iff the function did release (maybe a part of) a lock

◆ 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.

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

◆ lock_remove_all_on_table_for_trx()

static void lock_remove_all_on_table_for_trx ( dict_table_t table,
trx_t trx,
bool  remove_also_table_sx_locks 
)
static

Removes locks of a transaction 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.

Parameters
tablein: table to be dropped
trxin: a transaction
remove_also_table_sx_locksin: also removes table S and X locks

◆ lock_remove_recovered_trx_record_locks()

static ulint lock_remove_recovered_trx_record_locks ( dict_table_t table)
static

Remove any explicit record locks held by recovering transactions on the table.

Returns
number of recovered transactions examined
Parameters
tablein: check if there are any locks held on records in this table or on the table itself

◆ 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_report_wait_for_edge_to_server()

static void lock_report_wait_for_edge_to_server ( const lock_t waiting_lock,
const lock_t blocking_lock 
)
static

◆ lock_reuse_for_next_key_lock()

static void lock_reuse_for_next_key_lock ( const lock_t held_lock,
ulint  mode,
const buf_block_t block,
ulint  heap_no,
dict_index_t index,
trx_t trx 
)
static

A helper function for lock_rec_lock_slow(), which grants a Next Key Lock (either LOCK_X or LOCK_S as specified by mode) on <block,heap_no> in the index to the trx, assuming that it already has a granted held_lock, which is at least as strong as mode|LOCK_REC_NOT_GAP.

It does so by either reusing the lock if it already covers the gap, or by ensuring a separate GAP Lock, which in combination with Record Lock satisfies the request.

Parameters
[in]held_locka lock granted to trx which is at least as strong as mode|LOCK_REC_NOT_GAP
[in]moderequested lock mode: LOCK_X or LOCK_S
[in]blockbuffer block containing the record to be locked
[in]heap_noheap number of the record to be locked
[in]indexindex of record to be locked
[in]trxthe transaction requesting the Next Key Lock

◆ 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
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
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_sec_rec_some_has_impl()

static trx_t * lock_sec_rec_some_has_impl ( const rec_t rec,
dict_index_t index,
const ulint offsets 
)
static

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

Parameters
[in]recuser record
[in]indexsecondary index
[in]offsetsrec_get_offsets(rec, index)
Returns
transaction id of the transaction which has the x-lock, or 0; NOTE that this function can return false positives but never false negatives. The caller must confirm all positive results by checking if the trx is still active.

◆ lock_set_lock_and_trx_wait()

static void lock_set_lock_and_trx_wait ( lock_t lock)
inlinestatic

Sets the wait flag of a lock and the back pointer in trx to lock.

Parameters
[in]lockThe lock on which a transaction is waiting

◆ 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
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_create()

static lock_t * lock_table_create ( dict_table_t table,
ulint  type_mode,
trx_t trx 
)
inlinestatic

Creates a table lock object and adds it as the last in the lock queue of the table.

Does NOT check for deadlocks or lock compatibility.

Returns
own: new lock object
Parameters
tablein/out: database table in dictionary cache
type_modein: lock mode possibly ORed with LOCK_WAIT
trxin: trx

◆ lock_table_dequeue()

static void lock_table_dequeue ( lock_t in_lock)
static

Removes a table lock request, waiting or granted, from the queue and grants locks to other transactions in the queue, if they now are entitled to a lock.

Parameters
in_lockin/out: table lock object; transactions waiting behind will get their lock requests granted, if they are now qualified to it

◆ lock_table_enqueue_waiting()

static dberr_t lock_table_enqueue_waiting ( ulint  mode,
dict_table_t table,
que_thr_t thr,
const lock_t blocking_lock 
)
static

Enqueues a waiting request for a table lock which cannot be granted immediately.

Checks for deadlocks.

Parameters
[in]modelock mode this transaction is requesting
[in]tablethe table to be locked
[in]thrthe query thread requesting the lock
[in]blocking_lockthe lock which is the reason this request has to wait
Returns
DB_LOCK_WAIT or DB_DEADLOCK

◆ 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_has_to_wait_in_queue()

static const lock_t * lock_table_has_to_wait_in_queue ( const lock_t wait_lock,
const trx_t blocking_trx = nullptr 
)
static

Checks if a waiting table lock request still has to wait in a queue.

Parameters
[in]wait_lockWaiting table lock
[in]blocking_trxIf not nullptr, it restricts the search to only the locks held by the blocking_trx, which is useful in case when there might be multiple reasons for waiting in queue, but we need to report the specific one. Useful when reporting a deadlock cycle. (optional)
Returns
The conflicting lock which is the reason wait_lock has to wait or nullptr if it can be granted now

◆ 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_table_locks_lookup()

static const lock_t * lock_table_locks_lookup ( const dict_table_t table)
static

Scans all locks of all transactions in the rw_trx_list searching for any lock (table or rec) against the table.

Parameters
[in]tablethe table for which we perform the search
Returns
lock if found

◆ lock_table_other_has_incompatible()

static const lock_t * lock_table_other_has_incompatible ( const trx_t trx,
ulint  wait,
const dict_table_t table,
lock_mode  mode 
)
inlinestatic

Checks if other transactions have an incompatible mode lock request in the lock queue.

Returns
lock or NULL
Parameters
trxin: transaction, or NULL if all transactions should be included
waitin: LOCK_WAIT if also waiting locks are taken into account, or 0 if not
tablein: table
modein: lock mode

◆ lock_table_pop_autoinc_locks()

static void lock_table_pop_autoinc_locks ( trx_t trx)
inlinestatic

Pops autoinc lock requests from the transaction's autoinc_locks.

We handle the case where there are gaps in the array and they need to be popped off the stack.

Parameters
trxin/out: transaction that owns the AUTOINC locks

◆ lock_table_print()

static void lock_table_print ( FILE *  file,
const lock_t lock 
)
static

Prints info of a table lock.

Parameters
filein: file where to print
lockin: table type lock

◆ lock_table_queue_validate()

static bool lock_table_queue_validate ( const dict_table_t table)
static

Validates the lock queue on a table.

Returns
true if ok
Parameters
tablein: table

◆ lock_table_remove_autoinc_lock()

static void lock_table_remove_autoinc_lock ( lock_t lock,
trx_t trx 
)
inlinestatic

Removes an autoinc lock request from the transaction's autoinc_locks.

Parameters
lockin: table lock
trxin/out: transaction that owns the lock

◆ lock_table_remove_low()

static void lock_table_remove_low ( lock_t lock)
inlinestatic

Removes a table lock request from the queue and the trx list of locks; this is a low-level function which does NOT check if waiting requests can now be granted.

Parameters
lockin/out: table lock

◆ 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_holds_autoinc_locks()

static bool lock_trx_holds_autoinc_locks ( const trx_t trx)
static

Check if a transaction holds any autoinc locks.

Returns
true if the transaction holds any AUTOINC locks.
Parameters
trxin: transaction

◆ lock_trx_print_locks()

static bool lock_trx_print_locks ( FILE *  file,
const trx_t trx,
TrxLockIterator iter,
bool  load_block 
)
static

Prints info of locks for a transaction.

Returns
true if all printed, false if latches were released.
Parameters
filein/out: File to write
trxin: current transaction
iterin: transaction lock iterator
load_blockin: if true then read block from disk

◆ 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.

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).

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.

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_update_wait_for_edge()

static void lock_update_wait_for_edge ( const lock_t waiting_lock,
const lock_t blocking_lock 
)
static

Given a waiting_lock, and blocking_lock which is the reason it has to wait, makes sure that the (only) edge in the wait-for graph outgoing from the waiting_lock->trx points to blocking_lock->trx.

Parameters
[in]waiting_lockA lock waiting in queue, blocked by blocking_lock
[in]blocking_lockA lock which is a reason the waiting_lock has to wait

◆ lock_validate()

bool lock_validate ( )

Validates the lock system.

Returns
true if ok

◆ lock_validate_table_locks()

static void lock_validate_table_locks ( )
static

Validates the table locks.

Variable Documentation

◆ innobase_deadlock_detect

bool innobase_deadlock_detect = true

◆ lock_cached_lock_mode_names

std::unordered_map<uint, const char *> lock_cached_lock_mode_names
static

Used by lock_get_mode_str to cache results.

Strings pointed by these pointers might be in use by performance schema and thus can not be freed until the very end. Protected by exclusive global lock_cached_lock_mode_names_mutex.

◆ lock_cached_lock_mode_names_mutex

std::mutex lock_cached_lock_mode_names_mutex
static

Mutex protecting access to lock_cached_lock_mode_names.

◆ lock_constant_names

const std::map<uint, const char *> lock_constant_names
static
Initial value:
{
{LOCK_GAP, "GAP"},
{LOCK_REC_NOT_GAP, "REC_NOT_GAP"},
{LOCK_INSERT_INTENTION, "INSERT_INTENTION"},
{LOCK_PREDICATE, "PREDICATE"},
{LOCK_PRDT_PAGE, "PRDT_PAGE"},
}
constexpr uint32_t LOCK_PRDT_PAGE
Page lock.
Definition: lock0lock.h:977
constexpr uint32_t LOCK_PREDICATE
Predicate lock.
Definition: lock0lock.h:975
constexpr uint32_t LOCK_INSERT_INTENTION
this bit is set when we place a waiting gap type record lock request in order to let an insert of an ...
Definition: lock0lock.h:973
constexpr uint32_t LOCK_GAP
when this bit is set, it means that the lock holds only on the gap before the record; for instance,...
Definition: lock0lock.h:961
constexpr uint32_t LOCK_REC_NOT_GAP
this bit means that the lock is only on the index record and does NOT block inserts to the gap before...
Definition: lock0lock.h:967

Used by lock_get_mode_str to build a lock mode description.

◆ lock_deadlock_found

bool lock_deadlock_found = false
static

We store info on the latest deadlock error to this buffer.

InnoDB Monitor will then fetch it and print

◆ lock_latest_err_file

FILE* lock_latest_err_file
static

Only created if !srv_read_only_mode.

I/O operations on this file require exclusive lock_sys latch

◆ lock_sys

lock_sys_t* lock_sys = nullptr

The lock system.

◆ REC_LOCK_CACHE

const ulint REC_LOCK_CACHE = 8
static

Total number of cached record locks.

◆ REC_LOCK_SIZE

const ulint REC_LOCK_SIZE = sizeof(ib_lock_t) + 256
static

Maximum record lock size in bytes.

◆ TABLE_LOCK_CACHE

const ulint TABLE_LOCK_CACHE = 8
static

Total number of cached table locks.

◆ TABLE_LOCK_SIZE

const ulint TABLE_LOCK_SIZE = sizeof(ib_lock_t)
static

Size in bytes, of the table lock instance.