List:Commits« Previous MessageNext Message »
From:marko.makela Date:January 23 2013 2:54pm
Subject:bzr push into mysql-trunk branch (marko.makela:5426 to 5427) Bug#15866009
View as plain text  
 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#15866009marko.makela8 Mar