MDEV-26631 InnoDB fails to fetch page from doublewrite buffer

Problem:
========
InnoDB fails to fetch the page0 from dblwr if page0 is
corrupted.In that case, InnoDB defers the tablespace
and doesn't find the INIT_PAGE redo log record for page0
and it leads to failure.

Solution:
=========
 InnoDB should recover page0 from dblwr if space_id can
be found for deferred tablespace.
parent d9536110
......@@ -65,6 +65,7 @@ where name = 'test/t1';
# Ensure that dirty pages of table t1 is flushed.
flush tables t1 for export;
unlock tables;
set global innodb_log_checkpoint_now=1;
begin;
insert into t1 values (6, repeat('%', 12));
# Make the first page dirty for table t1
......
......@@ -159,6 +159,8 @@ where name = 'test/t1';
flush tables t1 for export;
unlock tables;
set global innodb_log_checkpoint_now=1;
begin;
insert into t1 values (6, repeat('%', 12));
......
......@@ -400,10 +400,19 @@ Datafile::validate_for_recovery()
err = validate_first_page(0);
switch (err) {
case DB_SUCCESS:
case DB_TABLESPACE_EXISTS:
break;
case DB_SUCCESS:
if (!m_defer || !m_space_id) {
break;
}
/* InnoDB should check whether the deferred
tablespace page0 can be recovered from
double write buffer. InnoDB should try
to recover only if m_space_id exists because
dblwr pages can be searched via {space_id, 0}.
m_space_id is set in read_first_page(). */
/* fall through */
default:
/* Re-open the file in read-write mode Attempt to restore
page 0 from doublewrite and read the space ID from a survey
......@@ -414,23 +423,30 @@ Datafile::validate_for_recovery()
return(err);
}
if (!m_defer) {
err = find_space_id();
if (err != DB_SUCCESS || m_space_id == 0) {
ib::error() << "Datafile '" << m_filepath << "' is"
" corrupted. Cannot determine the space ID from"
" the first 64 pages.";
ib::error() << "Datafile '" << m_filepath
<< "' is corrupted. Cannot determine "
"the space ID from the first 64 pages.";
return(err);
}
}
if (m_space_id == ULINT_UNDEFINED) {
return DB_SUCCESS; /* empty file */
}
if (restore_from_doublewrite()) {
if (m_defer) {
return err;
}
return(DB_CORRUPTION);
}
/* Free the previously read first page and then re-validate. */
free_first_page();
m_defer = false;
err = validate_first_page(0);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment