#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#58212 | marko.makela | 16 Nov |