MDEV-22190 InnoDB: Apparent corruption of an index page ... to be written

An InnoDB check for the validity of index pages would occasionally fail
in the test encryption.innodb_encryption_discard_import.

An analysis of a "rr replay" failure trace revealed that the problem
basically is a combination of two old anomalies, and a recently
implemented optimization in MariaDB 10.5.

MDEV-15528 allows InnoDB to discard buffer pool pages that were freed.

PageBulk::init() will disable the InnoDB validity check, because
during native ALTER TABLE (rebuilding tables or creating indexes)
we could write inconsistent index pages to data files.

In the occasional test failure, page 8:6 would have been written
from the buffer pool to the data file and subsequently freed.

However, fil_crypt_thread may perform dummy writes to pages that
have been freed. In case we are causing an inconsistent page to
be re-encrypted on page flush, we should disable the check.

In the analyzed "rr replay" trace, a fil_crypt_thread attempted
to access page 8:6 twice after it had been freed.
On the first call, buf_page_get_gen(..., BUF_PEEK_IF_IN_POOL, ...)
returned NULL. The second call succeeded, and shortly thereafter,
the server intentionally crashed due to writing the corrupted page.
This commit is contained in:
Marko Mäkelä 2020-06-13 11:59:34 +03:00
parent 114a843669
commit 574ef38005

View file

@ -1784,6 +1784,12 @@ fil_crypt_rotate_page(
mtr.write<1,mtr_t::FORCED>(*block,
&frame[FIL_PAGE_SPACE_ID],
frame[FIL_PAGE_SPACE_ID]);
/* This may be a freed page. Until
MDEV-21347 has been fixed, a page on which
BtrBulk::finish() invoked btr_page_free() may
be an inconsistent B-tree page. For now,
let us disable the flush-time check. */
block->skip_flush_check = true;
/* statistics */
state->crypt_stat.pages_modified++;