/*********************************************************************//** Creates a new record lock and inserts it to the lock queue. Does NOT check for deadlocks or lock compatibility! @return created lock */ static lock_t* lock_rec_create( /*============*/ ulint type_mode,/*!< in: lock mode and wait flag, type is ignored and replaced by LOCK_REC */ const buf_block_t* block, /*!< in: buffer block containing the record */ ulint heap_no, /*!< in: heap number of the record */ dict_index_t* index, /*!< in: index of record */ trx_t* trx) /*!< in: transaction */ { lock_t* lock; ulint page_no; ulint space; ulint n_bits; ulint n_bytes; const page_t* page; ut_ad(mutex_own(&kernel_mutex)); space = buf_block_get_space(block); page_no = buf_block_get_page_no(block); page = block->frame; /* If rec is the supremum record, then we reset the gap and LOCK_REC_NOT_GAP bits, as all locks on the supremum are automatically of the gap type */ if (UNIV_UNLIKELY(heap_no == PAGE_HEAP_NO_SUPREMUM)) { ut_ad(!(type_mode & LOCK_REC_NOT_GAP)); type_mode = type_mode & ~(LOCK_GAP | LOCK_REC_NOT_GAP); } /* Make lock bitmap bigger by a safety margin */ n_bits = page_dir_get_n_heap(page) + LOCK_PAGE_BITMAP_MARGIN; //函数详见 即page页中包含记录个数+64 n_bytes = 1 + n_bits / 8; //转化为所需的字节,注意这里要加1,例如 5bits 进行运算后,要分配一个字节 lock = mem_heap_alloc(trx->lock_heap, sizeof(lock_t) + n_bytes); //为锁分配内存 UT_LIST_ADD_LAST(trx_locks, trx->trx_locks, lock); lock->trx = trx; lock->type_mode = (type_mode & ~LOCK_TYPE_MASK) | LOCK_REC; lock->index = index; lock->un_member.rec_lock.space = space; lock->un_member.rec_lock.page_no = page_no; lock->un_member.rec_lock.n_bits = n_bytes * 8; //bitmap的容量 /* Reset to zero the bitmap which resides immediately after the lock struct */ lock_rec_bitmap_reset(lock); //清0,详见 /* Set the bit corresponding to rec */ lock_rec_set_nth_bit(lock, heap_no); //详见 HASH_INSERT(lock_t, hash, lock_sys->rec_hash, lock_rec_fold(space, page_no), lock); if (lock_is_wait_not_by_other(type_mode)) { lock_set_lock_and_trx_wait(lock, trx); } return(lock); }