函数fsp_fill_free_list

时间:2024-01-07 19:08:32
/**********************************************************************//**
Puts new extents to the free list if there are free extents above the free
limit. If an extent happens to contain an extent descriptor page, the extent
is put to the FSP_FREE_FRAG list with the page marked as used. */
static
void
fsp_fill_free_list(
/*===============*/
    ibool        init_space,    /*!< in: TRUE if this is a single-table
                    tablespace and we are only initing
                    the tablespace's first extent
                    descriptor page and ibuf bitmap page;
                    then we do not allocate more extents */
    ulint        space,        /*!< in: space */
    fsp_header_t*    header,        /*!< in/out: space header */
    mtr_t*        mtr)        /*!< in/out: mini-transaction */
{
    ulint    limit;
    ulint    size;
    ulint    zip_size;
    xdes_t*    descr;
    ulint    count        = ;
    ulint    frag_n_used;
    ulint    actual_increase;
    ulint    i;
    mtr_t    ibuf_mtr;

    ut_ad(header && mtr);
    ut_ad(page_offset(header) == FSP_HEADER_OFFSET);

    /* Check if we can fill free list from above the free list limit */
    size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
    limit = mtr_read_ulint(header + FSP_FREE_LIMIT, MLOG_4BYTES, mtr);

    zip_size = dict_table_flags_to_zip_size(
        mach_read_from_4(FSP_SPACE_FLAGS + header));
    ut_a(ut_is_2pow(zip_size));
    ut_a(zip_size <= UNIV_PAGE_SIZE);
    ut_a(!zip_size || zip_size >= PAGE_ZIP_MIN_SIZE);

     && srv_auto_extend_last_data_file
        && size < limit + FSP_EXTENT_SIZE * FSP_FREE_ADD) {

        /* Try to increase the last data file size */
        fsp_try_extend_data_file(&actual_increase, space, header, mtr);
        size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
    }

     && !init_space
        && size < limit + FSP_EXTENT_SIZE * FSP_FREE_ADD) {

        /* Try to increase the .ibd file size */
        fsp_try_extend_data_file(&actual_increase, space, header, mtr);
        size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr);
    }

    i = limit;

    /**     *还是先暂时分配4个page     *     *#define    FSP_FREE_ADD        4     *#define FSP_EXTENT_SIZE 64     *init_space 为false,所以第一个条件不执行     *fsp_init_file_page初始化后,limit为0     *while( (0+64 < size)&& 0<4){     init_xdes = (0%16328)=0         count=1     }     while( (16328<size) &&1<4 ){     init_xdes=16328%16328=0         count=2          }     ..     while(65312<size && 3<4)       init_xdex=65312%16328=0    count=4     }     结束while循环

     最终header + FSP_FREE_LIMIT 为 65312+64

*/
    ) || ((i + FSP_EXTENT_SIZE <= size) && (count < FSP_FREE_ADD))) {

        ibool    init_xdes;
        if (zip_size) {
            init_xdes = ut_2pow_remainder(i, zip_size) == ;
        } else {
            init_xdes = ut_2pow_remainder(i, UNIV_PAGE_SIZE) == ;
        }

        mlog_write_ulint(header + FSP_FREE_LIMIT, i + FSP_EXTENT_SIZE,MLOG_4BYTES, mtr);

        /* Update the free limit info in the log system and make
        a checkpoint */
        ) {
            ut_a(!zip_size);
            log_fsp_current_free_limit_set_and_checkpoint(
                (i + FSP_EXTENT_SIZE)
                / (( * ) / UNIV_PAGE_SIZE));
        }

        if (UNIV_UNLIKELY(init_xdes)) {

            buf_block_t*    block;

            /* We are going to initialize a new descriptor page
            and a new ibuf bitmap page: the prior contents of the
            pages should be ignored. */

            ) {                /**                 *从free-list,unzip-lru,common-lru取出block                 *初始化block                 */
                block = buf_page_create(space, i, zip_size, mtr);//详见
                buf_page_get(space, zip_size, i,RW_X_LATCH, mtr);
                buf_block_dbg_add_level(block,SYNC_FSP_PAGE);
                                //初始化blck一些属性
                fsp_init_file_page(block, mtr);

                
                mlog_write_ulint(buf_block_get_frame(block)+ FIL_PAGE_TYPE,FIL_PAGE_TYPE_XDES,MLOG_2BYTES, mtr);
            }

            /* Initialize the ibuf bitmap page in a separate
            mini-transaction because it is low in the latching
            order, and we must be able to release its latch
            before returning from the fsp routine */

            mtr_start(&ibuf_mtr);

            block = buf_page_create(space,
                            i + FSP_IBUF_BITMAP_OFFSET,
                            zip_size, &ibuf_mtr);
            buf_page_get(space, zip_size,
                     i + FSP_IBUF_BITMAP_OFFSET,
                     RW_X_LATCH, &ibuf_mtr);
            buf_block_dbg_add_level(block, SYNC_FSP_PAGE);

            fsp_init_file_page(block, &ibuf_mtr);

            ibuf_bitmap_page_init(block, &ibuf_mtr);

            mtr_commit(&ibuf_mtr);
        }
                /**         *1)根据偏移量i,计算出des page的page_no         *  1.1)如果page_no非0,则要根据offset在buf_pool->page_hash找到一个block,条件为page->offset == i         *  1.2)如果page_no为0,继续         *2)在xdes page中定位哪xdes entry的起始地址         */
        descr = xdes_get_descriptor_with_space_hdr(header, space, i,mtr);//详见
        xdes_init(descr, mtr);

        if (UNIV_UNLIKELY(init_xdes)) {

            /* The first page in the extent is a descriptor page
            and the second is an ibuf bitmap page: mark them
            used */

            xdes_set_bit(descr, XDES_FREE_BIT, , FALSE, mtr);
            xdes_set_bit(descr, XDES_FREE_BIT, FSP_IBUF_BITMAP_OFFSET, FALSE, mtr);
            xdes_set_state(descr, XDES_FREE_FRAG, mtr);

            flst_add_last(header + FSP_FREE_FRAG,descr + XDES_FLST_NODE, mtr);
            frag_n_used = mtr_read_ulint(header + FSP_FRAG_N_USED,MLOG_4BYTES, mtr);
            mlog_write_ulint(header + FSP_FRAG_N_USED,frag_n_used + , MLOG_4BYTES, mtr);
        } else {
            flst_add_last(header + FSP_FREE,descr + XDES_FLST_NODE, mtr);
            count++;
        }

        i += FSP_EXTENT_SIZE;
    }
}