函数lock_rec_add_to_queue

时间:2022-04-29 17:25:06

在原来的type_mode基础上,加上LOCK_REC

/*********************************************************************//**
Adds a record lock request in the record queue. The request is normally
added as the last in the queue, but if there are no waiting lock requests
on the record, and 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!
@return    lock where the bit was set */
static
lock_t*
lock_rec_add_to_queue(
/*==================*/
    ulint            type_mode,/*!< in: lock mode, wait, gap
                    etc. flags; 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;

    ut_ad(mutex_own(&kernel_mutex));
#ifdef UNIV_DEBUG
    switch (type_mode & LOCK_MODE_MASK) {
    case LOCK_X:
    case LOCK_S:
        break;
    default:
        ut_error;
    }

    if (!(type_mode & (LOCK_WAIT | LOCK_GAP))) {
        enum lock_mode    mode = (type_mode & LOCK_MODE_MASK) == LOCK_S
            ? LOCK_X
            : LOCK_S;
        lock_t*        other_lock
            = lock_rec_other_has_expl_req(mode, , LOCK_WAIT,
                              block, heap_no, trx);
        ut_a(!other_lock);
    }
#endif /* UNIV_DEBUG */
     
    type_mode |= LOCK_REC; //模式基础上 加上 LOCK_REC

    /* If rec is the supremum record, then we can reset the gap bit, as
    all locks on the supremum are automatically of the gap type, and we
    try to avoid unnecessary memory consumption of a new record lock
    struct for a gap type lock */

    if (UNIV_UNLIKELY(heap_no == PAGE_HEAP_NO_SUPREMUM)) {
/* There should never be LOCK_REC_NOT_GAP on a supremum
        record, but let us play safe */

        type_mode = type_mode & ~(LOCK_GAP | LOCK_REC_NOT_GAP);
    }

    /* Look for a waiting lock request on the same record or on a gap */

    lock = lock_rec_get_first_on_page(block);

    while (lock != NULL) {
        if (lock_get_wait(lock)
            && (lock_rec_get_nth_bit(lock, heap_no))) {

            goto somebody_waits;
        }

        lock = lock_rec_get_next_on_page(lock);
    }
        //以后再分析,貌似是为了节省空间
    if (UNIV_LIKELY(!(type_mode & LOCK_WAIT))) {

        /* Look for a similar record lock on the same page:
        if one is found and there are no waiting lock requests,
        we can just set the bit */

        lock = lock_rec_find_similar_on_page(
            type_mode, heap_no,
            lock_rec_get_first_on_page(block), trx);

        if (lock) {

            lock_rec_set_nth_bit(lock, heap_no);

            return(lock);
        }
    }

somebody_waits:
    return(lock_rec_create(type_mode, block, heap_no, index, trx));
}