5427 Marko Mäkelä 2013-01-23
Bug#15866009 UNNECESSARY BUFFER POOL LOOKUP WHILE FREEING BLOB
Skip calls to btr_search_drop_page_hash_when_freed() when freeing BLOB pages.
The adaptive hash index can only point to B-tree pages, never to BLOB pages.
fseg_free_page_low(), fseg_free_extent(): Add the parameter bool ahi,
to indicate whether there may be adaptive hash index entries that will
need to be freed.
btr_page_free_low(): Interpret level=ULINT_UNDEFINED as a BLOB page.
Add a debug status instrument innodb_ahi_drop_lookups, for testing this.
rb#1551 approved by Sunny Bains
modified:
storage/innobase/btr/btr0btr.cc
storage/innobase/btr/btr0cur.cc
storage/innobase/btr/btr0sea.cc
storage/innobase/fsp/fsp0fsp.cc
storage/innobase/handler/ha_innodb.cc
storage/innobase/ibuf/ibuf0ibuf.cc
storage/innobase/include/btr0btr.h
storage/innobase/include/fsp0fsp.h
storage/innobase/include/srv0srv.h
storage/innobase/trx/trx0purge.cc
storage/innobase/trx/trx0undo.cc
5426 Roy Lyseng 2013-01-23
Make some functions in sql_select.h const.
modified:
sql/sql_select.h
=== modified file 'storage/innobase/btr/btr0btr.cc'
--- a/storage/innobase/btr/btr0btr.cc revid:roy.lyseng@stripped31321-xlvvzx2nopc4hz9g
+++ b/storage/innobase/btr/btr0btr.cc revid:marko.makela@strippedutcd5c7k
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
This program is free software; you can redistribute it and/or modify it under
@@ -1240,15 +1240,14 @@ btr_page_free_for_ibuf(
/**************************************************************//**
Frees a file page used in an index tree. Can be used also to (BLOB)
-external storage pages, because the page level 0 can be given as an
-argument. */
+external storage pages. */
UNIV_INTERN
void
btr_page_free_low(
/*==============*/
dict_index_t* index, /*!< in: index tree */
buf_block_t* block, /*!< in: block to be freed, x-latched */
- ulint level, /*!< in: page level */
+ ulint level, /*!< in: page level (ULINT_UNDEFINED=BLOB) */
mtr_t* mtr) /*!< in: mtr */
{
fseg_header_t* seg_header;
@@ -1270,7 +1269,7 @@ btr_page_free_low(
root = btr_root_get(index, mtr);
- if (level == 0) {
+ if (level == 0 || level == ULINT_UNDEFINED) {
seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_LEAF;
} else {
seg_header = root + PAGE_HEADER + PAGE_BTR_SEG_TOP;
@@ -1278,7 +1277,8 @@ btr_page_free_low(
fseg_free_page(seg_header,
buf_block_get_space(block),
- buf_block_get_page_no(block), mtr);
+ buf_block_get_page_no(block),
+ level != ULINT_UNDEFINED, mtr);
/* The page was marked free in the allocation bitmap, but it
should remain buffer-fixed until mtr_commit(mtr) or until it
@@ -1305,6 +1305,7 @@ btr_page_free(
ulint level = btr_page_get_level(page, mtr);
ut_ad(fil_page_get_type(block->frame) == FIL_PAGE_INDEX);
+ ut_ad(level != ULINT_UNDEFINED);
btr_page_free_low(index, block, level, mtr);
}
@@ -1668,7 +1669,7 @@ leaf_loop:
fsp0fsp. */
finished = fseg_free_step(root + PAGE_HEADER + PAGE_BTR_SEG_LEAF,
- &mtr);
+ true, &mtr);
mtr_commit(&mtr);
if (!finished) {
@@ -1686,7 +1687,7 @@ top_loop:
#endif /* UNIV_BTR_DEBUG */
finished = fseg_free_step_not_header(
- root + PAGE_HEADER + PAGE_BTR_SEG_TOP, &mtr);
+ root + PAGE_HEADER + PAGE_BTR_SEG_TOP, true, &mtr);
mtr_commit(&mtr);
if (!finished) {
@@ -1720,7 +1721,7 @@ btr_free_root(
ut_a(btr_root_fseg_validate(header, space));
#endif /* UNIV_BTR_DEBUG */
- while (!fseg_free_step(header, mtr)) {
+ while (!fseg_free_step(header, true, mtr)) {
/* Free the entire segment in small steps. */
}
}
=== modified file 'storage/innobase/btr/btr0cur.cc'
--- a/storage/innobase/btr/btr0cur.cc revid:roy.lyseng@stripped
+++ b/storage/innobase/btr/btr0cur.cc revid:marko.makela@oracle.com-20130123145232-zm1e81yzutcd5c7k
@@ -4729,7 +4729,8 @@ func_exit:
ut_ad(btr_blob_op_is_update(op));
for (i = 0; i < n_freed_pages; i++) {
- btr_page_free_low(index, freed_pages[i], 0, alloc_mtr);
+ btr_page_free_low(index, freed_pages[i],
+ ULINT_UNDEFINED, alloc_mtr);
}
}
@@ -4954,7 +4955,8 @@ btr_free_externally_stored_field(
}
next_page_no = mach_read_from_4(page + FIL_PAGE_NEXT);
- btr_page_free_low(index, ext_block, 0, &mtr);
+ btr_page_free_low(index, ext_block, ULINT_UNDEFINED,
+ &mtr);
if (page_zip != NULL) {
mach_write_to_4(field_ref + BTR_EXTERN_PAGE_NO,
@@ -4981,11 +4983,8 @@ btr_free_externally_stored_field(
page + FIL_PAGE_DATA
+ BTR_BLOB_HDR_NEXT_PAGE_NO);
- /* We must supply the page level (= 0) as an argument
- because we did not store it on the page (we save the
- space overhead from an index page header. */
-
- btr_page_free_low(index, ext_block, 0, &mtr);
+ btr_page_free_low(index, ext_block, ULINT_UNDEFINED,
+ &mtr);
mlog_write_ulint(field_ref + BTR_EXTERN_PAGE_NO,
next_page_no,
=== modified file 'storage/innobase/btr/btr0sea.cc'
--- a/storage/innobase/btr/btr0sea.cc revid:roy.lyseng@strippedx2nopc4hz9g
+++ b/storage/innobase/btr/btr0sea.cc revid:marko.makela@stripped
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
Portions of this file contain modifications contributed and copyrighted by
@@ -1265,6 +1265,8 @@ btr_search_drop_page_hash_when_freed(
buf_block_t* block;
mtr_t mtr;
+ ut_d(export_vars.innodb_ahi_drop_lookups++);
+
mtr_start(&mtr);
/* If the caller has a latch on the page, then the caller must
=== modified file 'storage/innobase/fsp/fsp0fsp.cc'
--- a/storage/innobase/fsp/fsp0fsp.cc revid:roy.lyseng@stripped4hz9g
+++ b/storage/innobase/fsp/fsp0fsp.cc revid:marko.makela@stripped
@@ -64,18 +64,6 @@ fsp_free_extent(
ulint page, /*!< in: page offset in the extent */
mtr_t* mtr); /*!< in/out: mini-transaction */
/**********************************************************************//**
-Frees an extent of a segment to the space free list. */
-static
-void
-fseg_free_extent(
-/*=============*/
- fseg_inode_t* seg_inode, /*!< in: segment inode */
- ulint space, /*!< in: space id */
- ulint zip_size,/*!< in: compressed page size in bytes
- or 0 for uncompressed pages */
- ulint page, /*!< in: page offset in the extent */
- mtr_t* mtr); /*!< in/out: mini-transaction */
-/**********************************************************************//**
Calculates the number of pages reserved by a segment, and how
many pages are currently used.
@return number of reserved pages */
@@ -3058,6 +3046,8 @@ fseg_free_page_low(
ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
ulint page, /*!< in: page offset */
+ bool ahi, /*!< in: whether we may need to drop
+ the adaptive hash index */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
xdes_t* descr;
@@ -3075,7 +3065,9 @@ fseg_free_page_low(
/* Drop search system page hash index if the page is found in
the pool and is hashed */
- btr_search_drop_page_hash_when_freed(space, zip_size, page);
+ if (ahi) {
+ btr_search_drop_page_hash_when_freed(space, zip_size, page);
+ }
descr = xdes_get_descriptor(space, zip_size, page, mtr);
@@ -3193,6 +3185,8 @@ fseg_free_page(
fseg_header_t* seg_header, /*!< in: segment header */
ulint space, /*!< in: space id */
ulint page, /*!< in: page offset */
+ bool ahi, /*!< in: whether we may need to drop
+ the adaptive hash index */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
ulint flags;
@@ -3207,7 +3201,7 @@ fseg_free_page(
seg_inode = fseg_inode_get(seg_header, space, zip_size, mtr);
- fseg_free_page_low(seg_inode, space, zip_size, page, mtr);
+ fseg_free_page_low(seg_inode, space, zip_size, page, ahi, mtr);
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
buf_page_set_file_page_was_freed(space, page);
@@ -3259,7 +3253,7 @@ fseg_page_is_free(
/**********************************************************************//**
Frees an extent of a segment to the space free list. */
-static
+static __attribute__((nonnull))
void
fseg_free_extent(
/*=============*/
@@ -3268,6 +3262,8 @@ fseg_free_extent(
ulint zip_size,/*!< in: compressed page size in bytes
or 0 for uncompressed pages */
ulint page, /*!< in: a page in the extent */
+ bool ahi, /*!< in: whether we may need to drop
+ the adaptive hash index */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
ulint first_page_in_extent;
@@ -3287,14 +3283,18 @@ fseg_free_extent(
first_page_in_extent = page - (page % FSP_EXTENT_SIZE);
- for (i = 0; i < FSP_EXTENT_SIZE; i++) {
- if (!xdes_mtr_get_bit(descr, XDES_FREE_BIT, i, mtr)) {
-
- /* Drop search system page hash index if the page is
- found in the pool and is hashed */
-
- btr_search_drop_page_hash_when_freed(
- space, zip_size, first_page_in_extent + i);
+ if (ahi) {
+ for (i = 0; i < FSP_EXTENT_SIZE; i++) {
+ if (!xdes_mtr_get_bit(descr, XDES_FREE_BIT, i, mtr)) {
+
+ /* Drop search system page hash index
+ if the page is found in the pool and
+ is hashed */
+
+ btr_search_drop_page_hash_when_freed(
+ space, zip_size,
+ first_page_in_extent + i);
+ }
}
}
@@ -3343,6 +3343,8 @@ fseg_free_step(
resides on the first page of the frag list
of the segment, this pointer becomes obsolete
after the last freeing step */
+ bool ahi, /*!< in: whether we may need to drop
+ the adaptive hash index */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
ulint n;
@@ -3385,7 +3387,7 @@ fseg_free_step(
/* Free the extent held by the segment */
page = xdes_get_offset(descr);
- fseg_free_extent(inode, space, zip_size, page, mtr);
+ fseg_free_extent(inode, space, zip_size, page, ahi, mtr);
return(FALSE);
}
@@ -3401,7 +3403,8 @@ fseg_free_step(
}
fseg_free_page_low(inode, space, zip_size,
- fseg_get_nth_frag_page_no(inode, n, mtr), mtr);
+ fseg_get_nth_frag_page_no(inode, n, mtr),
+ ahi, mtr);
n = fseg_find_last_used_frag_page_slot(inode, mtr);
@@ -3425,6 +3428,8 @@ fseg_free_step_not_header(
/*======================*/
fseg_header_t* header, /*!< in: segment header which must reside on
the first fragment page of the segment */
+ bool ahi, /*!< in: whether we may need to drop
+ the adaptive hash index */
mtr_t* mtr) /*!< in/out: mini-transaction */
{
ulint n;
@@ -3452,7 +3457,7 @@ fseg_free_step_not_header(
/* Free the extent held by the segment */
page = xdes_get_offset(descr);
- fseg_free_extent(inode, space, zip_size, page, mtr);
+ fseg_free_extent(inode, space, zip_size, page, ahi, mtr);
return(FALSE);
}
@@ -3472,7 +3477,7 @@ fseg_free_step_not_header(
return(TRUE);
}
- fseg_free_page_low(inode, space, zip_size, page_no, mtr);
+ fseg_free_page_low(inode, space, zip_size, page_no, ahi, mtr);
return(FALSE);
}
=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc revid:roy.lyseng@strippedxlvvzx2nopc4hz9g
+++ b/storage/innobase/handler/ha_innodb.cc revid:marko.makela@strippedutcd5c7k
@@ -645,6 +645,8 @@ static SHOW_VAR innodb_status_variables[
(char*) &export_vars.innodb_purge_trx_id_age, SHOW_LONG},
{"purge_view_trx_id_age",
(char*) &export_vars.innodb_purge_view_trx_id_age, SHOW_LONG},
+ {"ahi_drop_lookups",
+ (char*) &export_vars.innodb_ahi_drop_lookups, SHOW_LONG},
#endif /* UNIV_DEBUG */
{NullS, NullS, SHOW_LONG}
};
=== modified file 'storage/innobase/ibuf/ibuf0ibuf.cc'
--- a/storage/innobase/ibuf/ibuf0ibuf.cc revid:roy.lyseng@oracle.com-20130123131321-xlvvzx2nopc4hz9g
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc revid:marko.makela@stripped123145232-zm1e81yzutcd5c7k
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1997, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1997, 2013, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -2192,7 +2192,7 @@ ibuf_remove_free_page(void)
page from it. */
fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
- IBUF_SPACE_ID, page_no, &mtr);
+ IBUF_SPACE_ID, page_no, false, &mtr);
#if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
buf_page_reset_file_page_was_freed(IBUF_SPACE_ID, page_no);
=== modified file 'storage/innobase/include/btr0btr.h'
--- a/storage/innobase/include/btr0btr.h revid:roy.lyseng@oracle.com-20130123131321-xlvvzx2nopc4hz9g
+++ b/storage/innobase/include/btr0btr.h revid:marko.makela@stripped23145232-zm1e81yzutcd5c7k
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
This program is free software; you can redistribute it and/or modify it under
@@ -676,15 +676,14 @@ btr_page_free(
__attribute__((nonnull));
/**************************************************************//**
Frees a file page used in an index tree. Can be used also to BLOB
-external storage pages, because the page level 0 can be given as an
-argument. */
+external storage pages. */
UNIV_INTERN
void
btr_page_free_low(
/*==============*/
dict_index_t* index, /*!< in: index tree */
buf_block_t* block, /*!< in: block to be freed, x-latched */
- ulint level, /*!< in: page level */
+ ulint level, /*!< in: page level (ULINT_UNDEFINED=BLOB) */
mtr_t* mtr) /*!< in: mtr */
__attribute__((nonnull));
#ifdef UNIV_BTR_PRINT
=== modified file 'storage/innobase/include/fsp0fsp.h'
--- a/storage/innobase/include/fsp0fsp.h revid:roy.lyseng@stripped1-xlvvzx2nopc4hz9g
+++ b/storage/innobase/include/fsp0fsp.h revid:marko.makela@strippedtcd5c7k
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -568,7 +568,10 @@ fseg_free_page(
fseg_header_t* seg_header, /*!< in: segment header */
ulint space, /*!< in: space id */
ulint page, /*!< in: page offset */
- mtr_t* mtr); /*!< in/out: mini-transaction */
+ bool ahi, /*!< in: whether we may need to drop
+ the adaptive hash index */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
+ __attribute__((nonnull));
/**********************************************************************//**
Checks if a single page of a segment is free.
@return true if free */
@@ -594,7 +597,10 @@ fseg_free_step(
resides on the first page of the frag list
of the segment, this pointer becomes obsolete
after the last freeing step */
- mtr_t* mtr); /*!< in/out: mini-transaction */
+ bool ahi, /*!< in: whether we may need to drop
+ the adaptive hash index */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
+ __attribute__((nonnull, warn_unused_result));
/**********************************************************************//**
Frees part of a segment. Differs from fseg_free_step because this function
leaves the header page unfreed.
@@ -605,7 +611,10 @@ fseg_free_step_not_header(
/*======================*/
fseg_header_t* header, /*!< in: segment header which must reside on
the first fragment page of the segment */
- mtr_t* mtr); /*!< in/out: mini-transaction */
+ bool ahi, /*!< in: whether we may need to drop
+ the adaptive hash index */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
+ __attribute__((nonnull, warn_unused_result));
/***********************************************************************//**
Checks if a page address is an extent descriptor page address.
@return TRUE if a descriptor page */
=== modified file 'storage/innobase/include/srv0srv.h'
--- a/storage/innobase/include/srv0srv.h revid:roy.lyseng@strippedopc4hz9g
+++ b/storage/innobase/include/srv0srv.h revid:marko.makela@stripped
@@ -829,6 +829,9 @@ struct export_var_t{
ulint innodb_purge_trx_id_age; /*!< rw_max_trx_id - purged trx_id */
ulint innodb_purge_view_trx_id_age; /*!< rw_max_trx_id
- purged view's min trx_id */
+ ulint innodb_ahi_drop_lookups; /*!< number of adaptive hash
+ index lookups when freeing
+ file pages */
#endif /* UNIV_DEBUG */
};
=== modified file 'storage/innobase/trx/trx0purge.cc'
--- a/storage/innobase/trx/trx0purge.cc revid:roy.lyseng@stripped
+++ b/storage/innobase/trx/trx0purge.cc revid:marko.makela@oracle.com-20130123145232-zm1e81yzutcd5c7k
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -335,7 +335,7 @@ trx_purge_free_segment(
}
if (fseg_free_step_not_header(
- seg_hdr + TRX_UNDO_FSEG_HEADER, &mtr)) {
+ seg_hdr + TRX_UNDO_FSEG_HEADER, false, &mtr)) {
break;
}
@@ -374,7 +374,7 @@ trx_purge_free_segment(
is not flooded with bufferfixed pages: see the note in
fsp0fsp.cc. */
- } while(!fseg_free_step(seg_hdr + TRX_UNDO_FSEG_HEADER, &mtr));
+ } while (!fseg_free_step(seg_hdr + TRX_UNDO_FSEG_HEADER, false, &mtr));
hist_size = mtr_read_ulint(rseg_hdr + TRX_RSEG_HISTORY_SIZE,
MLOG_4BYTES, &mtr);
=== modified file 'storage/innobase/trx/trx0undo.cc'
--- a/storage/innobase/trx/trx0undo.cc revid:roy.lyseng@stripped123131321-xlvvzx2nopc4hz9g
+++ b/storage/innobase/trx/trx0undo.cc revid:marko.makela@strippede81yzutcd5c7k
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -983,7 +983,7 @@ trx_undo_free_page(
undo_page + TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_NODE, mtr);
fseg_free_page(header_page + TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER,
- space, page_no, mtr);
+ space, page_no, false, mtr);
last_addr = flst_get_last(header_page + TRX_UNDO_SEG_HDR
+ TRX_UNDO_PAGE_LIST, mtr);
@@ -1227,7 +1227,7 @@ trx_undo_seg_free(
file_seg = seg_header + TRX_UNDO_FSEG_HEADER;
- finished = fseg_free_step(file_seg, &mtr);
+ finished = fseg_free_step(file_seg, false, &mtr);
if (finished) {
/* Update the rseg header */
No bundle (reason: useless for push emails).| Thread |
|---|
| • bzr push into mysql-trunk branch (marko.makela:5426 to 5427) Bug#15866009 | marko.makela | 8 Mar 2013 |