[MDEV-20562] btr_cur_open_at_rnd_pos() fails to return error for corrupted page Created: 2019-09-11  Updated: 2019-09-11  Resolved: 2019-09-11

Status: Closed
Project: MariaDB Server
Component/s: Storage Engine - InnoDB
Affects Version/s: 5.5, 10.1, 10.2, 10.3, 10.4, 10.5
Fix Version/s: 10.2.28, 10.3.19, 10.4.9

Type: Bug Priority: Major
Reporter: Marko Mäkelä Assignee: Marko Mäkelä
Resolution: Fixed Votes: 0
Labels: corruption, crash, statistics

Issue Links:
Relates
relates to MDEV-6113 merge 5.7 innodb Closed
relates to MDEV-8588 Assertion failure in file ha_innodb.c... Closed
relates to MDEV-12353 Efficient InnoDB redo log record format Closed

 Description   

In a bug fix in MySQL 5.7.6, the InnoDB function btr_cur_open_at_rnd_pos() was corrected so that it would return a status that indicates whether the cursor was successfully positioned. But this change was not correctly merged to MariaDB (Merge MySQL 5.7.9, part of MDEV-6113). That is, in the code path that was introduced in MDEV-8588, we would wrongly return success. The following patch fixes the problem:

diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index 349ae990edb..b23cacac227 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -2658,7 +2658,7 @@ btr_cur_open_at_rnd_pos_func(
 				index->table->file_unreadable = true;
 			}
 
-			goto exit_loop;
+			break;
 		}
 
 		page = buf_block_get_frame(block);
@@ -2815,12 +2815,11 @@ btr_cur_open_at_rnd_pos_func(
 		n_blocks++;
 	}
 
- exit_loop:
 	if (UNIV_LIKELY_NULL(heap)) {
 		mem_heap_free(heap);
 	}
 
-	return(true);
+	return err == DB_SUCCESS;
 }
 
 /*==================== B-TREE INSERT =========================*/

This problem was accidentally found by frequent crashes of the test innodb.leaf_page_corrupted_during_recovery after removing the function page_copy_rec_list_end_to_created_page(), in preparation for MDEV-12353. There is no deterministic test case for this.

The symptoms were as follows:

mysqld: /mariadb/10.5/storage/innobase/btr/btr0cur.cc:7116: ulint btr_rec_get_externally_stored_len(const rec_t*, const ulint*): Assertion `!rec_offs_comp(offsets) || !rec_get_node_ptr_flag(rec)' failed.
#8  0x00005565cd35d2a8 in btr_rec_get_externally_stored_len (rec=0x7fe096f4807e "\200", offsets=0x7fe03c13a9c0) at /mariadb/10.5-merge/storage/innobase/btr/btr0cur.cc:7116
#9  0x00005565cd35cdd6 in btr_estimate_number_of_different_key_vals (index=0x7fe0640123e8) at /mariadb/10.5-merge/storage/innobase/btr/btr0cur.cc:6988
#10 0x00005565cd41a303 in dict_stats_update_transient_for_index (index=0x7fe0640123e8) at /mariadb/10.5-merge/storage/innobase/dict/dict0stats.cc:886
#11 0x00005565cd41a582 in dict_stats_update_transient (table=0x7fe064010658) at /mariadb/10.5-merge/storage/innobase/dict/dict0stats.cc:944
#12 0x00005565cd420701 in dict_stats_update (table=0x7fe064010658, stats_upd_option=DICT_STATS_RECALC_TRANSIENT) at /mariadb/10.5-merge/storage/innobase/dict/dict0stats.cc:3343
#13 0x00005565cd06f481 in dict_stats_init (table=0x7fe064010658) at /mariadb/10.5-merge/storage/innobase/include/dict0stats.ic:165
#14 0x00005565cd079df9 in ha_innobase::open (this=0x7fe03c13b8d0, name=0x7fe03c13efa8 "./test/t1") at /mariadb/10.5-merge/storage/innobase/handler/ha_innodb.cc:6020

The assertion would fail on the very first access on the table, after starting up with innodb_force_recovery=1 (to ignore the corruption that was injected to the leaf page).


Generated at Thu Feb 08 09:00:26 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.