📄 fsp0fsp.c
字号:
for (i = hint + 1; i > 0; i--) { if (val == xdes_get_bit(descr, bit, i - 1, mtr)) { return(i - 1); } } for (i = FSP_EXTENT_SIZE - 1; i > hint; i--) { if (val == xdes_get_bit(descr, bit, i, mtr)) { return(i); } } return(ULINT_UNDEFINED); } /**************************************************************************Returns the number of used pages in a descriptor. */UNIV_INLINEulintxdes_get_n_used(/*============*/ /* out: number of pages used */ xdes_t* descr, /* in: descriptor */ mtr_t* mtr) /* in: mtr */{ ulint i; ulint count = 0; ut_ad(descr && mtr); ut_ad(mtr_memo_contains(mtr, buf_block_align(descr), MTR_MEMO_PAGE_X_FIX)); for (i = 0; i < FSP_EXTENT_SIZE; i++) { if (FALSE == xdes_get_bit(descr, XDES_FREE_BIT, i, mtr)) { count++; } } return(count); } /**************************************************************************Returns true if extent contains no used pages. */UNIV_INLINEiboolxdes_is_free(/*=========*/ /* out: TRUE if totally free */ xdes_t* descr, /* in: descriptor */ mtr_t* mtr) /* in: mtr */{ if (0 == xdes_get_n_used(descr, mtr)) { return(TRUE); } return(FALSE);}/**************************************************************************Returns true if extent contains no free pages. */UNIV_INLINEiboolxdes_is_full(/*=========*/ /* out: TRUE if full */ xdes_t* descr, /* in: descriptor */ mtr_t* mtr) /* in: mtr */{ if (FSP_EXTENT_SIZE == xdes_get_n_used(descr, mtr)) { return(TRUE); } return(FALSE);}/**************************************************************************Sets the state of an xdes. */UNIV_INLINEvoidxdes_set_state(/*===========*/ xdes_t* descr, /* in: descriptor */ ulint state, /* in: state to set */ mtr_t* mtr) /* in: mtr handle */{ ut_ad(descr && mtr); ut_ad(state >= XDES_FREE); ut_ad(state <= XDES_FSEG); ut_ad(mtr_memo_contains(mtr, buf_block_align(descr), MTR_MEMO_PAGE_X_FIX)); mlog_write_ulint(descr + XDES_STATE, state, MLOG_4BYTES, mtr); }/**************************************************************************Gets the state of an xdes. */UNIV_INLINEulintxdes_get_state(/*===========*/ /* out: state */ xdes_t* descr, /* in: descriptor */ mtr_t* mtr) /* in: mtr handle */{ ut_ad(descr && mtr); ut_ad(mtr_memo_contains(mtr, buf_block_align(descr), MTR_MEMO_PAGE_X_FIX)); return(mtr_read_ulint(descr + XDES_STATE, MLOG_4BYTES, mtr)); }/**************************************************************************Inits an extent descriptor to the free and clean state. */UNIV_INLINEvoidxdes_init(/*======*/ xdes_t* descr, /* in: descriptor */ mtr_t* mtr) /* in: mtr */{ ulint i; ut_ad(descr && mtr); ut_ad(mtr_memo_contains(mtr, buf_block_align(descr), MTR_MEMO_PAGE_X_FIX)); ut_ad((XDES_SIZE - XDES_BITMAP) % 4 == 0); for (i = XDES_BITMAP; i < XDES_SIZE; i += 4) { mlog_write_ulint(descr + i, 0xFFFFFFFFUL, MLOG_4BYTES, mtr); } xdes_set_state(descr, XDES_FREE, mtr);} /************************************************************************Calculates the page where the descriptor of a page resides. */UNIV_INLINEulintxdes_calc_descriptor_page(/*======================*/ /* out: descriptor page offset */ ulint offset) /* in: page offset */{ ut_ad(UNIV_PAGE_SIZE > XDES_ARR_OFFSET + (XDES_DESCRIBED_PER_PAGE / FSP_EXTENT_SIZE) * XDES_SIZE); return(ut_2pow_round(offset, XDES_DESCRIBED_PER_PAGE));}/************************************************************************Calculates the descriptor index within a descriptor page. */UNIV_INLINEulintxdes_calc_descriptor_index(/*=======================*/ /* out: descriptor index */ ulint offset) /* in: page offset */{ return(ut_2pow_remainder(offset, XDES_DESCRIBED_PER_PAGE) / FSP_EXTENT_SIZE);}/************************************************************************Gets pointer to a the extent descriptor of a page. The page where the extentdescriptor resides is x-locked. If the page offset is equal to the free limitof the space, adds new extents from above the free limit to the space freelist, if not free limit == space size. This adding is necessary to make thedescriptor defined, as they are uninitialized above the free limit. */UNIV_INLINExdes_t*xdes_get_descriptor_with_space_hdr(/*===============================*/ /* out: pointer to the extent descriptor, NULL if the page does not exist in the space or if offset > free limit */ fsp_header_t* sp_header,/* in: space header, x-latched */ ulint space, /* in: space id */ ulint offset, /* in: page offset; if equal to the free limit, we try to add new extents to the space free list */ mtr_t* mtr) /* in: mtr handle */{ ulint limit; ulint size; ulint descr_page_no; page_t* descr_page; ut_ad(mtr); ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space), MTR_MEMO_X_LOCK)); /* Read free limit and space size */ limit = mtr_read_ulint(sp_header + FSP_FREE_LIMIT, MLOG_4BYTES, mtr); size = mtr_read_ulint(sp_header + FSP_SIZE, MLOG_4BYTES, mtr); /* If offset is >= size or > limit, return NULL */ if ((offset >= size) || (offset > limit)) { return(NULL); } /* If offset is == limit, fill free list of the space. */ if (offset == limit) { fsp_fill_free_list(FALSE, space, sp_header, mtr); } descr_page_no = xdes_calc_descriptor_page(offset); if (descr_page_no == 0) { /* It is on the space header page */ descr_page = buf_frame_align(sp_header); } else { descr_page = buf_page_get(space, descr_page_no, RW_X_LATCH, mtr);#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(descr_page, SYNC_FSP_PAGE);#endif /* UNIV_SYNC_DEBUG */ } return(descr_page + XDES_ARR_OFFSET + XDES_SIZE * xdes_calc_descriptor_index(offset));}/************************************************************************Gets pointer to a the extent descriptor of a page. The page where theextent descriptor resides is x-locked. If the page offset is equal tothe free limit of the space, adds new extents from above the free limitto the space free list, if not free limit == space size. This addingis necessary to make the descriptor defined, as they are uninitializedabove the free limit. */staticxdes_t*xdes_get_descriptor(/*================*/ /* out: pointer to the extent descriptor, NULL if the page does not exist in the space or if offset > free limit */ ulint space, /* in: space id */ ulint offset, /* in: page offset; if equal to the free limit, we try to add new extents to the space free list */ mtr_t* mtr) /* in: mtr handle */{ fsp_header_t* sp_header; sp_header = FSP_HEADER_OFFSET + buf_page_get(space, 0, RW_X_LATCH, mtr);#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(sp_header, SYNC_FSP_PAGE);#endif /* UNIV_SYNC_DEBUG */ return(xdes_get_descriptor_with_space_hdr(sp_header, space, offset, mtr));}/************************************************************************Gets pointer to a the extent descriptor if the file addressof the descriptor list node is known. The page where theextent descriptor resides is x-locked. */UNIV_INLINExdes_t*xdes_lst_get_descriptor(/*====================*/ /* out: pointer to the extent descriptor */ ulint space, /* in: space id */ fil_addr_t lst_node,/* in: file address of the list node contained in the descriptor */ mtr_t* mtr) /* in: mtr handle */{ xdes_t* descr; ut_ad(mtr); ut_ad(mtr_memo_contains(mtr, fil_space_get_latch(space), MTR_MEMO_X_LOCK)); descr = fut_get_ptr(space, lst_node, RW_X_LATCH, mtr) - XDES_FLST_NODE; return(descr);}/************************************************************************Gets pointer to the next descriptor in a descriptor list and x-locks itspage. */UNIV_INLINExdes_t*xdes_lst_get_next(/*==============*/ xdes_t* descr, /* in: pointer to a descriptor */ mtr_t* mtr) /* in: mtr handle */{ ulint space; ut_ad(mtr && descr); space = buf_frame_get_space_id(descr); return(xdes_lst_get_descriptor(space, flst_get_next_addr(descr + XDES_FLST_NODE, mtr), mtr));}/************************************************************************Returns page offset of the first page in extent described by a descriptor. */UNIV_INLINEulintxdes_get_offset(/*============*/ /* out: offset of the first page in extent */ xdes_t* descr) /* in: extent descriptor */{ ut_ad(descr); return(buf_frame_get_page_no(descr) + ((descr - buf_frame_align(descr) - XDES_ARR_OFFSET) / XDES_SIZE) * FSP_EXTENT_SIZE);}/***************************************************************Inits a file page whose prior contents should be ignored. */staticvoidfsp_init_file_page_low(/*=====================*/ byte* ptr) /* in: pointer to a page */{ page_t* page; page = buf_frame_align(ptr); buf_block_align(page)->check_index_page_at_flush = FALSE; #ifdef UNIV_BASIC_LOG_DEBUG memset(page, 0xff, UNIV_PAGE_SIZE);#endif mach_write_to_8(page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM, ut_dulint_zero); mach_write_to_8(page + FIL_PAGE_LSN, ut_dulint_zero);}/***************************************************************Inits a file page whose prior contents should be ignored. */staticvoidfsp_init_file_page(/*===============*/ page_t* page, /* in: page */ mtr_t* mtr) /* in: mtr */{ fsp_init_file_page_low(page); mlog_write_initial_log_record(page, MLOG_INIT_FILE_PAGE, mtr);} /***************************************************************Parses a redo log record of a file page init. */byte*fsp_parse_init_file_page(/*=====================*/ /* out: end of log record or NULL */ byte* ptr, /* in: buffer */ byte* end_ptr __attribute__((unused)), /* in: buffer end */ page_t* page) /* in: page or NULL */{ ut_ad(ptr && end_ptr); if (page) { fsp_init_file_page_low(page); } return(ptr);}/**************************************************************************Initializes the fsp system. */voidfsp_init(void)/*==========*/{ /* Does nothing at the moment */}/**************************************************************************Writes the space id to a tablespace header. This function is used past thebuffer pool when we in fil0fil.c create a new single-table tablespace. */voidfsp_header_write_space_id(/*======================*/ page_t* page, /* in: first page in the space */ ulint space_id) /* in: space id */{ mach_write_to_4(page + FSP_HEADER_OFFSET + FSP_SPACE_ID, space_id);}/**************************************************************************Initializes the space header of a new created space and creates also theinsert buffer tree root if space == 0. */voidfsp_header_init(/*============*/ ulint space, /* in: space id */ ulint size, /* in: current size in blocks */ mtr_t* mtr) /* in: mini-transaction handle */ { fsp_header_t* header; page_t* page; ut_ad(mtr); mtr_x_lock(fil_space_get_latch(space), mtr); page = buf_page_create(space, 0, mtr); buf_page_get(space, 0, RW_X_LATCH, mtr);#ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(page, SYNC_FSP_PAGE);#endif /* UNIV_SYNC_DEBUG */ /* The prior contents of the file page should be ignored */ fsp_init_file_page(page, mtr); header = FSP_HEADER_OFFSET + page; mlog_write_ulint(header + FSP_SPACE_ID, space, MLOG_4BYTES, mtr); mlog_write_ulint(header + FSP_SIZE, size, MLOG_4BYTES, mtr); mlog_write_ulint(header + FSP_FREE_LIMIT, 0, MLOG_4BYTES, mtr); mlog_write_ulint(header + FSP_LOWEST_NO_WRITE, 0, MLOG_4BYTES, mtr); mlog_write_ulint(header + FSP_FRAG_N_USED, 0, MLOG_4BYTES, mtr); flst_init(header + FSP_FREE, mtr); flst_init(header + FSP_FREE_FRAG, mtr); flst_init(header + FSP_FULL_FRAG, mtr); flst_init(header + FSP_SEG_INODES_FULL, mtr); flst_init(header + FSP_SEG_INODES_FREE, mtr); mlog_write_dulint(header + FSP_SEG_ID, ut_dulint_create(0, 1), mtr); if (space == 0) { fsp_fill_free_list(FALSE, space, header, mtr); btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, space, ut_dulint_add(DICT_IBUF_ID_MIN, space), FALSE, mtr); } else { fsp_fill_free_list(TRUE, space, header, mtr); }}/**************************************************************************Reads the space id from the first page of a tablespace. */ulintfsp_header_get_space_id(/*====================*/ /* out: space id, ULINT UNDEFINED if error */ page_t* page) /* in: first page of a tablespace */{ ulint fsp_id; ulint id; fsp_id = mach_read_from_4(FSP_HEADER_OFFSET + page + FSP_SPACE_ID);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -