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);
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' Server/ storage/ innodb_ plugin/ btr/btr0cur. c 2012-10-16 11:18:45 +0000 Server/ storage/ innodb_ plugin/ btr/btr0cur. c 2012-10-16 18:08:32 +0000 block-> check_index_ page_at_ flush = TRUE; latch_mode == BTR_SEARCH_TREE)) { get_prev( page, mtr);
--- Percona-
+++ Percona-
@@ -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_
return;
+ case BTR_SEARCH_TREE:
case BTR_MODIFY_TREE:
- /* x-latch also brothers from left to right */
+ if (UNIV_UNLIKELY(
+ 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_
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) { a(btr_page_ get_next( get_block- >frame, mtr) page_no( page)); >check_ index_page_ at_flush = TRUE; release( mtr, get_block, >check_ index_page_ at_flush = TRUE;
return;
@@ -270,12 +279,18 @@
ut_
== page_get_
#endif /* UNIV_BTR_DEBUG */
- get_block-
+ if (sibling_mode == RW_NO_LATCH) {
+ mtr_memo_
+ MTR_MEMO_BUF_FIX);
+ }
+ else {
+ get_block-
+ }
}
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) { a(btr_page_ get_prev( get_block- >frame, mtr) page_no( page)); >check_ index_page_ at_flush = TRUE; release( mtr, get_block, >check_ index_page_ at_flush = TRUE;
return;
@@ -303,7 +318,13 @@
ut_
== page_get_
#endif /* UNIV_BTR_DEBUG */
- get_block-
+ if (sibling_mode == RW_NO_LATCH) {
+ mtr_memo_
+ MTR_MEMO_BUF_FIX);
+ }
+ else {
+ get_block-
+ }
}
return;