#include "univ.i"#include "mtr0mtr.h"#include "fut0lst.h"#include "ut0byte.h"#include "page0types.h"Include dependency graph for fsp0fsp.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
| #define FSEG_HDR_OFFSET 8 |
| #define FSEG_HDR_PAGE_NO 4 |
| #define FSEG_HDR_SPACE 0 |
| #define FSP_CLEANING 3000000 |
Definition at line 356 of file fsp0fsp.h.
Referenced by btr_cur_pessimistic_delete(), btr_cur_pessimistic_update(), and fsp_reserve_free_extents().
| #define FSP_DOWN ((byte)112) |
Definition at line 24 of file fsp0fsp.h.
Referenced by btr_attach_half_pages(), btr_page_split_and_insert(), and fseg_alloc_free_page_low().
| #define FSP_EXTENT_SIZE 64 |
Definition at line 28 of file fsp0fsp.h.
Referenced by fil_node_open_file(), fseg_alloc_free_extent(), fseg_alloc_free_page_low(), fseg_fill_free_list(), fseg_free_extent(), fseg_free_page_low(), fseg_free_step(), fseg_mark_page_used(), fseg_n_reserved_pages_low(), fseg_validate_low(), fsp_alloc_free_page(), fsp_fill_free_list(), fsp_free_page(), fsp_get_available_space_in_free_extents(), fsp_reserve_free_extents(), fsp_reserve_free_pages(), fsp_try_extend_data_file(), fsp_validate(), trx_sys_create_doublewrite_buf(), xdes_calc_descriptor_index(), xdes_find_bit(), xdes_find_bit_downward(), xdes_get_bit(), xdes_get_n_used(), xdes_get_offset(), xdes_is_full(), and xdes_set_bit().
| #define FSP_IBUF_BITMAP_OFFSET 1 |
Definition at line 369 of file fsp0fsp.h.
Referenced by fsp_fill_free_list(), and ibuf_bitmap_page_no_calc().
| #define FSP_IBUF_HEADER_PAGE_NO 3 |
| #define FSP_IBUF_TREE_ROOT_PAGE_NO 4 |
Definition at line 378 of file fsp0fsp.h.
Referenced by ibuf_data_init_for_space(), and ibuf_tree_root_get().
| #define FSP_NO_DIR ((byte)113) |
Definition at line 25 of file fsp0fsp.h.
Referenced by btr_root_raise_and_insert(), btr_store_big_rec_extern_fields(), and fseg_alloc_free_page_low().
| #define FSP_NORMAL 1000000 |
Definition at line 354 of file fsp0fsp.h.
Referenced by btr_cur_pessimistic_insert(), btr_cur_pessimistic_update(), fseg_alloc_free_page_general(), fseg_create_general(), and fsp_reserve_free_extents().
| #define FSP_UNDO 2000000 |
Definition at line 355 of file fsp0fsp.h.
Referenced by fsp_reserve_free_extents(), trx_undo_add_page(), and trx_undo_seg_create().
| #define FSP_UP ((byte)111) |
Definition at line 23 of file fsp0fsp.h.
Referenced by btr_create(), btr_page_split_and_insert(), fseg_alloc_free_page_low(), fseg_create_general(), ibuf_add_free_page(), trx_sys_create_doublewrite_buf(), and trx_undo_add_page().
| #define XDES_DESCRIBED_PER_PAGE UNIV_PAGE_SIZE |
Definition at line 361 of file fsp0fsp.h.
Referenced by fsp_fill_free_list(), fsp_get_available_space_in_free_extents(), fsp_reserve_free_extents(), fsp_validate(), ibuf_bitmap_page_get_bits(), ibuf_bitmap_page_init(), ibuf_bitmap_page_no_calc(), ibuf_bitmap_page_set_bits(), xdes_calc_descriptor_index(), and xdes_calc_descriptor_page().
| typedef byte fseg_header_t |
| ulint fseg_alloc_free_page | ( | fseg_header_t * | seg_header, | |
| ulint | hint, | |||
| byte | direction, | |||
| mtr_t * | mtr | |||
| ) |
Definition at line 2628 of file fsp0fsp.c.
References FALSE, and fseg_alloc_free_page_general().
Referenced by btr_create(), ibuf_add_free_page(), and trx_sys_create_doublewrite_buf().
02630 : allocated page offset, FIL_NULL if no 02631 page could be allocated */ 02632 fseg_header_t* seg_header,/* in: segment header */ 02633 ulint hint, /* in: hint of which page would be desirable */ 02634 byte direction,/* in: if the new page is needed because 02635 of an index page split, and records are 02636 inserted there in order, into which 02637 direction they go alphabetically: FSP_DOWN, 02638 FSP_UP, FSP_NO_DIR */ 02639 mtr_t* mtr) /* in: mtr handle */ 02640 { 02641 return(fseg_alloc_free_page_general(seg_header, hint, direction, 02642 FALSE, mtr)); 02643 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint fseg_alloc_free_page_general | ( | fseg_header_t * | seg_header, | |
| ulint | hint, | |||
| byte | direction, | |||
| ibool | has_done_reservation, | |||
| mtr_t * | mtr | |||
| ) |
Definition at line 2558 of file fsp0fsp.c.
References buf_frame_get_space_id(), FIL_NULL, fil_space_get_latch(), fil_space_release_free_extents(), fseg_alloc_free_page_low(), fseg_inode_get(), FSP_NORMAL, fsp_reserve_free_extents(), ibuf_free_excess_pages(), kernel_mutex, mtr_memo_contains(), MTR_MEMO_X_LOCK, mtr_x_lock, rw_lock_get_x_lock_count(), and ut_ad.
Referenced by btr_page_alloc(), fseg_alloc_free_page(), and trx_undo_add_page().
02560 : allocated page offset, FIL_NULL if no 02561 page could be allocated */ 02562 fseg_header_t* seg_header,/* in: segment header */ 02563 ulint hint, /* in: hint of which page would be desirable */ 02564 byte direction,/* in: if the new page is needed because 02565 of an index page split, and records are 02566 inserted there in order, into which 02567 direction they go alphabetically: FSP_DOWN, 02568 FSP_UP, FSP_NO_DIR */ 02569 ibool has_done_reservation, /* in: TRUE if the caller has 02570 already done the reservation for the page 02571 with fsp_reserve_free_extents, then there 02572 is no need to do the check for this individual 02573 page */ 02574 mtr_t* mtr) /* in: mtr handle */ 02575 { 02576 fseg_inode_t* inode; 02577 ulint space; 02578 rw_lock_t* latch; 02579 ibool success; 02580 ulint page_no; 02581 ulint n_reserved; 02582 02583 space = buf_frame_get_space_id(seg_header); 02584 02585 #ifdef UNIV_SYNC_DEBUG 02586 ut_ad(!mutex_own(&kernel_mutex) 02587 || mtr_memo_contains(mtr, fil_space_get_latch(space), 02588 MTR_MEMO_X_LOCK)); 02589 #endif /* UNIV_SYNC_DEBUG */ 02590 latch = fil_space_get_latch(space); 02591 02592 mtr_x_lock(latch, mtr); 02593 02594 if (rw_lock_get_x_lock_count(latch) == 1) { 02595 /* This thread did not own the latch before this call: free 02596 excess pages from the insert buffer free list */ 02597 02598 if (space == 0) { 02599 ibuf_free_excess_pages(space); 02600 } 02601 } 02602 02603 inode = fseg_inode_get(seg_header, mtr); 02604 02605 if (!has_done_reservation) { 02606 success = fsp_reserve_free_extents(&n_reserved, space, 2, 02607 FSP_NORMAL, mtr); 02608 if (!success) { 02609 return(FIL_NULL); 02610 } 02611 } 02612 02613 page_no = fseg_alloc_free_page_low(buf_frame_get_space_id(inode), 02614 inode, hint, direction, mtr); 02615 if (!has_done_reservation) { 02616 fil_space_release_free_extents(space, n_reserved); 02617 } 02618 02619 return(page_no); 02620 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 2127 of file fsp0fsp.c.
References FALSE, and fseg_create_general().
Referenced by btr_create(), dict_hdr_create(), trx_rseg_header_create(), trx_sys_create_doublewrite_buf(), and trx_sysf_create().
02129 : the page where the segment header is placed, 02130 x-latched, NULL if could not create segment 02131 because of lack of space */ 02132 ulint space, /* in: space id */ 02133 ulint page, /* in: page where the segment header is placed: if 02134 this is != 0, the page must belong to another segment, 02135 if this is 0, a new page will be allocated and it 02136 will belong to the created segment */ 02137 ulint byte_offset, /* in: byte offset of the created segment header 02138 on the page */ 02139 mtr_t* mtr) /* in: mtr */ 02140 { 02141 return(fseg_create_general(space, page, byte_offset, FALSE, mtr)); 02142 }
Here is the call graph for this function:

Here is the caller graph for this function:

| page_t* fseg_create_general | ( | ulint | space, | |
| ulint | page, | |||
| ulint | byte_offset, | |||
| ibool | has_done_reservation, | |||
| mtr_t * | mtr | |||
| ) |
Definition at line 1995 of file fsp0fsp.c.
References buf_frame_align(), buf_frame_get_page_no(), buf_page_get, FIL_NULL, FIL_PAGE_TYPE, FIL_PAGE_TYPE_SYS, fil_space_get_latch(), fil_space_release_free_extents(), flst_init(), fseg_alloc_free_page_low(), FSEG_FRAG_ARR_N_SLOTS, FSEG_FREE, FSEG_FULL, FSEG_HDR_OFFSET, FSEG_HDR_PAGE_NO, FSEG_HDR_SPACE, FSEG_ID, FSEG_MAGIC_N, FSEG_MAGIC_N_VALUE, FSEG_NOT_FULL, FSEG_NOT_FULL_N_USED, fseg_set_nth_frag_page_no(), fsp_alloc_seg_inode(), fsp_free_seg_inode(), fsp_get_space_header(), FSP_NORMAL, fsp_reserve_free_extents(), FSP_SEG_ID, FSP_UP, ibuf_free_excess_pages(), kernel_mutex, MLOG_2BYTES, MLOG_4BYTES, mlog_write_dulint(), mlog_write_ulint(), mtr_memo_contains(), MTR_MEMO_X_LOCK, mtr_read_dulint(), mtr_x_lock, NULL, page_t, rw_lock_get_x_lock_count(), RW_X_LATCH, ut_ad, and ut_dulint_add().
Referenced by fseg_create(), and trx_undo_seg_create().
01997 : the page where the segment header is placed, 01998 x-latched, NULL if could not create segment 01999 because of lack of space */ 02000 ulint space, /* in: space id */ 02001 ulint page, /* in: page where the segment header is placed: if 02002 this is != 0, the page must belong to another segment, 02003 if this is 0, a new page will be allocated and it 02004 will belong to the created segment */ 02005 ulint byte_offset, /* in: byte offset of the created segment header 02006 on the page */ 02007 ibool has_done_reservation, /* in: TRUE if the caller has already 02008 done the reservation for the pages with 02009 fsp_reserve_free_extents (at least 2 extents: one for 02010 the inode and the other for the segment) then there is 02011 no need to do the check for this individual 02012 operation */ 02013 mtr_t* mtr) /* in: mtr */ 02014 { 02015 fsp_header_t* space_header; 02016 fseg_inode_t* inode; 02017 dulint seg_id; 02018 fseg_header_t* header = 0; /* remove warning */ 02019 rw_lock_t* latch; 02020 ibool success; 02021 ulint n_reserved; 02022 page_t* ret = NULL; 02023 ulint i; 02024 02025 ut_ad(mtr); 02026 02027 if (page != 0) { 02028 header = byte_offset + buf_page_get(space, page, RW_X_LATCH, 02029 mtr); 02030 } 02031 02032 #ifdef UNIV_SYNC_DEBUG 02033 ut_ad(!mutex_own(&kernel_mutex) 02034 || mtr_memo_contains(mtr, fil_space_get_latch(space), 02035 MTR_MEMO_X_LOCK)); 02036 #endif /* UNIV_SYNC_DEBUG */ 02037 latch = fil_space_get_latch(space); 02038 02039 mtr_x_lock(latch, mtr); 02040 02041 if (rw_lock_get_x_lock_count(latch) == 1) { 02042 /* This thread did not own the latch before this call: free 02043 excess pages from the insert buffer free list */ 02044 02045 if (space == 0) { 02046 ibuf_free_excess_pages(space); 02047 } 02048 } 02049 02050 if (!has_done_reservation) { 02051 success = fsp_reserve_free_extents(&n_reserved, space, 2, 02052 FSP_NORMAL, mtr); 02053 if (!success) { 02054 return(NULL); 02055 } 02056 } 02057 02058 space_header = fsp_get_space_header(space, mtr); 02059 02060 inode = fsp_alloc_seg_inode(space_header, mtr); 02061 02062 if (inode == NULL) { 02063 02064 goto funct_exit; 02065 } 02066 02067 /* Read the next segment id from space header and increment the 02068 value in space header */ 02069 02070 seg_id = mtr_read_dulint(space_header + FSP_SEG_ID, mtr); 02071 02072 mlog_write_dulint(space_header + FSP_SEG_ID, ut_dulint_add(seg_id, 1), 02073 mtr); 02074 02075 mlog_write_dulint(inode + FSEG_ID, seg_id, mtr); 02076 mlog_write_ulint(inode + FSEG_NOT_FULL_N_USED, 0, MLOG_4BYTES, mtr); 02077 02078 flst_init(inode + FSEG_FREE, mtr); 02079 flst_init(inode + FSEG_NOT_FULL, mtr); 02080 flst_init(inode + FSEG_FULL, mtr); 02081 02082 mlog_write_ulint(inode + FSEG_MAGIC_N, FSEG_MAGIC_N_VALUE, 02083 MLOG_4BYTES, mtr); 02084 for (i = 0; i < FSEG_FRAG_ARR_N_SLOTS; i++) { 02085 fseg_set_nth_frag_page_no(inode, i, FIL_NULL, mtr); 02086 } 02087 02088 if (page == 0) { 02089 page = fseg_alloc_free_page_low(space, inode, 0, FSP_UP, mtr); 02090 02091 if (page == FIL_NULL) { 02092 02093 fsp_free_seg_inode(space, inode, mtr); 02094 02095 goto funct_exit; 02096 } 02097 02098 header = byte_offset 02099 + buf_page_get(space, page, RW_X_LATCH, mtr); 02100 mlog_write_ulint(header - byte_offset + FIL_PAGE_TYPE, 02101 FIL_PAGE_TYPE_SYS, MLOG_2BYTES, mtr); 02102 } 02103 02104 mlog_write_ulint(header + FSEG_HDR_OFFSET, 02105 inode - buf_frame_align(inode), MLOG_2BYTES, mtr); 02106 02107 mlog_write_ulint(header + FSEG_HDR_PAGE_NO, 02108 buf_frame_get_page_no(inode), MLOG_4BYTES, mtr); 02109 02110 mlog_write_ulint(header + FSEG_HDR_SPACE, space, MLOG_4BYTES, mtr); 02111 02112 ret = buf_frame_align(header); 02113 02114 funct_exit: 02115 if (!has_done_reservation) { 02116 02117 fil_space_release_free_extents(space, n_reserved); 02118 } 02119 02120 return(ret); 02121 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 3323 of file fsp0fsp.c.
References fil_addr_struct::boffset, yaSSL::finished, fseg_free_step(), fut_get_ptr(), mtr_commit(), mtr_start(), fil_addr_struct::page, and RW_X_LATCH.
03325 : space id */ 03326 ulint page_no,/* in: page number where the segment header is 03327 placed */ 03328 ulint offset) /* in: byte offset of the segment header on that 03329 page */ 03330 { 03331 mtr_t mtr; 03332 ibool finished; 03333 fseg_header_t* header; 03334 fil_addr_t addr; 03335 03336 addr.page = page_no; 03337 addr.boffset = offset; 03338 03339 for (;;) { 03340 mtr_start(&mtr); 03341 03342 header = fut_get_ptr(space, addr, RW_X_LATCH, &mtr); 03343 03344 finished = fseg_free_step(header, &mtr); 03345 03346 mtr_commit(&mtr); 03347 03348 if (finished) { 03349 03350 return; 03351 } 03352 } 03353 }
Here is the call graph for this function:

| void fseg_free_page | ( | fseg_header_t * | seg_header, | |
| ulint | space, | |||
| ulint | page, | |||
| mtr_t * | mtr | |||
| ) |
Definition at line 3083 of file fsp0fsp.c.
References buf_page_set_file_page_was_freed(), fil_space_get_latch(), fseg_free_page_low(), fseg_inode_get(), kernel_mutex, mtr_memo_contains(), MTR_MEMO_X_LOCK, mtr_x_lock, and ut_ad.
Referenced by btr_page_free_low(), ibuf_remove_free_page(), and trx_undo_free_page().
03085 : segment header */ 03086 ulint space, /* in: space id */ 03087 ulint page, /* in: page offset */ 03088 mtr_t* mtr) /* in: mtr handle */ 03089 { 03090 fseg_inode_t* seg_inode; 03091 03092 #ifdef UNIV_SYNC_DEBUG 03093 ut_ad(!mutex_own(&kernel_mutex) 03094 || mtr_memo_contains(mtr, fil_space_get_latch(space), 03095 MTR_MEMO_X_LOCK)); 03096 #endif /* UNIV_SYNC_DEBUG */ 03097 mtr_x_lock(fil_space_get_latch(space), mtr); 03098 03099 seg_inode = fseg_inode_get(seg_header, mtr); 03100 03101 fseg_free_page_low(seg_inode, space, page, mtr); 03102 03103 #ifdef UNIV_DEBUG_FILE_ACCESSES 03104 buf_page_set_file_page_was_freed(space, page); 03105 #endif 03106 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool fseg_free_step | ( | fseg_header_t * | header, | |
| mtr_t * | mtr | |||
| ) |
Definition at line 3186 of file fsp0fsp.c.
References buf_frame_get_page_no(), buf_frame_get_space_id(), FALSE, fil_space_get_latch(), fseg_find_last_used_frag_page_slot(), fseg_free_extent(), fseg_free_page_low(), fseg_get_first_extent(), fseg_get_nth_frag_page_no(), fseg_inode_get(), FSP_EXTENT_SIZE, fsp_free_seg_inode(), kernel_mutex, mtr_memo_contains(), MTR_MEMO_X_LOCK, mtr_x_lock, NULL, TRUE, ut_a, ut_ad, XDES_FREE_BIT, xdes_get_bit(), xdes_get_descriptor(), and xdes_get_offset().
Referenced by btr_free_but_not_root(), btr_free_root(), fseg_free(), trx_purge_free_segment(), and trx_undo_seg_free().
03188 : TRUE if freeing completed */ 03189 fseg_header_t* header, /* in, own: segment header; NOTE: if the header 03190 resides on the first page of the frag list 03191 of the segment, this pointer becomes obsolete 03192 after the last freeing step */ 03193 mtr_t* mtr) /* in: mtr */ 03194 { 03195 ulint n; 03196 ulint page; 03197 xdes_t* descr; 03198 fseg_inode_t* inode; 03199 ulint space; 03200 03201 space = buf_frame_get_space_id(header); 03202 03203 #ifdef UNIV_SYNC_DEBUG 03204 ut_ad(!mutex_own(&kernel_mutex) 03205 || mtr_memo_contains(mtr, fil_space_get_latch(space), 03206 MTR_MEMO_X_LOCK)); 03207 #endif /* UNIV_SYNC_DEBUG */ 03208 mtr_x_lock(fil_space_get_latch(space), mtr); 03209 03210 descr = xdes_get_descriptor(space, buf_frame_get_page_no(header), mtr); 03211 03212 /* Check that the header resides on a page which has not been 03213 freed yet */ 03214 03215 ut_a(descr); 03216 ut_a(xdes_get_bit(descr, XDES_FREE_BIT, buf_frame_get_page_no(header) 03217 % FSP_EXTENT_SIZE, mtr) == FALSE); 03218 inode = fseg_inode_get(header, mtr); 03219 03220 descr = fseg_get_first_extent(inode, mtr); 03221 03222 if (descr != NULL) { 03223 /* Free the extent held by the segment */ 03224 page = xdes_get_offset(descr); 03225 03226 fseg_free_extent(inode, space, page, mtr); 03227 03228 return(FALSE); 03229 } 03230 03231 /* Free a frag page */ 03232 n = fseg_find_last_used_frag_page_slot(inode, mtr); 03233 03234 if (n == ULINT_UNDEFINED) { 03235 /* Freeing completed: free the segment inode */ 03236 fsp_free_seg_inode(space, inode, mtr); 03237 03238 return(TRUE); 03239 } 03240 03241 fseg_free_page_low(inode, space, 03242 fseg_get_nth_frag_page_no(inode, n, mtr), mtr); 03243 03244 n = fseg_find_last_used_frag_page_slot(inode, mtr); 03245 03246 if (n == ULINT_UNDEFINED) { 03247 /* Freeing completed: free the segment inode */ 03248 fsp_free_seg_inode(space, inode, mtr); 03249 03250 return(TRUE); 03251 } 03252 03253 return(FALSE); 03254 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool fseg_free_step_not_header | ( | fseg_header_t * | header, | |
| mtr_t * | mtr | |||
| ) |
Definition at line 3261 of file fsp0fsp.c.
References buf_frame_get_page_no(), buf_frame_get_space_id(), FALSE, fil_space_get_latch(), fseg_find_last_used_frag_page_slot(), fseg_free_extent(), fseg_free_page_low(), fseg_get_first_extent(), fseg_get_nth_frag_page_no(), fseg_inode_get(), kernel_mutex, mtr_memo_contains(), MTR_MEMO_X_LOCK, mtr_x_lock, NULL, TRUE, ut_ad, ut_error, and xdes_get_offset().
Referenced by btr_free_but_not_root(), and trx_purge_free_segment().
03263 : TRUE if freeing completed, except the 03264 header page */ 03265 fseg_header_t* header, /* in: segment header which must reside on 03266 the first fragment page of the segment */ 03267 mtr_t* mtr) /* in: mtr */ 03268 { 03269 ulint n; 03270 ulint page; 03271 xdes_t* descr; 03272 fseg_inode_t* inode; 03273 ulint space; 03274 ulint page_no; 03275 03276 space = buf_frame_get_space_id(header); 03277 03278 #ifdef UNIV_SYNC_DEBUG 03279 ut_ad(!mutex_own(&kernel_mutex) 03280 || mtr_memo_contains(mtr, fil_space_get_latch(space), 03281 MTR_MEMO_X_LOCK)); 03282 #endif /* UNIV_SYNC_DEBUG */ 03283 mtr_x_lock(fil_space_get_latch(space), mtr); 03284 03285 inode = fseg_inode_get(header, mtr); 03286 03287 descr = fseg_get_first_extent(inode, mtr); 03288 03289 if (descr != NULL) { 03290 /* Free the extent held by the segment */ 03291 page = xdes_get_offset(descr); 03292 03293 fseg_free_extent(inode, space, page, mtr); 03294 03295 return(FALSE); 03296 } 03297 03298 /* Free a frag page */ 03299 03300 n = fseg_find_last_used_frag_page_slot(inode, mtr); 03301 03302 if (n == ULINT_UNDEFINED) { 03303 ut_error; 03304 } 03305 03306 page_no = fseg_get_nth_frag_page_no(inode, n, mtr); 03307 03308 if (page_no == buf_frame_get_page_no(header)) { 03309 03310 return(TRUE); 03311 } 03312 03313 fseg_free_page_low(inode, space, page_no, mtr); 03314 03315 return(FALSE); 03316 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ulint fseg_n_reserved_pages | ( | fseg_header_t * | header, | |
| ulint * | used, | |||
| mtr_t * | mtr | |||
| ) |
Definition at line 2179 of file fsp0fsp.c.
References buf_frame_get_space_id(), fil_space_get_latch(), fseg_inode_get(), fseg_n_reserved_pages_low(), kernel_mutex, mtr_memo_contains(), MTR_MEMO_X_LOCK, mtr_x_lock, and ut_ad.
Referenced by btr_get_size(), and ibuf_data_init_for_space().
02181 : number of reserved pages */ 02182 fseg_header_t* header, /* in: segment header */ 02183 ulint* used, /* out: number of pages used (<= reserved) */ 02184 mtr_t* mtr) /* in: mtr handle */ 02185 { 02186 ulint ret; 02187 fseg_inode_t* inode; 02188 ulint space; 02189 02190 space = buf_frame_get_space_id(header); 02191 02192 #ifdef UNIV_SYNC_DEBUG 02193 ut_ad(!mutex_own(&kernel_mutex) 02194 || mtr_memo_contains(mtr, fil_space_get_latch(space), 02195 MTR_MEMO_X_LOCK)); 02196 #endif /* UNIV_SYNC_DEBUG */ 02197 mtr_x_lock(fil_space_get_latch(space), mtr); 02198 02199 inode = fseg_inode_get(header, mtr); 02200 02201 ret = fseg_n_reserved_pages_low(inode, used, mtr); 02202 02203 return(ret); 02204 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void fseg_print | ( | fseg_header_t * | header, | |
| mtr_t * | mtr | |||
| ) |
Definition at line 3574 of file fsp0fsp.c.
References buf_frame_get_space_id(), fil_space_get_latch(), fseg_inode_get(), fseg_print_low(), and mtr_x_lock.
03576 : segment header */ 03577 mtr_t* mtr) /* in: mtr */ 03578 { 03579 fseg_inode_t* inode; 03580 ulint space; 03581 03582 space = buf_frame_get_space_id(header); 03583 03584 mtr_x_lock(fil_space_get_latch(space), mtr); 03585 03586 inode = fseg_inode_get(header, mtr); 03587 03588 fseg_print_low(inode, mtr); 03589 }
Here is the call graph for this function:

