diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2018-11-30 12:40:03 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2018-11-30 12:40:03 +0200 |
commit | e46a3aa42e1d391cef30881809d8b0d5416489c0 (patch) | |
tree | 5338e9127679114a88c2a85d2b64fa9225313007 | |
parent | 0abd2766b1b82b03a259bae4df0d1c2dc5a5a69d (diff) | |
download | mariadb-git-e46a3aa42e1d391cef30881809d8b0d5416489c0.tar.gz |
MDEV-17881 Assertion failure in cmp_dtuple_rec_with_match_bytes after instant ADD COLUMN
The special flag REC_INFO_MIN_REC_FLAG used to be only set on the
first record in the leftmost node pointer page of each level of the tree.
It was never set on leaf pages.
MDEV-11369 Instant ADD COLUMN in MariaDB Server 10.3 repurposed the flag
to identify a hidden metadata record, which is stored in the first record
on the leftmost leaf page.
If the adaptive hash index points to records in the leftmost leaf page
after instant ALTER TABLE, we would have such a metadata record in the
table, an assertion could fail when trying to validate the index record.
In a release build, we might wrongly qualify the hidden metadata record
and thus return garbage results.
cmp_dtuple_rec_with_match_bytes(): If the REC_INFO_MIN_REC_FLAG is
set on the record, assert that this is the first record on the
leftmost page and that the record is a metadata record, and finally
return 1, because by definition, anything is greater than the
minimum record.
-rw-r--r-- | storage/innobase/rem/rem0cmp.cc | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/storage/innobase/rem/rem0cmp.cc b/storage/innobase/rem/rem0cmp.cc index f8449e5443f..623d0bd1aa9 100644 --- a/storage/innobase/rem/rem0cmp.cc +++ b/storage/innobase/rem/rem0cmp.cc @@ -25,6 +25,7 @@ Created 7/1/1994 Heikki Tuuri #include "rem0cmp.h" #include "rem0rec.h" +#include "page0page.h" #include "dict0mem.h" #include "handler0alter.h" @@ -787,20 +788,23 @@ cmp_dtuple_rec_with_match_bytes( ulint* matched_fields, ulint* matched_bytes) { - ulint n_cmp = dtuple_get_n_fields_cmp(dtuple); - ulint cur_field; /* current field number */ - ulint cur_bytes; - int ret; /* return value */ - ut_ad(dtuple_check_typed(dtuple)); ut_ad(rec_offs_validate(rec, index, offsets)); ut_ad(!(REC_INFO_MIN_REC_FLAG & dtuple_get_info_bits(dtuple))); - ut_ad(!(REC_INFO_MIN_REC_FLAG - & rec_get_info_bits(rec, rec_offs_comp(offsets)))); - cur_field = *matched_fields; - cur_bytes = *matched_bytes; + if (UNIV_UNLIKELY(REC_INFO_MIN_REC_FLAG + & rec_get_info_bits(rec, rec_offs_comp(offsets)))) { + ut_ad(page_rec_is_first(rec, page_align(rec))); + ut_ad(!page_has_prev(page_align(rec))); + ut_ad(rec_is_metadata(rec, *index)); + return 1; + } + + ulint cur_field = *matched_fields; + ulint cur_bytes = *matched_bytes; + ulint n_cmp = dtuple_get_n_fields_cmp(dtuple); + int ret; ut_ad(n_cmp <= dtuple_get_n_fields(dtuple)); ut_ad(cur_field <= n_cmp); |