summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2020-07-23 16:59:30 +0530
committerThirunarayanan Balathandayuthapani <thiru@mariadb.com>2020-07-24 20:32:27 +0530
commit5f1ec5cbb78a427ff260888bef5e19daa36b10e2 (patch)
tree73987cc587176279cd9de567bfa1aef1c2b1509d
parenta3a249c72f07bf3270c059f60f68df030179f104 (diff)
downloadmariadb-git-5f1ec5cbb78a427ff260888bef5e19daa36b10e2.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)
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.cc22
1 files changed, 20 insertions, 2 deletions
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 35e578e1a5c..bacc05686e9 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -415,6 +415,7 @@ btr_cur_optimistic_latch_leaves(
{
ulint mode;
ulint left_page_no;
+ ulint curr_page_no;
switch (*latch_mode) {
case BTR_SEARCH_LEAF:
@@ -441,6 +442,8 @@ btr_cur_optimistic_latch_leaves(
goto unpin_failed;
}
+
+ curr_page_no = block->page.id.page_no();
left_page_no = btr_page_get_prev(
buf_block_get_frame(block));
rw_lock_s_unlock(&block->lock);
@@ -449,11 +452,26 @@ btr_cur_optimistic_latch_leaves(
const page_id_t page_id(
dict_index_get_space(cursor->index),
left_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 (btr_page_get_next(buf_block_get_frame(
+ cursor->left_block))
+ != curr_page_no) {
+ /* release the left block */
+ btr_leaf_page_release(
+ cursor->left_block, mode, mtr);
+ return false;
+ }
} else {
cursor->left_block = NULL;
}