| ibool fseg_validate | ( | fseg_header_t * | header, | |
| mtr_t * | mtr2 | |||
| ) |
Definition at line 3499 of file fsp0fsp.c.
References buf_frame_get_space_id(), fil_space_get_latch(), fseg_inode_get(), fseg_validate_low(), and mtr_x_lock.
03501 : TRUE if ok */ 03502 fseg_header_t* header, /* in: segment header */ 03503 mtr_t* mtr2) /* in: mtr */ 03504 { 03505 fseg_inode_t* inode; 03506 ibool ret; 03507 ulint space; 03508 03509 space = buf_frame_get_space_id(header); 03510 03511 mtr_x_lock(fil_space_get_latch(space), mtr2); 03512 03513 inode = fseg_inode_get(header, mtr2); 03514 03515 ret = fseg_validate_low(inode, mtr2); 03516 03517 return(ret); 03518 }
Here is the call graph for this function:

| UNIV_INLINE ibool fsp_descr_page | ( | ulint | page_no | ) |
Definition at line 2822 of file fsp0fsp.c.
References fil_space_get_latch(), flst_get_len(), FSP_EXTENT_SIZE, FSP_FREE, FSP_FREE_LIMIT, fsp_get_space_header(), FSP_SIZE, kernel_mutex, MLOG_4BYTES, mtr_commit(), mtr_read_ulint(), mtr_start(), mtr_x_lock, UNIV_PAGE_SIZE, ut_a, ut_ad, and XDES_DESCRIBED_PER_PAGE.
02824 : available space in kB */ 02825 ulint space) /* in: space id */ 02826 { 02827 fsp_header_t* space_header; 02828 ulint n_free_list_ext; 02829 ulint free_limit; 02830 ulint size; 02831 ulint n_free; 02832 ulint n_free_up; 02833 ulint reserve; 02834 rw_lock_t* latch; 02835 mtr_t mtr; 02836 02837 #ifdef UNIV_SYNC_DEBUG 02838 ut_ad(!mutex_own(&kernel_mutex)); 02839 #endif /* UNIV_SYNC_DEBUG */ 02840 mtr_start(&mtr); 02841 02842 latch = fil_space_get_latch(space); 02843 02844 mtr_x_lock(latch, &mtr); 02845 02846 space_header = fsp_get_space_header(space, &mtr); 02847 02848 size = mtr_read_ulint(space_header + FSP_SIZE, MLOG_4BYTES, &mtr); 02849 02850 n_free_list_ext = flst_get_len(space_header + FSP_FREE, &mtr); 02851 02852 free_limit = mtr_read_ulint(space_header + FSP_FREE_LIMIT, 02853 MLOG_4BYTES, &mtr); 02854 mtr_commit(&mtr); 02855 02856 if (size < FSP_EXTENT_SIZE) { 02857 ut_a(space != 0); /* This must be a single-table 02858 tablespace */ 02859 02860 return(0); /* TODO: count free frag pages and 02861 return a value based on that */ 02862 } 02863 02864 /* Below we play safe when counting free extents above the free limit: 02865 some of them will contain extent descriptor pages, and therefore 02866 will not be free extents */ 02867 02868 n_free_up = (size - free_limit) / FSP_EXTENT_SIZE; 02869 02870 if (n_free_up > 0) { 02871 n_free_up--; 02872 n_free_up = n_free_up - n_free_up 02873 / (XDES_DESCRIBED_PER_PAGE / FSP_EXTENT_SIZE); 02874 } 02875 02876 n_free = n_free_list_ext + n_free_up; 02877 02878 /* We reserve 1 extent + 0.5 % of the space size to undo logs 02879 and 1 extent + 0.5 % to cleaning operations; NOTE: this source 02880 code is duplicated in the function above! */ 02881 02882 reserve = 2 + ((size / FSP_EXTENT_SIZE) * 2) / 200; 02883 02884 if (reserve > n_free) { 02885 return(0); 02886 } 02887 02888 return(((n_free - reserve) * FSP_EXTENT_SIZE) 02889 * (UNIV_PAGE_SIZE / 1024)); 02890 }
Here is the call graph for this function:

Definition at line 307 of file fsp0fsp.c.
References FSP_HEADER_OFFSET, FSP_SIZE, and mach_read_from_4().
00309 : tablespace size stored in the space header */ 00310 page_t* page) /* in: header page (page 0 in the tablespace) */ 00311 { 00312 return(mach_read_from_4(page + FSP_HEADER_OFFSET + FSP_SIZE)); 00313 }
Here is the call graph for this function:

Definition at line 983 of file fsp0fsp.c.
References fil_space_get_latch(), FSP_FREE_LIMIT, fsp_get_space_header(), log_fsp_current_free_limit_set_and_checkpoint(), MLOG_4BYTES, mtr_commit(), mtr_read_ulint(), mtr_start(), mtr_x_lock, UNIV_PAGE_SIZE, and ut_a.
Referenced by innobase_start_or_create_for_mysql().
00985 : free limit in megabytes */ 00986 ulint space) /* in: space id, must be 0 */ 00987 { 00988 fsp_header_t* header; 00989 ulint limit; 00990 mtr_t mtr; 00991 00992 ut_a(space == 0); /* We have only one log_fsp_current_... variable */ 00993 00994 mtr_start(&mtr); 00995 00996 mtr_x_lock(fil_space_get_latch(space), &mtr); 00997 00998 header = fsp_get_space_header(space, &mtr); 00999 01000 limit = mtr_read_ulint(header + FSP_FREE_LIMIT, MLOG_4BYTES, &mtr); 01001 01002 limit = limit / ((1024 * 1024) / UNIV_PAGE_SIZE); 01003 01004 log_fsp_current_free_limit_set_and_checkpoint(limit); 01005 01006 mtr_commit(&mtr); 01007 01008 return(limit); 01009 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 928 of file fsp0fsp.c.
References FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, FSP_HEADER_OFFSET, FSP_SPACE_ID, id, and mach_read_from_4().
Referenced by fil_load_single_table_tablespace(), fil_node_open_file(), fil_open_single_table_tablespace(), and fil_reset_too_high_lsns().
00930 : space id, ULINT UNDEFINED if error */ 00931 page_t* page) /* in: first page of a tablespace */ 00932 { 00933 ulint fsp_id; 00934 ulint id; 00935 00936 fsp_id = mach_read_from_4(FSP_HEADER_OFFSET + page + FSP_SPACE_ID); 00937 00938 id = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); 00939 00940 if (id != fsp_id) { 00941 fprintf(stderr, 00942 "InnoDB: Error: space id in fsp header %lu, but in the page header %lu\n", 00943 (ulong) fsp_id, (ulong) id); 00944 00945 return(ULINT_UNDEFINED); 00946 } 00947 00948 return(id); 00949 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1017 of file fsp0fsp.c.
References fil_space_get_latch(), fsp_get_space_header(), FSP_SIZE, MLOG_4BYTES, mtr_commit(), mtr_read_ulint(), mtr_start(), mtr_x_lock, and ut_a.
Referenced by innobase_start_or_create_for_mysql().
01019 : size in pages */ 01020 ulint space) /* in: space id, must be 0 */ 01021 { 01022 fsp_header_t* header; 01023 ulint size; 01024 mtr_t mtr; 01025 01026 ut_a(space == 0); /* We have only one log_fsp_current_... variable */ 01027 01028 mtr_start(&mtr); 01029 01030 mtr_x_lock(fil_space_get_latch(space), &mtr); 01031 01032 header = fsp_get_space_header(space, &mtr); 01033 01034 size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, &mtr); 01035 01036 mtr_commit(&mtr); 01037 01038 return(size); 01039 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 955 of file fsp0fsp.c.
References fil_space_get_latch(), fsp_get_space_header(), FSP_SIZE, MLOG_4BYTES, mlog_write_ulint(), mtr_read_ulint(), mtr_x_lock, and ut_ad.
Referenced by innobase_start_or_create_for_mysql().
00957 : space id */ 00958 ulint size_inc,/* in: size increment in pages */ 00959 mtr_t* mtr) /* in: mini-transaction handle */ 00960 { 00961 fsp_header_t* header; 00962 ulint size; 00963 00964 ut_ad(mtr); 00965 00966 mtr_x_lock(fil_space_get_latch(space), mtr); 00967 00968 header = fsp_get_space_header(space, mtr); 00969 00970 size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, mtr); 00971 00972 mlog_write_ulint(header + FSP_SIZE, size + size_inc, MLOG_4BYTES, 00973 mtr); 00974 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 872 of file fsp0fsp.c.
References btr_create(), buf_page_create(), buf_page_get, DICT_CLUSTERED, DICT_IBUF, DICT_IBUF_ID_MIN, DICT_UNIVERSAL, FALSE, FIL_PAGE_TYPE, FIL_PAGE_TYPE_FSP_HDR, fil_space_get_latch(), flst_init(), fsp_fill_free_list(), FSP_FRAG_N_USED, FSP_FREE, FSP_FREE_FRAG, FSP_FREE_LIMIT, FSP_FULL_FRAG, FSP_HEADER_OFFSET, fsp_init_file_page(), FSP_LOWEST_NO_WRITE, FSP_NOT_USED, FSP_SEG_ID, FSP_SEG_INODES_FREE, FSP_SEG_INODES_FULL, FSP_SIZE, FSP_SPACE_ID, MLOG_2BYTES, MLOG_4BYTES, mlog_write_dulint(), mlog_write_ulint(), mtr_x_lock, page, page_t, RW_X_LATCH, SYNC_FSP_PAGE, TRUE, ut_ad, ut_dulint_add(), and ut_dulint_create().
Referenced by dict_build_table_def_step(), and innobase_start_or_create_for_mysql().
00874 : space id */ 00875 ulint size, /* in: current size in blocks */ 00876 mtr_t* mtr) /* in: mini-transaction handle */ 00877 { 00878 fsp_header_t* header; 00879 page_t* page; 00880 00881 ut_ad(mtr); 00882 00883 mtr_x_lock(fil_space_get_latch(space), mtr); 00884 00885 page = buf_page_create(space, 0, mtr); 00886 buf_page_get(space, 0, RW_X_LATCH, mtr); 00887 #ifdef UNIV_SYNC_DEBUG 00888 buf_page_dbg_add_level(page, SYNC_FSP_PAGE); 00889 #endif /* UNIV_SYNC_DEBUG */ 00890 00891 /* The prior contents of the file page should be ignored */ 00892 00893 fsp_init_file_page(page, mtr); 00894 00895 mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_TYPE_FSP_HDR, 00896 MLOG_2BYTES, mtr); 00897 00898 header = FSP_HEADER_OFFSET + page; 00899 00900 mlog_write_ulint(header + FSP_SPACE_ID, space, MLOG_4BYTES, mtr); 00901 mlog_write_ulint(header + FSP_NOT_USED, 0, MLOG_4BYTES, mtr); 00902 00903 mlog_write_ulint(header + FSP_SIZE, size, MLOG_4BYTES, mtr); 00904 mlog_write_ulint(header + FSP_FREE_LIMIT, 0, MLOG_4BYTES, mtr); 00905 mlog_write_ulint(header + FSP_LOWEST_NO_WRITE, 0, MLOG_4BYTES, mtr); 00906 mlog_write_ulint(header + FSP_FRAG_N_USED, 0, MLOG_4BYTES, mtr); 00907 00908 flst_init(header + FSP_FREE, mtr); 00909 flst_init(header + FSP_FREE_FRAG, mtr); 00910 flst_init(header + FSP_FULL_FRAG, mtr); 00911 flst_init(header + FSP_SEG_INODES_FULL, mtr); 00912 flst_init(header + FSP_SEG_INODES_FREE, mtr); 00913 00914 mlog_write_dulint(header + FSP_SEG_ID, ut_dulint_create(0, 1), mtr); 00915 if (space == 0) { 00916 fsp_fill_free_list(FALSE, space, header, mtr); 00917 btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, space, 00918 ut_dulint_add(DICT_IBUF_ID_MIN, space), FALSE, mtr); 00919 } else { 00920 fsp_fill_free_list(TRUE, space, header, mtr); 00921 } 00922 }
Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 859 of file fsp0fsp.c.
References FSP_HEADER_OFFSET, FSP_SPACE_ID, and mach_write_to_4().
Referenced by fil_create_new_single_table_tablespace().
00861 : first page in the space */ 00862 ulint space_id) /* in: space id */ 00863 { 00864 mach_write_to_4(page + FSP_HEADER_OFFSET + FSP_SPACE_ID, space_id); 00865 }
Here is the call graph for this function:

Here is the caller graph for this function:

| void fsp_init | ( | void | ) |
Definition at line 848 of file fsp0fsp.c.
Referenced by innobase_start_or_create_for_mysql().
Here is the caller graph for this function:

| void fsp_print | ( | ulint | space | ) |
Definition at line 3826 of file fsp0fsp.c.
References fil_addr_is_null(), fil_space_get_latch(), flst_get_first(), flst_get_len(), flst_get_next_addr(), FSEG_ID, FSEG_INODE_PAGE_NODE, fseg_print_low(), FSP_FRAG_N_USED, FSP_FREE, FSP_FREE_FRAG, FSP_FREE_LIMIT, FSP_FULL_FRAG, fsp_get_space_header(), FSP_SEG_ID, fsp_seg_inode_page_get_nth_inode(), FSP_SEG_INODES_FREE, FSP_SEG_INODES_FULL, FSP_SEG_INODES_PER_PAGE, FSP_SIZE, fut_get_ptr(), mach_read_from_8(), MLOG_4BYTES, mtr_commit(), mtr_read_dulint(), mtr_read_ulint(), mtr_start(), mtr_x_lock, page_t, RW_X_LATCH, ut_a, ut_dulint_cmp(), ut_dulint_get_high(), ut_dulint_get_low(), and ut_dulint_zero.
Referenced by srv_lock_timeout_and_monitor_thread().
03828 : space id */ 03829 { 03830 fsp_header_t* header; 03831 fseg_inode_t* seg_inode; 03832 page_t* seg_inode_page; 03833 ulint size; 03834 ulint free_limit; 03835 ulint frag_n_used; 03836 fil_addr_t node_addr; 03837 fil_addr_t next_node_addr; 03838 ulint n_free; 03839 ulint n_free_frag; 03840 ulint n_full_frag; 03841 ulint seg_id_low; 03842 ulint seg_id_high; 03843 ulint n; 03844 ulint n_segs = 0; 03845 dulint d_var; 03846 mtr_t mtr; 03847 mtr_t mtr2; 03848 03849 /* Start first a mini-transaction mtr2 to lock out all other threads 03850 from the fsp system */ 03851 03852 mtr_start(&mtr2); 03853 03854 mtr_x_lock(fil_space_get_latch(space), &mtr2); 03855 03856 mtr_start(&mtr); 03857 03858 mtr_x_lock(fil_space_get_latch(space), &mtr); 03859 03860 header = fsp_get_space_header(space, &mtr); 03861 03862 size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, &mtr); 03863 03864 free_limit = mtr_read_ulint(header + FSP_FREE_LIMIT, MLOG_4BYTES, 03865 &mtr); 03866 frag_n_used = mtr_read_ulint(header + FSP_FRAG_N_USED, MLOG_4BYTES, 03867 &mtr); 03868 n_free = flst_get_len(header + FSP_FREE, &mtr); 03869 n_free_frag = flst_get_len(header + FSP_FREE_FRAG, &mtr); 03870 n_full_frag = flst_get_len(header + FSP_FULL_FRAG, &mtr); 03871 03872 d_var = mtr_read_dulint(header + FSP_SEG_ID, &mtr); 03873 03874 seg_id_low = ut_dulint_get_low(d_var); 03875 seg_id_high = ut_dulint_get_high(d_var); 03876 03877 fprintf(stderr, 03878 "FILE SPACE INFO: id %lu\n" 03879 "size %lu, free limit %lu, free extents %lu\n" 03880 "not full frag extents %lu: used pages %lu, full frag extents %lu\n" 03881 "first seg id not used %lu %lu\n", 03882 (long) space, 03883 (ulong) size, (ulong) free_limit, (ulong) n_free, 03884 (ulong) n_free_frag, (ulong) frag_n_used, (ulong) n_full_frag, 03885 (ulong) seg_id_high, (ulong) seg_id_low); 03886 03887 mtr_commit(&mtr); 03888 03889 /* Print segments */ 03890 03891 mtr_start(&mtr); 03892 mtr_x_lock(fil_space_get_latch(space), &mtr); 03893 03894 header = fsp_get_space_header(space, &mtr); 03895 03896 node_addr = flst_get_first(header + FSP_SEG_INODES_FULL, &mtr); 03897 03898 mtr_commit(&mtr); 03899 03900 while (!fil_addr_is_null(node_addr)) { 03901 03902 for (n = 0; n < FSP_SEG_INODES_PER_PAGE; n++) { 03903 03904 mtr_start(&mtr); 03905 mtr_x_lock(fil_space_get_latch(space), &mtr); 03906 03907 seg_inode_page = fut_get_ptr(space, node_addr, 03908 RW_X_LATCH, &mtr) - FSEG_INODE_PAGE_NODE; 03909 03910 seg_inode = fsp_seg_inode_page_get_nth_inode( 03911 seg_inode_page, n, &mtr); 03912 ut_a(ut_dulint_cmp(mach_read_from_8( 03913 seg_inode + FSEG_ID), 03914 ut_dulint_zero) != 0); 03915 fseg_print_low(seg_inode, &mtr); 03916 03917 n_segs++; 03918 03919 next_node_addr = flst_get_next_addr(seg_inode_page 03920 + FSEG_INODE_PAGE_NODE, &mtr); 03921 mtr_commit(&mtr); 03922 } 03923 03924 node_addr = next_node_addr; 03925 } 03926 03927 mtr_start(&mtr); 03928 mtr_x_lock(fil_space_get_latch(space), &mtr); 03929 03930 header = fsp_get_space_header(space, &mtr); 03931 03932 node_addr = flst_get_first(header + FSP_SEG_INODES_FREE, &mtr); 03933 03934 mtr_commit(&mtr); 03935 03936 while (!fil_addr_is_null(node_addr)) { 03937 03938 for (n = 0; n < FSP_SEG_INODES_PER_PAGE; n++) { 03939 03940 mtr_start(&mtr); 03941 mtr_x_lock(fil_space_get_latch(space), &mtr); 03942 03943 seg_inode_page = fut_get_ptr(space, node_addr, 03944 RW_X_LATCH, &mtr) - FSEG_INODE_PAGE_NODE; 03945 03946 seg_inode = fsp_seg_inode_page_get_nth_inode( 03947 seg_inode_page, n, &mtr); 03948 if (ut_dulint_cmp(mach_read_from_8( 03949 seg_inode + FSEG_ID), 03950 ut_dulint_zero) != 0) { 03951 03952 fseg_print_low(seg_inode, &mtr); 03953 n_segs++; 03954 } 03955 03956 next_node_addr = flst_get_next_addr(seg_inode_page 03957 + FSEG_INODE_PAGE_NODE, &mtr); 03958 mtr_commit(&mtr); 03959 } 03960 03961 node_addr = next_node_addr; 03962 } 03963 03964 mtr_commit(&mtr2); 03965 03966 fprintf(stderr, "NUMBER of file segments: %lu\n", (ulong) n_segs); 03967 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool fsp_reserve_free_extents | ( | ulint * | n_reserved, | |
| ulint | space, | |||
| ulint | n_ext, | |||
| ulint | alloc_type, | |||
| mtr_t * | mtr | |||
| ) |
Definition at line 2712 of file fsp0fsp.c.
References FALSE, fil_space_get_latch(), fil_space_reserve_free_extents(), flst_get_len(), FSP_CLEANING, FSP_EXTENT_SIZE, FSP_FREE, FSP_FREE_LIMIT, fsp_get_space_header(), FSP_NORMAL, fsp_reserve_free_pages(), FSP_SIZE, fsp_try_extend_data_file(), FSP_UNDO, kernel_mutex, MLOG_4BYTES, mtr_memo_contains(), MTR_MEMO_X_LOCK, mtr_read_ulint(), mtr_x_lock, TRUE, ut_a, ut_ad, and XDES_DESCRIBED_PER_PAGE.
Referenced by btr_cur_pessimistic_delete(), btr_cur_pessimistic_insert(), btr_cur_pessimistic_update(), fseg_alloc_free_page_general(), fseg_create_general(), trx_undo_add_page(), and trx_undo_seg_create().
02714 : TRUE if we were able to make the reservation */ 02715 ulint* n_reserved,/* out: number of extents actually reserved; if we 02716 return TRUE and the tablespace size is < 64 pages, 02717 then this can be 0, otherwise it is n_ext */ 02718 ulint space, /* in: space id */ 02719 ulint n_ext, /* in: number of extents to reserve */ 02720 ulint alloc_type,/* in: FSP_NORMAL, FSP_UNDO, or FSP_CLEANING */ 02721 mtr_t* mtr) /* in: mtr */ 02722 { 02723 fsp_header_t* space_header; 02724 rw_lock_t* latch; 02725 ulint n_free_list_ext; 02726 ulint free_limit; 02727 ulint size; 02728 ulint n_free; 02729 ulint n_free_up; 02730 ulint reserve; 02731 ibool success; 02732 ulint n_pages_added; 02733 02734 ut_ad(mtr); 02735 #ifdef UNIV_SYNC_DEBUG 02736 ut_ad(!mutex_own(&kernel_mutex) 02737 || mtr_memo_contains(mtr, fil_space_get_latch(space), 02738 MTR_MEMO_X_LOCK)); 02739 #endif /* UNIV_SYNC_DEBUG */ 02740 *n_reserved = n_ext; 02741 02742 latch = fil_space_get_latch(space); 02743 02744 mtr_x_lock(latch, mtr); 02745 02746 space_header = fsp_get_space_header(space, mtr); 02747 try_again: 02748 size = mtr_read_ulint(space_header + FSP_SIZE, MLOG_4BYTES, mtr); 02749 02750 if (size < FSP_EXTENT_SIZE / 2) { 02751 /* Use different rules for small single-table tablespaces */ 02752 *n_reserved = 0; 02753 return(fsp_reserve_free_pages(space, space_header, size, mtr)); 02754 } 02755 02756 n_free_list_ext = flst_get_len(space_header + FSP_FREE, mtr); 02757 02758 free_limit = mtr_read_ulint(space_header + FSP_FREE_LIMIT, 02759 MLOG_4BYTES, mtr); 02760 02761 /* Below we play safe when counting free extents above the free limit: 02762 some of them will contain extent descriptor pages, and therefore 02763 will not be free extents */ 02764 02765 n_free_up = (size - free_limit) / FSP_EXTENT_SIZE; 02766 02767 if (n_free_up > 0) { 02768 n_free_up--; 02769 n_free_up = n_free_up - n_free_up 02770 / (XDES_DESCRIBED_PER_PAGE / FSP_EXTENT_SIZE); 02771 } 02772 02773 n_free = n_free_list_ext + n_free_up; 02774 02775 if (alloc_type == FSP_NORMAL) { 02776 /* We reserve 1 extent + 0.5 % of the space size to undo logs 02777 and 1 extent + 0.5 % to cleaning operations; NOTE: this source 02778 code is duplicated in the function below! */ 02779 02780 reserve = 2 + ((size / FSP_EXTENT_SIZE) * 2) / 200; 02781 02782 if (n_free <= reserve + n_ext) { 02783 02784 goto try_to_extend; 02785 } 02786 } else if (alloc_type == FSP_UNDO) { 02787 /* We reserve 0.5 % of the space size to cleaning operations */ 02788 02789 reserve = 1 + ((size / FSP_EXTENT_SIZE) * 1) / 200; 02790 02791 if (n_free <= reserve + n_ext) { 02792 02793 goto try_to_extend; 02794 } 02795 } else { 02796 ut_a(alloc_type == FSP_CLEANING); 02797 } 02798 02799 success = fil_space_reserve_free_extents(space, n_free, n_ext); 02800 02801 if (success) { 02802 return(TRUE); 02803 } 02804 try_to_extend: 02805 success = fsp_try_extend_data_file(&n_pages_added, space, 02806 space_header, mtr); 02807 if (success && n_pages_added > 0) { 02808 02809 goto try_again; 02810 } 02811 02812 return(FALSE); 02813 }
Here is the call graph for this function:

Here is the caller graph for this function:

| ibool fsp_validate | ( | ulint | space | ) |
Definition at line 3595 of file fsp0fsp.c.
References fil_addr_is_null(), fil_space_get_latch(), flst_get_first(), flst_get_len(), flst_get_next_addr(), flst_validate(), FSEG_FREE, FSEG_FULL, fseg_get_n_frag_pages(), FSEG_ID, FSEG_INODE_PAGE_NODE, FSEG_NOT_FULL, fseg_validate_low(), FSP_EXTENT_SIZE, FSP_FRAG_N_USED, FSP_FREE, FSP_FREE_FRAG, FSP_FREE_LIMIT, FSP_FULL_FRAG, fsp_get_space_header(), fsp_seg_inode_page_get_nth_inode(), FSP_SEG_INODES_FREE, FSP_SEG_INODES_FULL, FSP_SEG_INODES_PER_PAGE, FSP_SIZE, fut_get_ptr(), mach_read_from_8(), MLOG_4BYTES, mtr_commit(), mtr_read_ulint(), mtr_start(), mtr_x_lock, page_t, RW_X_LATCH, TRUE, ut_a, ut_dulint_cmp(), ut_dulint_zero, XDES_DESCRIBED_PER_PAGE, XDES_FLST_NODE, XDES_FREE, XDES_FREE_FRAG, XDES_FULL_FRAG, xdes_get_n_used(), xdes_get_state(), and xdes_lst_get_descriptor().
Referenced by srv_lock_timeout_and_monitor_thread().
03597 : TRUE if ok */ 03598 ulint space) /* in: space id */ 03599 { 03600 fsp_header_t* header; 03601 fseg_inode_t* seg_inode; 03602 page_t* seg_inode_page; 03603 ulint size; 03604 ulint free_limit; 03605 ulint frag_n_used; 03606 mtr_t mtr; 03607 mtr_t mtr2; 03608 xdes_t* descr; 03609 fil_addr_t node_addr; 03610 fil_addr_t next_node_addr; 03611 ulint descr_count = 0; 03612 ulint n_used = 0; 03613 ulint n_used2 = 0; 03614 ulint n_full_frag_pages; 03615 ulint n; 03616 ulint seg_inode_len_free; 03617 ulint seg_inode_len_full; 03618 03619 /* Start first a mini-transaction mtr2 to lock out all other threads 03620 from the fsp system */ 03621 mtr_start(&mtr2); 03622 mtr_x_lock(fil_space_get_latch(space), &mtr2); 03623 03624 mtr_start(&mtr); 03625 mtr_x_lock(fil_space_get_latch(space), &mtr); 03626 03627 header = fsp_get_space_header(space, &mtr); 03628 03629 size = mtr_read_ulint(header + FSP_SIZE, MLOG_4BYTES, &mtr); 03630 free_limit = mtr_read_ulint(header + FSP_FREE_LIMIT, 03631 MLOG_4BYTES, &mtr); 03632 frag_n_used = mtr_read_ulint(header + FSP_FRAG_N_USED, 03633 MLOG_4BYTES, &mtr); 03634 03635 n_full_frag_pages = FSP_EXTENT_SIZE * 03636 flst_get_len(header + FSP_FULL_FRAG, &mtr); 03637 03638 ut_a(free_limit <= size || (space != 0 && size < FSP_EXTENT_SIZE)); 03639 03640 flst_validate(header + FSP_FREE, &mtr); 03641 flst_validate(header + FSP_FREE_FRAG, &mtr); 03642 flst_validate(header + FSP_FULL_FRAG, &mtr); 03643 03644 mtr_commit(&mtr); 03645 03646 /* Validate FSP_FREE list */ 03647 mtr_start(&mtr); 03648 mtr_x_lock(fil_space_get_latch(space), &mtr); 03649 03650 header = fsp_get_space_header(space, &mtr); 03651 node_addr = flst_get_first(header + FSP_FREE, &mtr); 03652 03653 mtr_commit(&mtr); 03654 03655 while (!fil_addr_is_null(node_addr)) { 03656 mtr_start(&mtr); 03657 mtr_x_lock(fil_space_get_latch(space), &mtr); 03658 03659 descr_count++; 03660 descr = xdes_lst_get_descriptor(space, node_addr, &mtr); 03661 03662 ut_a(xdes_get_n_used(descr, &mtr) == 0); 03663 ut_a(xdes_get_state(descr, &mtr) == XDES_FREE); 03664 03665 node_addr = flst_get_next_addr(descr + XDES_FLST_NODE, &mtr); 03666 mtr_commit(&mtr); 03667 } 03668 03669 /* Validate FSP_FREE_FRAG list */ 03670 mtr_start(&mtr); 03671 mtr_x_lock(fil_space_get_latch(space), &mtr); 03672 03673 header = fsp_get_space_header(space, &mtr); 03674 node_addr = flst_get_first(header + FSP_FREE_FRAG, &mtr); 03675 03676 mtr_commit(&mtr); 03677 03678 while (!fil_addr_is_null(node_addr)) { 03679 mtr_start(&mtr); 03680 mtr_x_lock(fil_space_get_latch(space), &mtr); 03681 03682 descr_count++; 03683 descr = xdes_lst_get_descriptor(space, node_addr, &mtr); 03684 03685 ut_a(xdes_get_n_used(descr, &mtr) > 0); 03686 ut_a(xdes_get_n_used(descr, &mtr) < FSP_EXTENT_SIZE); 03687 ut_a(xdes_get_state(descr, &mtr) == XDES_FREE_FRAG); 03688 03689 n_used += xdes_get_n_used(descr, &mtr); 03690 node_addr = flst_get_next_addr(descr + XDES_FLST_NODE, &mtr); 03691 03692 mtr_commit(&mtr); 03693 } 03694 03695 /* Validate FSP_FULL_FRAG list */ 03696 mtr_start(&mtr); 03697 mtr_x_lock(fil_space_get_latch(space), &mtr); 03698 03699 header = fsp_get_space_header(space, &mtr); 03700 node_addr = flst_get_first(header + FSP_FULL_FRAG, &mtr); 03701 03702 mtr_commit(&mtr); 03703 03704 while (!fil_addr_is_null(node_addr)) { 03705 mtr_start(&mtr); 03706 mtr_x_lock(fil_space_get_latch(space), &mtr); 03707 03708 descr_count++; 03709 descr = xdes_lst_get_descriptor(space, node_addr, &mtr); 03710 03711 ut_a(xdes_get_n_used(descr, &mtr) == FSP_EXTENT_SIZE); 03712 ut_a(xdes_get_state(descr, &mtr) == XDES_FULL_FRAG); 03713 03714 node_addr = flst_get_next_addr(descr + XDES_FLST_NODE, &mtr); 03715 mtr_commit(&mtr); 03716 } 03717 03718 /* Validate segments */ 03719 mtr_start(&mtr); 03720 mtr_x_lock(fil_space_get_latch(space), &mtr); 03721 03722 header = fsp_get_space_header(space, &mtr); 03723 03724 node_addr = flst_get_first(header + FSP_SEG_INODES_FULL, &mtr); 03725 03726 seg_inode_len_full = flst_get_len(header + FSP_SEG_INODES_FULL, &mtr); 03727 03728 mtr_commit(&mtr); 03729 03730 while (!fil_addr_is_null(node_addr)) { 03731 03732 for (n = 0; n < FSP_SEG_INODES_PER_PAGE; n++) { 03733 03734 mtr_start(&mtr); 03735 mtr_x_lock(fil_space_get_latch(space), &mtr); 03736 03737 seg_inode_page = fut_get_ptr(space, node_addr, 03738 RW_X_LATCH, &mtr) - FSEG_INODE_PAGE_NODE; 03739 03740 seg_inode = fsp_seg_inode_page_get_nth_inode( 03741 seg_inode_page, n, &mtr); 03742 ut_a(ut_dulint_cmp( 03743 mach_read_from_8(seg_inode + FSEG_ID), 03744 ut_dulint_zero) != 0); 03745 fseg_validate_low(seg_inode, &mtr); 03746 03747 descr_count += flst_get_len(seg_inode + FSEG_FREE, 03748 &mtr); 03749 descr_count += flst_get_len(seg_inode + FSEG_FULL, 03750 &mtr); 03751 descr_count += flst_get_len(seg_inode + FSEG_NOT_FULL, 03752 &mtr); 03753 03754 n_used2 += fseg_get_n_frag_pages(seg_inode, &mtr); 03755 03756 next_node_addr = flst_get_next_addr(seg_inode_page 03757 + FSEG_INODE_PAGE_NODE, &mtr); 03758 mtr_commit(&mtr); 03759 } 03760 03761 node_addr = next_node_addr; 03762 } 03763 03764 mtr_start(&mtr); 03765 mtr_x_lock(fil_space_get_latch(space), &mtr); 03766 03767 header = fsp_get_space_header(space, &mtr); 03768 03769 node_addr = flst_get_first(header + FSP_SEG_INODES_FREE, &mtr); 03770 03771 seg_inode_len_free = flst_get_len(header + FSP_SEG_INODES_FREE, &mtr); 03772 03773 mtr_commit(&mtr); 03774 03775 while (!fil_addr_is_null(node_addr)) { 03776 03777 for (n = 0; n < FSP_SEG_INODES_PER_PAGE; n++) { 03778 03779 mtr_start(&mtr); 03780 mtr_x_lock(fil_space_get_latch(space), &mtr); 03781 03782 seg_inode_page = fut_get_ptr(space, node_addr, 03783 RW_X_LATCH, &mtr) - FSEG_INODE_PAGE_NODE; 03784 03785 seg_inode = fsp_seg_inode_page_get_nth_inode( 03786 seg_inode_page, n, &mtr); 03787 if (ut_dulint_cmp(mach_read_from_8( 03788 seg_inode + FSEG_ID), 03789 ut_dulint_zero) != 0) { 03790 fseg_validate_low(seg_inode, &mtr); 03791 03792 descr_count += flst_get_len( 03793 seg_inode + FSEG_FREE, &mtr); 03794 descr_count += flst_get_len( 03795 seg_inode + FSEG_FULL, &mtr); 03796 descr_count += flst_get_len( 03797 seg_inode + FSEG_NOT_FULL, &mtr); 03798 n_used2 += fseg_get_n_frag_pages( 03799 seg_inode, &mtr); 03800 } 03801 03802 next_node_addr = flst_get_next_addr(seg_inode_page 03803 + FSEG_INODE_PAGE_NODE, &mtr); 03804 mtr_commit(&mtr); 03805 } 03806 03807 node_addr = next_node_addr; 03808 } 03809 03810 ut_a(descr_count * FSP_EXTENT_SIZE == free_limit); 03811 ut_a(n_used + n_full_frag_pages 03812 == n_used2 + 2* ((free_limit + XDES_DESCRIBED_PER_PAGE - 1) 03813 / XDES_DESCRIBED_PER_PAGE) 03814 + seg_inode_len_full + seg_inode_len_free); 03815 ut_a(frag_n_used == n_used); 03816 03817 mtr_commit(&mtr2); 03818 03819 return(TRUE); 03820 }
Here is the call graph for this function:

Here is the caller graph for this function:

1.4.7

