Uploaded image for project: 'MariaDB Server'
  1. MariaDB Server
  2. MDEV-20562

btr_cur_open_at_rnd_pos() fails to return error for corrupted page



      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(
      - exit_loop:
       	if (UNIV_LIKELY_NULL(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).


          Issue Links



              • Assignee:
                marko Marko Mäkelä
                marko Marko Mäkelä
              • Votes:
                0 Vote for this issue
                1 Start watching this issue


                • Created: