diff options
author | Marko Mäkelä <marko.makela@oracle.com> | 2011-10-26 11:44:28 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@oracle.com> | 2011-10-26 11:44:28 +0300 |
commit | 1885f3720ff8d85e2a38aded6c85c81cc1d600c0 (patch) | |
tree | 644aa74ed246e7c4530392e1c9e24800dbfdfdc9 /storage/innobase/fsp/fsp0fsp.c | |
parent | d653549ecc82bac7a492dceb5e4dd2bbed5be4f6 (diff) | |
download | mariadb-git-1885f3720ff8d85e2a38aded6c85c81cc1d600c0.tar.gz |
Revert most of revno 3560.9.1 (Bug#12704861)
This was an attempt to address problems with the Bug#12612184 fix.
Even with this follow-up fix, crash recovery can be broken.
Let us fix the bug later.
Diffstat (limited to 'storage/innobase/fsp/fsp0fsp.c')
-rw-r--r-- | storage/innobase/fsp/fsp0fsp.c | 159 |
1 files changed, 47 insertions, 112 deletions
diff --git a/storage/innobase/fsp/fsp0fsp.c b/storage/innobase/fsp/fsp0fsp.c index d5be8fca38f..90e6ad34a9a 100644 --- a/storage/innobase/fsp/fsp0fsp.c +++ b/storage/innobase/fsp/fsp0fsp.c @@ -300,12 +300,8 @@ fseg_alloc_free_page_low( inserted there in order, into which direction they go alphabetically: FSP_DOWN, FSP_UP, FSP_NO_DIR */ - mtr_t* mtr, /* in/out: mini-transaction */ - mtr_t* init_mtr);/* in/out: mini-transaction in which the - page should be initialized - (may be the same as mtr), or NULL if it - should not be initialized (the page at hint - was previously freed in mtr) */ + mtr_t* mtr); /* in/out: mini-transaction */ + /************************************************************************** Reads the file space size stored in the header page. */ @@ -1375,43 +1371,6 @@ fsp_alloc_free_extent( return(descr); } -/**********************************************************************//** -Allocates a single free page from a space. */ -static __attribute__((nonnull)) -void -fsp_alloc_from_free_frag( -/*=====================*/ - fsp_header_t* header, /* in/out: tablespace header */ - xdes_t* descr, /* in/out: extent descriptor */ - ulint bit, /* in: slot to allocate in the extent */ - mtr_t* mtr) /* in/out: mini-transaction */ -{ - ulint frag_n_used; - - ut_ad(xdes_get_state(descr, mtr) == XDES_FREE_FRAG); - ut_a(xdes_get_bit(descr, XDES_FREE_BIT, bit, mtr)); - xdes_set_bit(descr, XDES_FREE_BIT, bit, FALSE, mtr); - - /* Update the FRAG_N_USED field */ - frag_n_used = mtr_read_ulint(header + FSP_FRAG_N_USED, MLOG_4BYTES, - mtr); - frag_n_used++; - mlog_write_ulint(header + FSP_FRAG_N_USED, frag_n_used, MLOG_4BYTES, - mtr); - if (xdes_is_full(descr, mtr)) { - /* The fragment is full: move it to another list */ - flst_remove(header + FSP_FREE_FRAG, descr + XDES_FLST_NODE, - mtr); - xdes_set_state(descr, XDES_FULL_FRAG, mtr); - - flst_add_last(header + FSP_FULL_FRAG, descr + XDES_FLST_NODE, - mtr); - mlog_write_ulint(header + FSP_FRAG_N_USED, - frag_n_used - FSP_EXTENT_SIZE, MLOG_4BYTES, - mtr); - } -} - /************************************************************************** Allocates a single free page from a space. The page is marked as used. */ static @@ -1422,22 +1381,19 @@ fsp_alloc_free_page( be allocated */ ulint space, /* in: space id */ ulint hint, /* in: hint of which page would be desirable */ - mtr_t* mtr, /* in/out: mini-transaction */ - mtr_t* init_mtr)/* in/out: mini-transaction in which the - page should be initialized - (may be the same as mtr) */ + mtr_t* mtr) /* in/out: mini-transaction */ { fsp_header_t* header; fil_addr_t first; xdes_t* descr; page_t* page; ulint free; + ulint frag_n_used; ulint page_no; ulint space_size; ibool success; ut_ad(mtr); - ut_ad(init_mtr); header = fsp_get_space_header(space, mtr); @@ -1517,21 +1473,40 @@ fsp_alloc_free_page( } } - fsp_alloc_from_free_frag(header, descr, free, mtr); + xdes_set_bit(descr, XDES_FREE_BIT, free, FALSE, mtr); + + /* Update the FRAG_N_USED field */ + frag_n_used = mtr_read_ulint(header + FSP_FRAG_N_USED, MLOG_4BYTES, + mtr); + frag_n_used++; + mlog_write_ulint(header + FSP_FRAG_N_USED, frag_n_used, MLOG_4BYTES, + mtr); + if (xdes_is_full(descr, mtr)) { + /* The fragment is full: move it to another list */ + flst_remove(header + FSP_FREE_FRAG, descr + XDES_FLST_NODE, + mtr); + xdes_set_state(descr, XDES_FULL_FRAG, mtr); + + flst_add_last(header + FSP_FULL_FRAG, descr + XDES_FLST_NODE, + mtr); + mlog_write_ulint(header + FSP_FRAG_N_USED, + frag_n_used - FSP_EXTENT_SIZE, MLOG_4BYTES, + mtr); + } /* Initialize the allocated page to the buffer pool, so that it can be obtained immediately with buf_page_get without need for a disk read. */ - buf_page_create(space, page_no, init_mtr); + buf_page_create(space, page_no, mtr); - page = buf_page_get(space, page_no, RW_X_LATCH, init_mtr); + page = buf_page_get(space, page_no, RW_X_LATCH, mtr); #ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(page, SYNC_FSP_PAGE); #endif /* UNIV_SYNC_DEBUG */ /* Prior contents of the page should be ignored */ - fsp_init_file_page(page, init_mtr); + fsp_init_file_page(page, mtr); return(page_no); } @@ -1750,7 +1725,7 @@ fsp_alloc_seg_inode_page( space = buf_frame_get_space_id(space_header); - page_no = fsp_alloc_free_page(space, 0, mtr, mtr); + page_no = fsp_alloc_free_page(space, 0, mtr); if (page_no == FIL_NULL) { @@ -2120,8 +2095,7 @@ fseg_create_general( } if (page == 0) { - page = fseg_alloc_free_page_low(space, - inode, 0, FSP_UP, mtr, mtr); + page = fseg_alloc_free_page_low(space, inode, 0, FSP_UP, mtr); if (page == FIL_NULL) { @@ -2365,12 +2339,7 @@ fseg_alloc_free_page_low( inserted there in order, into which direction they go alphabetically: FSP_DOWN, FSP_UP, FSP_NO_DIR */ - mtr_t* mtr, /* in/out: mini-transaction */ - mtr_t* init_mtr)/* in/out: mini-transaction in which the - page should be initialized - (may be the same as mtr), or NULL if it - should not be initialized (the page at hint - was previously freed in mtr) */ + mtr_t* mtr) /* in/out: mini-transaction */ { fsp_header_t* space_header; ulint space_size; @@ -2382,6 +2351,7 @@ fseg_alloc_free_page_low( if could not be allocated */ xdes_t* ret_descr; /* the extent of the allocated page */ page_t* page; + ibool frag_page_allocated = FALSE; ibool success; ulint n; @@ -2402,8 +2372,6 @@ fseg_alloc_free_page_low( if (descr == NULL) { /* Hint outside space or too high above free limit: reset hint */ - ut_a(init_mtr); - /* The file space header page is always allocated. */ hint = 0; descr = xdes_get_descriptor(space, hint, mtr); } @@ -2415,20 +2383,15 @@ fseg_alloc_free_page_low( mtr), seg_id)) && (xdes_get_bit(descr, XDES_FREE_BIT, hint % FSP_EXTENT_SIZE, mtr) == TRUE)) { -take_hinted_page: + /* 1. We can take the hinted page =================================*/ ret_descr = descr; ret_page = hint; - /* Skip the check for extending the tablespace. If the - page hint were not within the size of the tablespace, - we would have got (descr == NULL) above and reset the hint. */ - goto got_hinted_page; /*-----------------------------------------------------------*/ - } else if (xdes_get_state(descr, mtr) == XDES_FREE - && (!init_mtr - || ((reserved - used < reserved / FSEG_FILLFACTOR) - && used >= FSEG_FRAG_LIMIT))) { + } else if ((xdes_get_state(descr, mtr) == XDES_FREE) + && ((reserved - used) < reserved / FSEG_FILLFACTOR) + && (used >= FSEG_FRAG_LIMIT)) { /* 2. We allocate the free extent from space and can take ========================================================= @@ -2446,20 +2409,8 @@ take_hinted_page: /* Try to fill the segment free list */ fseg_fill_free_list(seg_inode, space, hint + FSP_EXTENT_SIZE, mtr); - goto take_hinted_page; - /*-----------------------------------------------------------*/ - } else if (!init_mtr) { - ut_a(xdes_get_state(descr, mtr) == XDES_FREE_FRAG); - fsp_alloc_from_free_frag(space_header, descr, - hint % FSP_EXTENT_SIZE, mtr); ret_page = hint; - ret_descr = NULL; - - /* Put the page in the fragment page array of the segment */ - n = fseg_find_free_frag_page_slot(seg_inode, mtr); - ut_a(n != FIL_NULL); - fseg_set_nth_frag_page_no(seg_inode, n, ret_page, mtr); - goto got_hinted_page; + /*-----------------------------------------------------------*/ } else if ((direction != FSP_NO_DIR) && ((reserved - used) < reserved / FSEG_FILLFACTOR) && (used >= FSEG_FRAG_LIMIT) @@ -2517,9 +2468,11 @@ take_hinted_page: } else if (used < FSEG_FRAG_LIMIT) { /* 6. We allocate an individual page from the space ===================================================*/ - ret_page = fsp_alloc_free_page(space, hint, mtr, init_mtr); + ret_page = fsp_alloc_free_page(space, hint, mtr); ret_descr = NULL; + frag_page_allocated = TRUE; + if (ret_page != FIL_NULL) { /* Put the page in the fragment page array of the segment */ @@ -2529,10 +2482,6 @@ take_hinted_page: fseg_set_nth_frag_page_no(seg_inode, n, ret_page, mtr); } - - /* fsp_alloc_free_page() invoked fsp_init_file_page() - already. */ - return(ret_page); /*-----------------------------------------------------------*/ } else { /* 7. We allocate a new extent and take its first page @@ -2579,31 +2528,22 @@ take_hinted_page: } } -got_hinted_page: - { + if (!frag_page_allocated) { /* Initialize the allocated page to buffer pool, so that it can be obtained immediately with buf_page_get without need for a disk read */ - mtr_t* block_mtr = init_mtr ? init_mtr : mtr; - page = buf_page_create(space, ret_page, block_mtr); + page = buf_page_create(space, ret_page, mtr); - ut_a(page == buf_page_get(space, ret_page, RW_X_LATCH, - block_mtr)); + ut_a(page == buf_page_get(space, ret_page, RW_X_LATCH, mtr)); #ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(page, SYNC_FSP_PAGE); #endif /* UNIV_SYNC_DEBUG */ - if (init_mtr) { - /* The prior contents of the page should be ignored */ - fsp_init_file_page(page, init_mtr); - } - } + /* The prior contents of the page should be ignored */ + fsp_init_file_page(page, mtr); - /* ret_descr == NULL if the block was allocated from free_frag - (XDES_FREE_FRAG) */ - if (ret_descr != NULL) { /* At this point we know the extent and the page offset. The extent is still in the appropriate list (FSEG_NOT_FULL or FSEG_FREE), and the page is not yet marked as used. */ @@ -2640,11 +2580,7 @@ fseg_alloc_free_page_general( with fsp_reserve_free_extents, then there is no need to do the check for this individual page */ - mtr_t* mtr, /* in/out: mini-transaction handle */ - mtr_t* init_mtr)/* in/out: mtr or another mini-transaction - in which the page should be initialized, - or NULL if this is a "fake allocation" of - a page that was previously freed in mtr */ + mtr_t* mtr) /* in/out: mini-transaction */ { fseg_inode_t* inode; ulint space; @@ -2682,8 +2618,7 @@ fseg_alloc_free_page_general( } page_no = fseg_alloc_free_page_low(buf_frame_get_space_id(inode), - inode, hint, direction, - mtr, init_mtr); + inode, hint, direction, mtr); if (!has_done_reservation) { fil_space_release_free_extents(space, n_reserved); } @@ -2711,7 +2646,7 @@ fseg_alloc_free_page( mtr_t* mtr) /* in: mtr handle */ { return(fseg_alloc_free_page_general(seg_header, hint, direction, - FALSE, mtr, mtr)); + FALSE, mtr)); } /************************************************************************** |