Initialization at server boot up time (i.e., srv_start())

  1. ulint n_cells) /*!< in: number of slots in lock hash table */
  2. {
  3. mutex_create(LATCH_ID_LOCK_SYS, &lock_sys->mutex);
  4. lock_sys->rec_hash = hash_create(n_cells);
  5. lock_sys->prdt_hash = hash_create(n_cells);
  6. lock_sys->prdt_page_hash = hash_create(n_cells);
  7. }
  8. lock_sys_create(srv_lock_table_size);
  9. /* normalize lock_sys */
  10. srv_lock_table_size = 5 * (srv_buf_pool_size / UNIV_PAGE_SIZE);
  1. static void row_ins_foreign_trx_print(trx_t *trx) /*!< in: transaction */
  2. {
  3. n_rec_locks = lock_number_of_rows_locked(&trx->lock);
  4. n_trx_locks = UT_LIST_GET_LEN(trx->lock.trx_locks);
  5. heap_size = mem_heap_get_size(trx->lock.lock_heap);
  6. lock_mutex_exit();
  7. }
  8. //Create a row lock
  9. lock_t *RecLock::create(trx_t *trx, bool add_to_hash, const lock_prdt_t *prdt) {
  10. lock_t *lock = lock_alloc(trx, m_index, m_mode, m_rec_id, m_size);
  11. //hookup to the lock hash table
  12. lock_add(lock, add_to_hash);
  13. }
  14. /**
  15. Record lock ID */
  16. struct RecID {
  17. /**
  18. Tablespace ID */
  19. space_id_t m_space_id;
  20. /**
  21. Page number within the space ID */
  22. page_no_t m_page_no;
  23. /**
  24. Heap number within the page */?????
  25. uint32_t m_heap_no;
  26. Hashed key value */
  27. ulint m_fold;
  28. };

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:

  1. @param trx the start transaction (start node)
  2. @param wait_lock lock that a transaction wants
  3. @param mark_start visited node counter */
  4. DeadlockChecker(const trx_t *trx, const lock_t *wait_lock,
  5. uint64_t mark_start)
  6. }

Basic DFS search structure:

Basic Entry Point

  1. /** Check and resolve any deadlocks
  2. @param[in, out] lock The lock being acquired
  3. @return DB_LOCK_WAIT, DB_DEADLOCK, or
  4. DB_SUCCESS_LOCKED_REC; DB_SUCCESS_LOCKED_REC means that
  5. there was a deadlock, but another transaction was chosen
  6. as a victim, and we got the lock immediately: no need to
  7. wait then */
  8. dberr_t RecLock::deadlock_check(lock_t *lock) {
  9. const trx_t *victim_trx = DeadlockChecker::check_and_resolve(lock, m_trx);
  10. {
  11. /* Try and resolve as many deadlocks as possible. */
  12. do {
  13. DeadlockChecker checker(trx, lock, s_lock_mark_counter);
  14. victim_trx = checker.search();
  15. }

https://dev.mysql.com/doc/refman/8.0/en/innodb-locking.html

How to create a deadlock

https://www.youtube.com/watch?v=joqmqvHC_Bo