Comment 1 for bug 1059738

Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

I wonder if the prefetched sibling pages have to be latched at all. I am testing a patch that reads them into buffer with RW_NO_LATCH and then immediately releases them from MTR (as RW_NO_LATCH puts them there, buffer-fixed).

=== modified file 'Percona-Server/storage/innodb_plugin/btr/btr0cur.c'
--- Percona-Server/storage/innodb_plugin/btr/btr0cur.c 2012-10-16 11:18:45 +0000
+++ Percona-Server/storage/innodb_plugin/btr/btr0cur.c 2012-10-16 18:08:32 +0000
@@ -228,6 +228,7 @@
  mtr_t* mtr) /*!< in: mtr */
 {
  ulint mode;
+ ulint sibling_mode;
  ulint left_page_no;
  ulint right_page_no;
  buf_block_t* get_block;
@@ -251,14 +252,22 @@
 #endif /* UNIV_BTR_DEBUG */
   get_block->check_index_page_at_flush = TRUE;
   return;
+ case BTR_SEARCH_TREE:
  case BTR_MODIFY_TREE:
- /* x-latch also brothers from left to right */
+ if (UNIV_UNLIKELY(latch_mode == BTR_SEARCH_TREE)) {
+ mode = RW_S_LATCH;
+ sibling_mode = RW_NO_LATCH;
+ }
+ else {
+ mode = sibling_mode = RW_X_LATCH;
+ }
+ /* Fetch and possibly latch also brothers from left to right */
   left_page_no = btr_page_get_prev(page, mtr);

   if (left_page_no != FIL_NULL) {
    get_block = btr_block_get(
     space, zip_size, left_page_no,
- RW_X_LATCH, cursor->index, mtr);
+ sibling_mode, cursor->index, mtr);

    if (srv_pass_corrupt_table && !get_block) {
     return;
@@ -270,12 +279,18 @@
    ut_a(btr_page_get_next(get_block->frame, mtr)
         == page_get_page_no(page));
 #endif /* UNIV_BTR_DEBUG */
- get_block->check_index_page_at_flush = TRUE;
+ if (sibling_mode == RW_NO_LATCH) {
+ mtr_memo_release(mtr, get_block,
+ MTR_MEMO_BUF_FIX);
+ }
+ else {
+ get_block->check_index_page_at_flush = TRUE;
+ }
   }

   get_block = btr_block_get(
    space, zip_size, page_no,
- RW_X_LATCH, cursor->index, mtr);
+ mode, cursor->index, mtr);

   if (srv_pass_corrupt_table && !get_block) {
    return;
@@ -291,7 +306,7 @@
   if (right_page_no != FIL_NULL) {
    get_block = btr_block_get(
     space, zip_size, right_page_no,
- RW_X_LATCH, cursor->index, mtr);
+ sibling_mode, cursor->index, mtr);

    if (srv_pass_corrupt_table && !get_block) {
     return;
@@ -303,7 +318,13 @@
    ut_a(btr_page_get_prev(get_block->frame, mtr)
         == page_get_page_no(page));
 #endif /* UNIV_BTR_DEBUG */
- get_block->check_index_page_at_flush = TRUE;
+ if (sibling_mode == RW_NO_LATCH) {
+ mtr_memo_release(mtr, get_block,
+ MTR_MEMO_BUF_FIX);
+ }
+ else {
+ get_block->check_index_page_at_flush = TRUE;
+ }
   }

   return;