summaryrefslogtreecommitdiff
path: root/storage/innobase/fsp/fsp0fsp.c
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@oracle.com>2011-10-26 11:44:28 +0300
committerMarko Mäkelä <marko.makela@oracle.com>2011-10-26 11:44:28 +0300
commit1885f3720ff8d85e2a38aded6c85c81cc1d600c0 (patch)
tree644aa74ed246e7c4530392e1c9e24800dbfdfdc9 /storage/innobase/fsp/fsp0fsp.c
parentd653549ecc82bac7a492dceb5e4dd2bbed5be4f6 (diff)
downloadmariadb-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.c159
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));
}
/**************************************************************************