summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-03-22 19:21:07 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2019-03-25 10:53:01 +0200
commit72b934e3f7d5f0c717cb98b718c9529c74741b4a (patch)
treec795b0f60d0d139ee29f71a701409f7c6534ccdf
parenta4d0d6828bb46c1a1b0049ebfd9c5c136a7a7862 (diff)
downloadmariadb-git-72b934e3f7d5f0c717cb98b718c9529c74741b4a.tar.gz
MDEV-14126: Detect unexpected emptying of B-tree pages
If an index page becomes empty, btr_page_empty() should be called.
-rw-r--r--storage/innobase/include/page0page.ic5
-rw-r--r--storage/innobase/page/page0cur.cc2
-rw-r--r--storage/innobase/page/page0page.cc1
-rw-r--r--storage/innobase/page/page0zip.cc6
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. */