List:Commits« Previous MessageNext Message »
From:marko.makela Date:November 16 2010 12:21pm
Subject:bzr commit into mysql-5.5-innodb branch (marko.makela:3228) Bug#58212
View as plain text  
#At file:///home/marko/innobase/dev/mysql2a/5.5-innodb/ based on revid:jimmy.yang@stripped7l3u4p48f5

 3228 Marko Mäkelä	2010-11-16
      Bug#58212 Possible deadlock in change buffer in debug builds
      
      ibuf_page(): Renamed to ibuf_page_low(). Add the parameters file, line
      so that the latch diagnostics will be more meaningful.
      In debug builds, add the parameter ibool x_latch. When x_latch=FALSE,
      it is OK to return TRUE even if the page is not in the buffer pool.
      
      ibuf_page(): A wrapper macro for ibuf_page_low(). Pass x_latch=TRUE.
      
      buf_page_get_gen(): Use ibuf_page_low(x_latch=FALSE) in the debug assertion.
      This avoids the possible deadlock.

    modified:
      storage/innobase/buf/buf0buf.c
      storage/innobase/ibuf/ibuf0ibuf.c
      storage/innobase/include/ibuf0ibuf.h
=== modified file 'storage/innobase/buf/buf0buf.c'
--- a/storage/innobase/buf/buf0buf.c	revid:jimmy.yang@stripped
+++ b/storage/innobase/buf/buf0buf.c	revid:marko.makela@stripped20101116122146-f5ilp7xzdwl8t190
@@ -2745,7 +2745,8 @@ buf_page_get_gen(
 	ut_ad(zip_size == fil_space_get_zip_size(space));
 	ut_ad(ut_is_2pow(zip_size));
 #ifndef UNIV_LOG_DEBUG
-	ut_ad(!ibuf_inside() || ibuf_page(space, zip_size, offset, NULL));
+	ut_ad(!ibuf_inside() || ibuf_page_low(space, zip_size, offset,
+					      FALSE, file, line, NULL));
 #endif
 	buf_pool->stat.n_page_gets++;
 	fold = buf_page_address_fold(space, offset);

=== modified file 'storage/innobase/ibuf/ibuf0ibuf.c'
--- a/storage/innobase/ibuf/ibuf0ibuf.c	revid:jimmy.yang@stripped070804-gz1z4s7l3u4p48f5
+++ b/storage/innobase/ibuf/ibuf0ibuf.c	revid:marko.makela@stripped7xzdwl8t190
@@ -1109,21 +1109,29 @@ Must not be called when recv_no_ibuf_ope
 @return	TRUE if level 2 or level 3 page */
 UNIV_INTERN
 ibool
-ibuf_page(
-/*======*/
-	ulint	space,	/*!< in: space id */
-	ulint	zip_size,/*!< in: compressed page size in bytes, or 0 */
-	ulint	page_no,/*!< in: page number */
-	mtr_t*	mtr)	/*!< in: mtr which will contain an x-latch to the
-			bitmap page if the page is not one of the fixed
-			address ibuf pages, or NULL, in which case a new
-			transaction is created. */
+ibuf_page_low(
+/*==========*/
+	ulint		space,	/*!< in: space id */
+	ulint		zip_size,/*!< in: compressed page size in bytes, or 0 */
+	ulint		page_no,/*!< in: page number */
+#ifdef UNIV_DEBUG
+	ibool		x_latch,/*!< in: FALSE if relaxed check
+				(avoid latching the bitmap page) */
+#endif /* UNIV_DEBUG */
+	const char*	file,	/*!< in: file name */
+	ulint		line,	/*!< in: line where called */
+	mtr_t*		mtr)	/*!< in: mtr which will contain an
+				x-latch to the bitmap page if the page
+				is not one of the fixed address ibuf
+				pages, or NULL, in which case a new
+				transaction is created. */
 {
 	ibool	ret;
 	mtr_t	local_mtr;
 	page_t*	bitmap_page;
 
 	ut_ad(!recv_no_ibuf_operations);
+	ut_ad(x_latch || mtr == NULL);
 
 	if (ibuf_fixed_addr_page(space, zip_size, page_no)) {
 
@@ -1135,12 +1143,37 @@ ibuf_page(
 
 	ut_ad(fil_space_get_type(IBUF_SPACE_ID) == FIL_TABLESPACE);
 
+#ifdef UNIV_DEBUG
+	if (!x_latch) {
+		ulint		bitmap_page_no;
+		buf_block_t*	bitmap_block;
+
+		mtr_start(&local_mtr);
+		bitmap_page_no = ibuf_bitmap_page_no_calc(zip_size, page_no);
+
+		bitmap_block = buf_page_get_gen(space, zip_size,
+						bitmap_page_no,
+						RW_NO_LATCH, NULL,
+						BUF_GET_IF_IN_POOL,
+						file, line, &local_mtr);
+		ret = bitmap_block == NULL
+			|| ibuf_bitmap_page_get_bits(
+				buf_block_get_frame(bitmap_block),
+				page_no, zip_size, IBUF_BITMAP_IBUF,
+				&local_mtr);
+
+		mtr_commit(&local_mtr);
+		return(ret);
+	}
+#endif /* UNIV_DEBUG */
+
 	if (mtr == NULL) {
 		mtr = &local_mtr;
 		mtr_start(mtr);
 	}
 
-	bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr);
+	bitmap_page = ibuf_bitmap_get_map_page_func(space, page_no, zip_size,
+						    file, line, mtr);
 
 	ret = ibuf_bitmap_page_get_bits(bitmap_page, page_no, zip_size,
 					IBUF_BITMAP_IBUF, mtr);

=== modified file 'storage/innobase/include/ibuf0ibuf.h'
--- a/storage/innobase/include/ibuf0ibuf.h	revid:jimmy.yang@oracle.com-20101115070804-gz1z4s7l3u4p48f5
+++ b/storage/innobase/include/ibuf0ibuf.h	revid:marko.makela@stripped01116122146-f5ilp7xzdwl8t190
@@ -244,15 +244,44 @@ Must not be called when recv_no_ibuf_ope
 @return	TRUE if level 2 or level 3 page */
 UNIV_INTERN
 ibool
-ibuf_page(
-/*======*/
-	ulint	space,	/*!< in: space id */
-	ulint	zip_size,/*!< in: compressed page size in bytes, or 0 */
-	ulint	page_no,/*!< in: page number */
-	mtr_t*	mtr);	/*!< in: mtr which will contain an x-latch to the
-			bitmap page if the page is not one of the fixed
-			address ibuf pages, or NULL, in which case a new
-			transaction is created. */
+ibuf_page_low(
+/*==========*/
+	ulint		space,	/*!< in: space id */
+	ulint		zip_size,/*!< in: compressed page size in bytes, or 0 */
+	ulint		page_no,/*!< in: page number */
+#ifdef UNIV_DEBUG
+	ibool		x_latch,/*!< in: FALSE if relaxed check
+				(avoid latching the bitmap page) */
+#endif /* UNIV_DEBUG */
+	const char*	file,	/*!< in: file name */
+	ulint		line,	/*!< in: line where called */
+	mtr_t*		mtr)	/*!< in: mtr which will contain an
+				x-latch to the bitmap page if the page
+				is not one of the fixed address ibuf
+				pages, or NULL, in which case a new
+				transaction is created. */
+	__attribute__((warn_unused_result));
+#ifdef UNIV_DEBUG
+/** Checks if a page is a level 2 or 3 page in the ibuf hierarchy of
+pages.  Must not be called when recv_no_ibuf_operations==TRUE.
+@param space	tablespace identifier
+@param zip_size	compressed page size in bytes, or 0
+@param page_no	page number
+@param mtr	mini-transaction or NULL
+@return TRUE if level 2 or level 3 page */
+# define ibuf_page(space, zip_size, page_no, mtr)			\
+	ibuf_page_low(space, zip_size, page_no, TRUE, __FILE__, __LINE__, mtr)
+#else /* UVIV_DEBUG */
+/** Checks if a page is a level 2 or 3 page in the ibuf hierarchy of
+pages.  Must not be called when recv_no_ibuf_operations==TRUE.
+@param space	tablespace identifier
+@param zip_size	compressed page size in bytes, or 0
+@param page_no	page number
+@param mtr	mini-transaction or NULL
+@return TRUE if level 2 or level 3 page */
+# define ibuf_page(space, zip_size, page_no, mtr)			\
+	ibuf_page_low(space, zip_size, page_no, __FILE__, __LINE__, mtr)
+#endif /* UVIV_DEBUG */
 /***********************************************************************//**
 Frees excess pages from the ibuf free list. This function is called when an OS
 thread calls fsp services to allocate a new file segment, or a new page to a

Attachment: [text/bzr-bundle] bzr/marko.makela@oracle.com-20101116122146-f5ilp7xzdwl8t190.bundle
Thread
bzr commit into mysql-5.5-innodb branch (marko.makela:3228) Bug#58212marko.makela16 Nov