summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-11-30 12:40:03 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2018-11-30 12:40:03 +0200
commite46a3aa42e1d391cef30881809d8b0d5416489c0 (patch)
tree5338e9127679114a88c2a85d2b64fa9225313007
parent0abd2766b1b82b03a259bae4df0d1c2dc5a5a69d (diff)
downloadmariadb-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.cc22
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);