Skip to content

Commit

Permalink
MDEV-20813: Do not rotate keys for unallocated pages
Browse files Browse the repository at this point in the history
fil_crypt_rotate_page(): Skip the key rotation for pages that carry 0
in FIL_PAGE_TYPE. This avoids not only unnecessary writes, but also
failures of the recently added debug assertion in
buf_flush_init_for_writing() that the FIL_PAGE_TYPE should be nonzero.

Note: the debug assertion can fail if the file was originally created
before MySQL 5.5. In old InnoDB versions, FIL_PAGE_TYPE was only
initialized for B-tree pages, to FIL_PAGE_INDEX. For any other pages,
the field could be garbage, including FIL_PAGE_INDEX. In MariaDB 10.2
and later, buf_flush_init_for_writing() would initialize the
FIL_PAGE_TYPE on such old pages, but only after passing the debug
assertion that insists that pages have a nonzero FIL_PAGE_TYPE.
Thus, the debug assertion at the start of buf_flush_init_for_writing()
can fail when upgrading from very old debug files. This assertion is
only present in debug builds, not release builds.
  • Loading branch information
dr-m committed Oct 14, 2019
1 parent 4f9f3f1 commit f989c0c
Showing 1 changed file with 17 additions and 8 deletions.
25 changes: 17 additions & 8 deletions storage/innobase/fil/fil0crypt.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1773,8 +1773,6 @@ fil_crypt_rotate_page(
return;
}

ut_d(const bool was_free = fseg_page_is_free(space, offset));

mtr_t mtr;
mtr.start();
if (buf_block_t* block = fil_crypt_get_page_throttle(state,
Expand All @@ -1789,9 +1787,9 @@ fil_crypt_rotate_page(
if (space->is_stopping()) {
/* The tablespace is closing (in DROP TABLE or
TRUNCATE TABLE or similar): avoid further access */
} else if (!*reinterpret_cast<uint32_t*>(FIL_PAGE_OFFSET
+ frame)) {
/* It looks like this page was never
} else if (!kv && !*reinterpret_cast<uint16_t*>
(&frame[FIL_PAGE_TYPE])) {
/* It looks like this page is not
allocated. Because key rotation is accessing
pages in a pattern that is unlike the normal
B-tree and undo log access pattern, we cannot
Expand All @@ -1801,9 +1799,20 @@ fil_crypt_rotate_page(
tablespace latch before acquiring block->lock,
then the fseg_page_is_free() information
could be stale already. */
ut_ad(was_free);
ut_ad(kv == 0);
ut_ad(page_get_space_id(frame) == 0);

/* If the data file was originally created
before MariaDB 10.0 or MySQL 5.6, some
allocated data pages could carry 0 in
FIL_PAGE_TYPE. The FIL_PAGE_TYPE on those
pages will be updated in
buf_flush_init_for_writing() when the page
is modified the next time.
Also, when the doublewrite buffer pages are
allocated on bootstrap in a non-debug build,
some dummy pages will be allocated, with 0 in
the FIL_PAGE_TYPE. Those pages should be
skipped from key rotation forever. */
} else if (fil_crypt_needs_rotation(
crypt_data,
kv,
Expand Down

0 comments on commit f989c0c

Please sign in to comment.