diff options
author | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2020-07-23 16:59:30 +0530 |
---|---|---|
committer | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2020-07-23 17:38:46 +0530 |
commit | 0ec30e0606d1795d020bab9f1a40744e57e6eb68 (patch) | |
tree | fe08e69936501d7fe83fb457565a593b887db2a0 | |
parent | fe39d02f51b96536dccca7ff89faf05e13548877 (diff) | |
download | mariadb-git-bb-10.2-MDEV-14711.tar.gz |
MDEV-14711 Assertion `mode == 16 || mode == 12 || !fix_block->page.file_page_was_freed' failed in buf_page_get_gen (rollback requesting a freed undo page)bb-10.2-MDEV-14711
Problem:
=======
In buf_cur_optimistic_latch_leaves(), requesting a left block with BTR_GET
after releasing current block. But there is no guarantee that left block
could be still available.
Fix:
====
(1) In btr_cur_optimistic_latch_leaves(), replace the BUF_GET with
BUF_GET_POSSIBLY_FREED for fetching left block.
(2) Once InnoDB acquires left block, it should check FIL_PAGE_NEXT with
current block page number. If not, release cursor->left_block and return
false.
-rw-r--r-- | storage/innobase/btr/btr0cur.cc | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 35e578e1a5c..f3f84557a17 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -438,9 +438,12 @@ btr_cur_optimistic_latch_leaves( rw_lock_s_lock(&block->lock); if (block->modify_clock != modify_clock) { rw_lock_s_unlock(&block->lock); - - goto unpin_failed; +unpin_failed: + /* unpin the block */ + buf_block_buf_fix_dec(block); + return(false); } + left_page_no = btr_page_get_prev( buf_block_get_frame(block)); rw_lock_s_unlock(&block->lock); @@ -449,11 +452,28 @@ btr_cur_optimistic_latch_leaves( const page_id_t page_id( dict_index_get_space(cursor->index), left_page_no); + ulint curr_page_no = block->page.id.page_no(); + dberr_t err = DB_SUCCESS; - cursor->left_block = btr_block_get( + cursor->left_block = buf_page_get_gen( page_id, dict_table_page_size(cursor->index->table), - mode, cursor->index, mtr); + mode, NULL, BUF_GET_POSSIBLY_FREED, + __FILE__, __LINE__, mtr, &err); + + if (err == DB_DECRYPTION_FAILED) { + cursor->index->table->file_unreadable = true; + } + + if (UNIV_UNLIKELY(btr_page_get_next( + cursor->left_block->frame) + != curr_page_no)) { + /* release the left block */ + btr_leaf_page_release( + cursor->left_block, mode, mtr); + cursor->left_block = NULL; + goto unpin_failed; + } } else { cursor->left_block = NULL; } @@ -476,11 +496,8 @@ btr_cur_optimistic_latch_leaves( btr_leaf_page_release(cursor->left_block, mode, mtr); } -unpin_failed: - /* unpin the block */ - buf_block_buf_fix_dec(block); - return(false); + goto unpin_failed; default: ut_error; return(false); |