Initialization at server boot up time (i.e., srv_start())
ulint n_cells) /*!< in: number of slots in lock hash table */
{
mutex_create(LATCH_ID_LOCK_SYS, &lock_sys->mutex);
lock_sys->rec_hash = hash_create(n_cells);
lock_sys->prdt_hash = hash_create(n_cells);
lock_sys->prdt_page_hash = hash_create(n_cells);
}
lock_sys_create(srv_lock_table_size);
/* normalize lock_sys */
srv_lock_table_size = 5 * (srv_buf_pool_size / UNIV_PAGE_SIZE);
static void row_ins_foreign_trx_print(trx_t *trx) /*!< in: transaction */
{
n_rec_locks = lock_number_of_rows_locked(&trx->lock);
n_trx_locks = UT_LIST_GET_LEN(trx->lock.trx_locks);
heap_size = mem_heap_get_size(trx->lock.lock_heap);
lock_mutex_exit();
}
//Create a row lock
lock_t *RecLock::create(trx_t *trx, bool add_to_hash, const lock_prdt_t *prdt) {
lock_t *lock = lock_alloc(trx, m_index, m_mode, m_rec_id, m_size);
//hookup to the lock hash table
lock_add(lock, add_to_hash);
}
/**
Record lock ID */
struct RecID {
/**
Tablespace ID */
space_id_t m_space_id;
/**
Page number within the space ID */
page_no_t m_page_no;
/**
Heap number within the page */?????
uint32_t m_heap_no;
Hashed key value */
ulint m_fold;
};
DeadLock Detection
Not all operations will trigger the deadlock detection. It will only be triggered by If we cannot get the required lock immediately. For example:
Basic idea:
Basic data structure:
@param trx the start transaction (start node)
@param wait_lock lock that a transaction wants
@param mark_start visited node counter */
DeadlockChecker(const trx_t *trx, const lock_t *wait_lock,
uint64_t mark_start)
}
Basic DFS search structure:
Basic Entry Point
/** Check and resolve any deadlocks
@param[in, out] lock The lock being acquired
@return DB_LOCK_WAIT, DB_DEADLOCK, or
DB_SUCCESS_LOCKED_REC; DB_SUCCESS_LOCKED_REC means that
there was a deadlock, but another transaction was chosen
as a victim, and we got the lock immediately: no need to
wait then */
dberr_t RecLock::deadlock_check(lock_t *lock) {
const trx_t *victim_trx = DeadlockChecker::check_and_resolve(lock, m_trx);
{
/* Try and resolve as many deadlocks as possible. */
do {
DeadlockChecker checker(trx, lock, s_lock_mark_counter);
victim_trx = checker.search();
}
https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html