diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2022-08-01 11:25:50 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2022-08-01 11:25:50 +0300 |
commit | 63478e72de6940abae6bb2d3b35c9b1ffa7180d9 (patch) | |
tree | 7bc8dd9428d34a2c8772ea92f55fdc05698db7a9 /storage/innobase/include/rem0rec.inl | |
parent | a6f7c8edc9b8c394662e06df7421eb6215ced0d3 (diff) | |
download | mariadb-git-63478e72de6940abae6bb2d3b35c9b1ffa7180d9.tar.gz |
MDEV-21098: Assertion failure in rec_get_offsets_func()
The function rec_get_offsets_func() used to hit ut_error
due to an invalid rec_get_status() value of a
ROW_FORMAT!=REDUNDANT record. This fix is twofold:
We will not only avoid a crash on corruption in this case,
but we will also make more effort to validate each record
every time we are iterating over index page records.
rec_get_offsets_func(): Do not crash on a corrupted record.
page_rec_get_nth(): Return nullptr on error.
page_dir_slot_get_rec_validate(): Like page_dir_slot_get_rec(),
but validate the pointer and return nullptr on error.
page_cur_search_with_match(), page_cur_search_with_match_bytes(),
page_dir_split_slot(), page_cur_move_to_next():
Indicate failure in a return value.
page_cur_search(): Replaced with page_cur_search_with_match().
rec_get_next_ptr_const(), rec_get_next_ptr(): Replaced with
page_rec_get_next_low().
TODO: rtr_page_split_initialize_nodes(), rtr_update_mbr_field(),
and possibly other SPATIAL INDEX functions fail to properly handle
errors.
Reviewed by: Thirunarayanan Balathandayuthapani
Tested by: Matthias Leich
Performance tested by: Axel Schwenke
Diffstat (limited to 'storage/innobase/include/rem0rec.inl')
-rw-r--r-- | storage/innobase/include/rem0rec.inl | 72 |
1 files changed, 1 insertions, 71 deletions
diff --git a/storage/innobase/include/rem0rec.inl b/storage/innobase/include/rem0rec.inl index 30c72a7415a..46c209cbdec 100644 --- a/storage/innobase/include/rem0rec.inl +++ b/storage/innobase/include/rem0rec.inl @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2019, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2022, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -204,76 +204,6 @@ rec_set_bit_field_2( } /******************************************************//** -The following function is used to get the pointer of the next chained record -on the same page. -@return pointer to the next chained record, or NULL if none */ -UNIV_INLINE -const rec_t* -rec_get_next_ptr_const( -/*===================*/ - const rec_t* rec, /*!< in: physical record */ - ulint comp) /*!< in: nonzero=compact page format */ -{ - ulint field_value; - - compile_time_assert(REC_NEXT_MASK == 0xFFFFUL); - compile_time_assert(REC_NEXT_SHIFT == 0); - - field_value = mach_read_from_2(rec - REC_NEXT); - - if (field_value == 0) { - - return(NULL); - } - - if (comp) { -#if UNIV_PAGE_SIZE_MAX <= 32768 - /* Note that for 64 KiB pages, field_value can 'wrap around' - and the debug assertion is not valid */ - - /* In the following assertion, field_value is interpreted - as signed 16-bit integer in 2's complement arithmetics. - If all platforms defined int16_t in the standard headers, - the expression could be written simpler as - (int16_t) field_value + ut_align_offset(...) < srv_page_size - */ - ut_ad((field_value >= 32768 - ? field_value - 65536 - : field_value) - + ut_align_offset(rec, srv_page_size) - < srv_page_size); -#endif - /* There must be at least REC_N_NEW_EXTRA_BYTES + 1 - between each record. */ - ut_ad((field_value > REC_N_NEW_EXTRA_BYTES - && field_value < 32768) - || field_value < (uint16) -REC_N_NEW_EXTRA_BYTES); - - return((byte*) ut_align_down(rec, srv_page_size) - + ut_align_offset(rec + field_value, srv_page_size)); - } else { - ut_ad(field_value < srv_page_size); - - return((byte*) ut_align_down(rec, srv_page_size) - + field_value); - } -} - -/******************************************************//** -The following function is used to get the pointer of the next chained record -on the same page. -@return pointer to the next chained record, or NULL if none */ -UNIV_INLINE -rec_t* -rec_get_next_ptr( -/*=============*/ - rec_t* rec, /*!< in: physical record */ - ulint comp) /*!< in: nonzero=compact page format */ -{ - return(const_cast<rec_t*>(rec_get_next_ptr_const(rec, comp))); -} - -/******************************************************//** The following function is used to get the offset of the next chained record on the same page. @return the page offset of the next chained record, or 0 if none */ |