From 72b934e3f7d5f0c717cb98b718c9529c74741b4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 22 Mar 2019 19:21:07 +0200 Subject: [PATCH] MDEV-14126: Detect unexpected emptying of B-tree pages If an index page becomes empty, btr_page_empty() should be called. --- storage/innobase/include/page0page.ic | 5 +++-- storage/innobase/page/page0cur.cc | 2 ++ storage/innobase/page/page0page.cc | 1 + storage/innobase/page/page0zip.cc | 6 ++++-- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic index d1efca1d244..11d5e2d1854 100644 --- a/storage/innobase/include/page0page.ic +++ b/storage/innobase/include/page0page.ic @@ -173,8 +173,9 @@ page_header_set_field( { ut_ad(page); ut_ad(field <= PAGE_N_RECS); - ut_ad(field == PAGE_N_HEAP || val < UNIV_PAGE_SIZE); - ut_ad(field != PAGE_N_HEAP || (val & 0x7fff) < UNIV_PAGE_SIZE); + ut_ad(field != PAGE_N_RECS || val); + ut_ad(field == PAGE_N_HEAP || val < srv_page_size); + ut_ad(field != PAGE_N_HEAP || (val & 0x7fff) < srv_page_size); mach_write_to_2(page + PAGE_HEADER + field, val); if (page_zip) { diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc index ae46d1e71ce..561f053710f 100644 --- a/storage/innobase/page/page0cur.cc +++ b/storage/innobase/page/page0cur.cc @@ -2140,6 +2140,8 @@ page_copy_rec_list_end_to_created_page( rec = page_rec_get_next(rec); } while (!page_rec_is_supremum(rec)); + ut_ad(n_recs); + if ((slot_index > 0) && (count + 1 + (PAGE_DIR_SLOT_MAX_N_OWNED + 1) / 2 <= PAGE_DIR_SLOT_MAX_N_OWNED)) { diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc index be426ec4927..2f3879dda08 100644 --- a/storage/innobase/page/page0page.cc +++ b/storage/innobase/page/page0page.cc @@ -1231,6 +1231,7 @@ delete_all: page_header_set_field(page, NULL, PAGE_GARBAGE, size + page_header_get_field(page, PAGE_GARBAGE)); + ut_ad(page_get_n_recs(page) > n_recs); page_header_set_field(page, NULL, PAGE_N_RECS, (ulint)(page_get_n_recs(page) - n_recs)); } diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc index 811b5d88947..001d33662d1 100644 --- a/storage/innobase/page/page0zip.cc +++ b/storage/innobase/page/page0zip.cc @@ -4448,10 +4448,12 @@ page_zip_dir_delete( slot_rec = page_zip_dir_find(page_zip, page_offset(rec)); ut_a(slot_rec); - + uint16_t n_recs = page_get_n_recs(page); + ut_ad(n_recs); + ut_ad(n_recs > 1 || page_get_page_no(page) == index->page); /* This could not be done before page_zip_dir_find(). */ page_header_set_field(page, page_zip, PAGE_N_RECS, - (ulint)(page_get_n_recs(page) - 1)); + n_recs - 1); if (UNIV_UNLIKELY(!free)) { /* Make the last slot the start of the free list. */