diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-01-02 16:11:55 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-01-02 16:11:55 +0200 |
commit | d67e17bb812ac1198d916aed3da8573d0f620fb5 (patch) | |
tree | 29f401e06b8365ed07e87aea8599888832b09bc6 /storage | |
parent | 734c587f684828fc4ffa725cb75375ac8fc65cd4 (diff) | |
download | mariadb-git-d67e17bb812ac1198d916aed3da8573d0f620fb5.tar.gz |
MDEV-24512 Assertion failed in rec_is_metadata() in btr_discard_only_page_on_level()
btr_discard_only_page_on_level(): Attempt to read the MDEV-15562 metadata
record from the leaf page, not the root page. In the root, the leftmost
(in this case, the only) node pointer would look like a metadata record.
This corruption bug was introduced in
commit 0e5a4ac2532c64a545796c787354dc41d61d0e62 (MDEV-15562).
The scenario is rare: a column was dropped instantly or the order of
columns was changed instantly, and then the table became empty in such
a way that in the last step, the root page had one child page.
Normally, a non-leaf B-tree page would always contain at least 2 children.
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/btr/btr0btr.cc | 8 |
1 files changed, 3 insertions, 5 deletions
diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 8ee7d167805..2bda1ad372d 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -4094,12 +4094,13 @@ btr_discard_only_page_on_level( mtr_t* mtr) /*!< in: mtr */ { ulint page_level = 0; - trx_id_t max_trx_id; ut_ad(!index->is_dummy); /* Save the PAGE_MAX_TRX_ID from the leaf page. */ - max_trx_id = page_get_max_trx_id(buf_block_get_frame(block)); + const trx_id_t max_trx_id = page_get_max_trx_id(block->frame); + const rec_t* r = page_rec_get_next(page_get_infimum_rec(block->frame)); + ut_ad(rec_is_metadata(r, *index) == index->is_instant()); while (block->page.id.page_no() != dict_index_get_page(index)) { btr_cur_t cursor; @@ -4154,9 +4155,6 @@ btr_discard_only_page_on_level( const rec_t* rec = NULL; rec_offs* offsets = NULL; if (index->table->instant) { - const rec_t* r = page_rec_get_next(page_get_infimum_rec( - block->frame)); - ut_ad(rec_is_metadata(r, *index) == index->is_instant()); if (rec_is_alter_metadata(r, *index)) { heap = mem_heap_create(srv_page_size); offsets = rec_get_offsets(r, index, NULL, true, |