函数buf_page_create

/********************************************************************//**
Initializes a page to the buffer buf_pool. The page is usually not read
from a file even if it cannot be found in the buffer buf_pool. This is one
of the functions which perform to a block a state transition NOT_USED =>
FILE_PAGE (the other is buf_page_get_gen).
@return    pointer to the block, page bufferfixed */
UNIV_INTERN
buf_block_t*
buf_page_create(
/*============*/
    ulint    space,    /*!< in: space id */
    ulint    offset,    /*!< in: offset of the page within space in units of
            a page */
    ulint    zip_size,/*!< in: compressed page size, or 0 */
    mtr_t*    mtr)    /*!< in: mini-transaction handle */
{
    buf_frame_t*    frame;
    buf_block_t*    block;
    ulint        fold;
    buf_block_t*    free_block    = NULL;
    buf_pool_t*    buf_pool     = buf_pool_get(space, offset);//获取具体buff pool实例 详见

    ut_ad(mtr);
    ut_ad(mtr->state == MTR_ACTIVE);
    ut_ad(space || !zip_size);

    free_block = buf_LRU_get_free_block(buf_pool); //取得一块空闲block 这里

    fold = buf_page_address_fold(space, offset); //计算hash值 详见

    buf_pool_mutex_enter(buf_pool);
    //可忽略这个
    block = (buf_block_t*) buf_page_hash_get_low(buf_pool, space, offset, fold);

    if (block
        && buf_page_in_file(&block->page)
        && !buf_pool_watch_is_sentinel(buf_pool, &block->page)) {

        /* Page can be found in buf_pool */
        buf_pool_mutex_exit(buf_pool);

        buf_block_free(free_block);

        return(buf_page_get_with_no_latch(space, zip_size,offset, mtr));
    }

    /* If we get here, the page was not in buf_pool: init it there */    block = free_block;

    mutex_enter(&block->mutex);
        /**     *初始化block,详见     *计算block中的lock_hash_val     *将block->page放入buf_pool->page_hash中     */
    buf_page_init(buf_pool, space, offset, fold, zip_size, block);/* The block must be put to the LRU list */
    buf_LRU_add_block(&block->page, FALSE); //放入lru中,且status为old 详见

    buf_block_buf_fix_inc(block, __FILE__, __LINE__);
    buf_pool->stat.n_pages_created++;

    if (zip_size) {
        void*    data;
        ibool    lru;

        /* Prevent race conditions during buf_buddy_alloc(),
        which may release and reacquire buf_pool->mutex,
        by IO-fixing and X-latching the block. */

        buf_page_set_io_fix(&block->page, BUF_IO_READ);
        rw_lock_x_lock(&block->lock);
        mutex_exit(&block->mutex);
        /* buf_pool->mutex may be released and reacquired by
        buf_buddy_alloc().  Thus, we must release block->mutex
        in order not to break the latching order in
        the reacquisition of buf_pool->mutex.  We also must
        defer this operation until after the block descriptor
        has been added to buf_pool->LRU and buf_pool->page_hash. */
        data = buf_buddy_alloc(buf_pool, zip_size, &lru);
        mutex_enter(&block->mutex);
        block->page.zip.data = data;

        /* To maintain the invariant
        block->in_unzip_LRU_list
        == buf_page_belongs_to_unzip_LRU(&block->page)
        we have to add this block to unzip_LRU after
        block->page.zip.data is set. */
        ut_ad(buf_page_belongs_to_unzip_LRU(&block->page));
        buf_unzip_LRU_add_block(block, FALSE);

        buf_page_set_io_fix(&block->page, BUF_IO_NONE);
        rw_lock_x_unlock(&block->lock);
    }

    buf_pool_mutex_exit(buf_pool);

    mtr_memo_push(mtr, block, MTR_MEMO_BUF_FIX);

    buf_page_set_accessed(&block->page);

    mutex_exit(&block->mutex);

    /* Delete possible entries for the page from the insert buffer:
    such can exist if the page belonged to an index which was dropped */

    ibuf_merge_or_delete_for_page(NULL, space, offset, zip_size, TRUE);

    /* Flush pages from the end of the LRU list if necessary */
    buf_flush_free_margin(buf_pool);
        /**     *取出block中的frame     *block结构体 详见     */
    frame = block->frame;
            */
    memset(frame + FIL_PAGE_PREV, );
    memset(frame + FIL_PAGE_NEXT, );
    mach_write_to_2(frame + FIL_PAGE_TYPE, FIL_PAGE_TYPE_ALLOCATED);

    /* Reset to zero the file flush lsn field in the page; if the first
    page of an ibdata file is 'created' in this function into the buffer
    pool then we lose the original contents of the file flush lsn stamp.
    Then InnoDB could in a crash recovery print a big, false, corruption
    warning if the stamp contains an lsn bigger than the ib_logfile lsn. */

    memset(frame + FIL_PAGE_FILE_FLUSH_LSN, , );

    return(block);
}
上一篇:前端开发之Chrome插件


下一篇:欢迎来到2021年的Qt Champions