/*********************************************************************//**
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);
}