diff options
Diffstat (limited to 'storage/xtradb/fsp/fsp0fsp.c')
-rw-r--r-- | storage/xtradb/fsp/fsp0fsp.c | 218 |
1 files changed, 123 insertions, 95 deletions
diff --git a/storage/xtradb/fsp/fsp0fsp.c b/storage/xtradb/fsp/fsp0fsp.c index cd28186109f..5e3959a3c7f 100644 --- a/storage/xtradb/fsp/fsp0fsp.c +++ b/storage/xtradb/fsp/fsp0fsp.c @@ -127,9 +127,8 @@ typedef byte fseg_inode_t; #define FSEG_ARR_OFFSET (FSEG_PAGE_DATA + FLST_NODE_SIZE) /*-------------------------------------*/ -#define FSEG_ID 0 /* 8 bytes of segment id: if this is - ut_dulint_zero, it means that the - header is unused */ +#define FSEG_ID 0 /* 8 bytes of segment id: if this is 0, + it means that the header is unused */ #define FSEG_NOT_FULL_N_USED 8 /* number of used segment pages in the FSEG_NOT_FULL list */ @@ -657,13 +656,18 @@ xdes_calc_descriptor_page( 0 for uncompressed pages */ ulint offset) /*!< in: page offset */ { -#ifndef DOXYGEN /* Doxygen gets confused of these */ -# if PAGE_ZIP_MIN_SIZE <= XDES_ARR_OFFSET \ - + (PAGE_ZIP_MIN_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE -# error -# endif -#endif /* !DOXYGEN */ +//#ifndef DOXYGEN /* Doxygen gets confused of these */ +//# if UNIV_PAGE_SIZE <= XDES_ARR_OFFSET +// + (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE +//# error +//# endif +//# if PAGE_ZIP_MIN_SIZE <= XDES_ARR_OFFSET +// + (PAGE_ZIP_MIN_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE +//# error +//# endif +//#endif /* !DOXYGEN */ ut_a(UNIV_PAGE_SIZE > XDES_ARR_OFFSET + (UNIV_PAGE_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE); + ut_a(PAGE_ZIP_MIN_SIZE > XDES_ARR_OFFSET + (PAGE_ZIP_MIN_SIZE / FSP_EXTENT_SIZE) * XDES_SIZE); ut_ad(ut_is_2pow(zip_size)); if (!zip_size) { @@ -1008,11 +1012,11 @@ fsp_header_init( 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); + mlog_write_ull(header + FSP_SEG_ID, 1, mtr); if (space == TRX_SYS_SPACE || space == TRX_DOUBLEWRITE_SPACE) { fsp_fill_free_list(FALSE, space, header, mtr); btr_create(DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, - space, 0, ut_dulint_add(DICT_IBUF_ID_MIN, space), + space, 0, DICT_IBUF_ID_MIN + space, dict_ind_redundant, mtr); } else { fsp_fill_free_list(TRUE, space, header, mtr); @@ -1850,7 +1854,7 @@ fsp_seg_inode_page_find_used( inode = fsp_seg_inode_page_get_nth_inode( page, i, zip_size, mtr); - if (!ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))) { + if (mach_read_from_8(inode + FSEG_ID)) { /* This is used */ ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) @@ -1886,7 +1890,7 @@ fsp_seg_inode_page_find_free( inode = fsp_seg_inode_page_get_nth_inode( page, i, zip_size, mtr); - if (ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID))) { + if (!mach_read_from_8(inode + FSEG_ID)) { /* This is unused */ return(i); @@ -1945,7 +1949,7 @@ fsp_alloc_seg_inode_page( inode = fsp_seg_inode_page_get_nth_inode(page, i, zip_size, mtr); - mlog_write_dulint(inode + FSEG_ID, ut_dulint_zero, mtr); + mlog_write_ull(inode + FSEG_ID, 0, mtr); } flst_add_last(space_header + FSP_SEG_INODES_FREE, @@ -2017,7 +2021,7 @@ fsp_alloc_seg_inode( page + FSEG_INODE_PAGE_NODE, mtr); } - ut_ad(ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID)) + ut_ad(!mach_read_from_8(inode + FSEG_ID) || mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); return(inode); } @@ -2055,7 +2059,7 @@ fsp_free_seg_inode( page + FSEG_INODE_PAGE_NODE, mtr); } - mlog_write_dulint(inode + FSEG_ID, ut_dulint_zero, mtr); + mlog_write_ull(inode + FSEG_ID, 0, mtr); mlog_write_ulint(inode + FSEG_MAGIC_N, 0xfa051ce3, MLOG_4BYTES, mtr); if (ULINT_UNDEFINED @@ -2097,8 +2101,7 @@ fseg_inode_try_get( } ut_a(inode); - if (UNIV_UNLIKELY - (ut_dulint_is_zero(mach_read_from_8(inode + FSEG_ID)))) { + if (UNIV_UNLIKELY(!mach_read_from_8(inode + FSEG_ID))) { inode = NULL; } else { @@ -2273,7 +2276,7 @@ fseg_create_general( ulint zip_size; fsp_header_t* space_header; fseg_inode_t* inode; - dulint seg_id; + ib_id_t seg_id; buf_block_t* block = 0; /* remove warning */ fseg_header_t* header = 0; /* remove warning */ rw_lock_t* latch; @@ -2327,12 +2330,11 @@ fseg_create_general( /* Read the next segment id from space header and increment the value in space header */ - seg_id = mtr_read_dulint(space_header + FSP_SEG_ID, mtr); + seg_id = mach_read_from_8(space_header + FSP_SEG_ID); - mlog_write_dulint(space_header + FSP_SEG_ID, ut_dulint_add(seg_id, 1), - mtr); + mlog_write_ull(space_header + FSP_SEG_ID, seg_id + 1, mtr); - mlog_write_dulint(inode + FSEG_ID, seg_id, mtr); + mlog_write_ull(inode + FSEG_ID, seg_id, mtr); mlog_write_ulint(inode + FSEG_NOT_FULL_N_USED, 0, MLOG_4BYTES, mtr); flst_init(inode + FSEG_FREE, mtr); @@ -2484,7 +2486,7 @@ fseg_fill_free_list( { xdes_t* descr; ulint i; - dulint seg_id; + ib_id_t seg_id; ulint reserved; ulint used; @@ -2521,10 +2523,10 @@ fseg_fill_free_list( xdes_set_state(descr, XDES_FSEG, mtr); - seg_id = mtr_read_dulint(inode + FSEG_ID, mtr); + seg_id = mach_read_from_8(inode + FSEG_ID); ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); - mlog_write_dulint(descr + XDES_ID, seg_id, mtr); + mlog_write_ull(descr + XDES_ID, seg_id, mtr); flst_add_last(inode + FSEG_FREE, descr + XDES_FLST_NODE, mtr); hint += FSP_EXTENT_SIZE; @@ -2548,7 +2550,7 @@ fseg_alloc_free_extent( mtr_t* mtr) /*!< in: mtr */ { xdes_t* descr; - dulint seg_id; + ib_id_t seg_id; fil_addr_t first; ut_ad(!((page_offset(inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE)); @@ -2569,10 +2571,10 @@ fseg_alloc_free_extent( return(NULL); } - seg_id = mtr_read_dulint(inode + FSEG_ID, mtr); + seg_id = mach_read_from_8(inode + FSEG_ID); xdes_set_state(descr, XDES_FSEG, mtr); - mlog_write_dulint(descr + XDES_ID, seg_id, mtr); + mlog_write_ull(descr + XDES_ID, seg_id, mtr); flst_add_last(inode + FSEG_FREE, descr + XDES_FLST_NODE, mtr); /* Try to fill the segment free list */ @@ -2607,7 +2609,7 @@ fseg_alloc_free_page_low( { fsp_header_t* space_header; ulint space_size; - dulint seg_id; + ib_id_t seg_id; ulint used; ulint reserved; xdes_t* descr; /*!< extent of the hinted page */ @@ -2623,9 +2625,9 @@ fseg_alloc_free_page_low( ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); ut_ad(!((page_offset(seg_inode) - FSEG_ARR_OFFSET) % FSEG_INODE_SIZE)); - seg_id = mtr_read_dulint(seg_inode + FSEG_ID, mtr); + seg_id = mach_read_from_8(seg_inode + FSEG_ID); - ut_ad(!ut_dulint_is_zero(seg_id)); + ut_ad(seg_id); reserved = fseg_n_reserved_pages_low(seg_inode, &used, mtr); @@ -2643,8 +2645,7 @@ fseg_alloc_free_page_low( /* In the big if-else below we look for ret_page and ret_descr */ /*-------------------------------------------------------------*/ if ((xdes_get_state(descr, mtr) == XDES_FSEG) - && (0 == ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, - mtr), seg_id)) + && mach_read_from_8(descr + XDES_ID) == seg_id && (xdes_get_bit(descr, XDES_FREE_BIT, hint % FSP_EXTENT_SIZE, mtr) == TRUE)) { @@ -2666,7 +2667,7 @@ fseg_alloc_free_page_low( ut_a(ret_descr == descr); xdes_set_state(ret_descr, XDES_FSEG, mtr); - mlog_write_dulint(ret_descr + XDES_ID, seg_id, mtr); + mlog_write_ull(ret_descr + XDES_ID, seg_id, mtr); flst_add_last(seg_inode + FSEG_FREE, ret_descr + XDES_FLST_NODE, mtr); @@ -2695,8 +2696,7 @@ fseg_alloc_free_page_low( } /*-----------------------------------------------------------*/ } else if ((xdes_get_state(descr, mtr) == XDES_FSEG) - && (0 == ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, - mtr), seg_id)) + && mach_read_from_8(descr + XDES_ID) == seg_id && (!xdes_is_full(descr, mtr))) { /* 4. We can take the page from the same extent as the @@ -3126,13 +3126,63 @@ fsp_get_available_space_in_free_extents( ut_ad(!mutex_own(&kernel_mutex)); + /* The convoluted mutex acquire is to overcome latching order + issues: The problem is that the fil_mutex is at a lower level + than the tablespace latch and the buffer pool mutex. We have to + first prevent any operations on the file system by acquiring the + dictionary mutex. Then acquire the tablespace latch to obey the + latching order and then release the dictionary mutex. That way we + ensure that the tablespace instance can't be freed while we are + examining its contents (see fil_space_free()). + + However, there is one further complication, we release the fil_mutex + when we need to invalidate the the pages in the buffer pool and we + reacquire the fil_mutex when deleting and freeing the tablespace + instance in fil0fil.c. Here we need to account for that situation + too. */ + + mutex_enter(&dict_sys->mutex); + + /* At this stage there is no guarantee that the tablespace even + exists in the cache. */ + + if (fil_tablespace_deleted_or_being_deleted_in_mem(space, -1)) { + + mutex_exit(&dict_sys->mutex); + + return(ULLINT_UNDEFINED); + } + mtr_start(&mtr); latch = fil_space_get_latch(space, &flags); + + /* This should ensure that the tablespace instance can't be freed + by another thread. However, the tablespace pages can still be freed + from the buffer pool. We need to check for that again. */ + zip_size = dict_table_flags_to_zip_size(flags); mtr_x_lock(latch, &mtr); + mutex_exit(&dict_sys->mutex); + + /* At this point it is possible for the tablespace to be deleted and + its pages removed from the buffer pool. We need to check for that + situation. However, the tablespace instance can't be deleted because + our latching above should ensure that. */ + + if (fil_tablespace_is_being_deleted(space)) { + + mtr_commit(&mtr); + + return(ULLINT_UNDEFINED); + } + + /* From here on even if the user has dropped the tablespace, the + pages _must_ still exist in the buffer pool and the tablespace + instance _must_ be in the file system hash table. */ + space_header = fsp_get_space_header(space, zip_size, &mtr); size = mtr_read_ulint(space_header + FSP_SIZE, MLOG_4BYTES, &mtr); @@ -3267,8 +3317,8 @@ fseg_free_page_low( xdes_t* descr; ulint not_full_n_used; ulint state; - dulint descr_id; - dulint seg_id; + ib_id_t descr_id; + ib_id_t seg_id; ulint i; ut_ad(seg_inode && mtr); @@ -3305,7 +3355,7 @@ fseg_free_page_low( "InnoDB: database!\n", (ulong) page); crash: fputs("InnoDB: Please refer to\n" - "InnoDB: " REFMAN "forcing-recovery.html\n" + "InnoDB: " REFMAN "forcing-innodb-recovery.html\n" "InnoDB: about forcing recovery.\n", stderr); ut_error; } @@ -3332,20 +3382,18 @@ crash: /* If we get here, the page is in some extent of the segment */ - descr_id = mtr_read_dulint(descr + XDES_ID, mtr); - seg_id = mtr_read_dulint(seg_inode + FSEG_ID, mtr); + descr_id = mach_read_from_8(descr + XDES_ID); + seg_id = mach_read_from_8(seg_inode + FSEG_ID); #if 0 fprintf(stderr, "InnoDB: InnoDB is freeing space %lu page %lu,\n" - "InnoDB: which belongs to descr seg %lu %lu\n" - "InnoDB: segment %lu %lu.\n", + "InnoDB: which belongs to descr seg %llu\n" + "InnoDB: segment %llu.\n", (ulong) space, (ulong) page, - (ulong) ut_dulint_get_high(descr_id), - (ulong) ut_dulint_get_low(descr_id), - (ulong) ut_dulint_get_high(seg_id), - (ulong) ut_dulint_get_low(seg_id)); + (ullint) descr_id, + (ullint) seg_id); #endif /* 0 */ - if (0 != ut_dulint_cmp(descr_id, seg_id)) { + if (UNIV_UNLIKELY(descr_id != seg_id)) { fputs("InnoDB: Dump of the tablespace extent descriptor: ", stderr); ut_print_buf(stderr, descr, 40); @@ -3357,13 +3405,11 @@ crash: "InnoDB: Serious error: InnoDB is trying to" " free space %lu page %lu,\n" "InnoDB: which does not belong to" - " segment %lu %lu but belongs\n" - "InnoDB: to segment %lu %lu.\n", + " segment %llu but belongs\n" + "InnoDB: to segment %llu.\n", (ulong) space, (ulong) page, - (ulong) ut_dulint_get_high(descr_id), - (ulong) ut_dulint_get_low(descr_id), - (ulong) ut_dulint_get_high(seg_id), - (ulong) ut_dulint_get_low(seg_id)); + (ullint) descr_id, + (ullint) seg_id); goto crash; } @@ -3423,9 +3469,9 @@ fseg_free_page( fseg_free_page_low(seg_inode, space, zip_size, page, mtr); -#ifdef UNIV_DEBUG_FILE_ACCESSES +#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG buf_page_set_file_page_was_freed(space, page); -#endif +#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */ } /**********************************************************************//** @@ -3452,8 +3498,7 @@ fseg_free_extent( descr = xdes_get_descriptor(space, zip_size, page, mtr); ut_a(xdes_get_state(descr, mtr) == XDES_FSEG); - ut_a(0 == ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, mtr), - mtr_read_dulint(seg_inode + FSEG_ID, mtr))); + ut_a(!memcmp(descr + XDES_ID, seg_inode + FSEG_ID, 8)); ut_ad(mach_read_from_4(seg_inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE); @@ -3492,13 +3537,13 @@ fseg_free_extent( fsp_free_extent(space, zip_size, page, mtr); -#ifdef UNIV_DEBUG_FILE_ACCESSES +#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG for (i = 0; i < FSP_EXTENT_SIZE; i++) { buf_page_set_file_page_was_freed(space, first_page_in_extent + i); } -#endif +#endif /* UNIV_DEBUG_FILE_ACCESSES || UNIV_DEBUG */ } /**********************************************************************//** @@ -3724,7 +3769,7 @@ fseg_validate_low( mtr_t* mtr2) /*!< in: mtr */ { ulint space; - dulint seg_id; + ib_id_t seg_id; mtr_t mtr; xdes_t* descr; fil_addr_t node_addr; @@ -3736,7 +3781,7 @@ fseg_validate_low( space = page_get_space_id(page_align(inode)); - seg_id = mtr_read_dulint(inode + FSEG_ID, mtr2); + seg_id = mach_read_from_8(inode + FSEG_ID); n_used = mtr_read_ulint(inode + FSEG_NOT_FULL_N_USED, MLOG_4BYTES, mtr2); flst_validate(inode + FSEG_FREE, mtr2); @@ -3759,8 +3804,7 @@ fseg_validate_low( ut_a(xdes_get_n_used(descr, &mtr) == 0); ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG); - ut_a(!ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, &mtr), - seg_id)); + ut_a(mach_read_from_8(descr + XDES_ID) == seg_id); node_addr = flst_get_next_addr(descr + XDES_FLST_NODE, &mtr); mtr_commit(&mtr); @@ -3784,8 +3828,7 @@ fseg_validate_low( ut_a(xdes_get_n_used(descr, &mtr) > 0); ut_a(xdes_get_n_used(descr, &mtr) < FSP_EXTENT_SIZE); ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG); - ut_a(!ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, &mtr), - seg_id)); + ut_a(mach_read_from_8(descr + XDES_ID) == seg_id); n_used2 += xdes_get_n_used(descr, &mtr); @@ -3810,8 +3853,7 @@ fseg_validate_low( ut_a(xdes_get_n_used(descr, &mtr) == FSP_EXTENT_SIZE); ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG); - ut_a(!ut_dulint_cmp(mtr_read_dulint(descr + XDES_ID, &mtr), - seg_id)); + ut_a(mach_read_from_8(descr + XDES_ID) == seg_id); node_addr = flst_get_next_addr(descr + XDES_FLST_NODE, &mtr); mtr_commit(&mtr); @@ -3862,8 +3904,6 @@ fseg_print_low( mtr_t* mtr) /*!< in: mtr */ { ulint space; - ulint seg_id_low; - ulint seg_id_high; ulint n_used; ulint n_frag; ulint n_free; @@ -3872,7 +3912,7 @@ fseg_print_low( ulint reserved; ulint used; ulint page_no; - dulint d_var; + ib_id_t seg_id; ut_ad(mtr_memo_contains_page(mtr, inode, MTR_MEMO_PAGE_X_FIX)); space = page_get_space_id(page_align(inode)); @@ -3880,10 +3920,7 @@ fseg_print_low( reserved = fseg_n_reserved_pages_low(inode, &used, mtr); - d_var = mtr_read_dulint(inode + FSEG_ID, mtr); - - seg_id_low = ut_dulint_get_low(d_var); - seg_id_high = ut_dulint_get_high(d_var); + seg_id = mach_read_from_8(inode + FSEG_ID); n_used = mtr_read_ulint(inode + FSEG_NOT_FULL_N_USED, MLOG_4BYTES, mtr); @@ -3893,11 +3930,11 @@ fseg_print_low( n_full = flst_get_len(inode + FSEG_FULL, mtr); fprintf(stderr, - "SEGMENT id %lu %lu space %lu; page %lu;" + "SEGMENT id %llu space %lu; page %lu;" " res %lu used %lu; full ext %lu\n" "fragm pages %lu; free extents %lu;" " not full extents %lu: pages %lu\n", - (ulong) seg_id_high, (ulong) seg_id_low, + (ullint) seg_id, (ulong) space, (ulong) page_no, (ulong) reserved, (ulong) used, (ulong) n_full, (ulong) n_frag, (ulong) n_free, (ulong) n_not_full, @@ -4099,8 +4136,7 @@ fsp_validate( seg_inode = fsp_seg_inode_page_get_nth_inode( seg_inode_page, n, zip_size, &mtr); - ut_a(!ut_dulint_is_zero( - mach_read_from_8(seg_inode + FSEG_ID))); + ut_a(mach_read_from_8(seg_inode + FSEG_ID) != 0); fseg_validate_low(seg_inode, &mtr); descr_count += flst_get_len(seg_inode + FSEG_FREE, @@ -4145,8 +4181,7 @@ fsp_validate( seg_inode = fsp_seg_inode_page_get_nth_inode( seg_inode_page, n, zip_size, &mtr); - if (!ut_dulint_is_zero( - mach_read_from_8(seg_inode + FSEG_ID))) { + if (mach_read_from_8(seg_inode + FSEG_ID)) { fseg_validate_low(seg_inode, &mtr); descr_count += flst_get_len( @@ -4208,11 +4243,9 @@ fsp_print( ulint n_free; ulint n_free_frag; ulint n_full_frag; - ulint seg_id_low; - ulint seg_id_high; + ib_id_t seg_id; ulint n; ulint n_segs = 0; - dulint d_var; mtr_t mtr; mtr_t mtr2; @@ -4242,21 +4275,18 @@ fsp_print( n_free_frag = flst_get_len(header + FSP_FREE_FRAG, &mtr); n_full_frag = flst_get_len(header + FSP_FULL_FRAG, &mtr); - d_var = mtr_read_dulint(header + FSP_SEG_ID, &mtr); - - seg_id_low = ut_dulint_get_low(d_var); - seg_id_high = ut_dulint_get_high(d_var); + seg_id = mach_read_from_8(header + FSP_SEG_ID); fprintf(stderr, "FILE SPACE INFO: id %lu\n" "size %lu, free limit %lu, free extents %lu\n" "not full frag extents %lu: used pages %lu," " full frag extents %lu\n" - "first seg id not used %lu %lu\n", + "first seg id not used %llu\n", (ulong) space, (ulong) size, (ulong) free_limit, (ulong) n_free, (ulong) n_free_frag, (ulong) frag_n_used, (ulong) n_full_frag, - (ulong) seg_id_high, (ulong) seg_id_low); + (ullint) seg_id); mtr_commit(&mtr); @@ -4286,8 +4316,7 @@ fsp_print( seg_inode = fsp_seg_inode_page_get_nth_inode( seg_inode_page, n, zip_size, &mtr); - ut_a(!ut_dulint_is_zero( - mach_read_from_8(seg_inode + FSEG_ID))); + ut_a(mach_read_from_8(seg_inode + FSEG_ID) != 0); fseg_print_low(seg_inode, &mtr); n_segs++; @@ -4324,8 +4353,7 @@ fsp_print( seg_inode = fsp_seg_inode_page_get_nth_inode( seg_inode_page, n, zip_size, &mtr); - if (!ut_dulint_is_zero( - mach_read_from_8(seg_inode + FSEG_ID))) { + if (mach_read_from_8(seg_inode + FSEG_ID)) { fseg_print_low(seg_inode, &mtr); n_segs++; |