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'; ...@@ -65,6 +65,7 @@ where name = 'test/t1';
# Ensure that dirty pages of table t1 is flushed. # Ensure that dirty pages of table t1 is flushed.
flush tables t1 for export; flush tables t1 for export;
unlock tables; unlock tables;
set global innodb_log_checkpoint_now=1;
begin; begin;
insert into t1 values (6, repeat('%', 12)); insert into t1 values (6, repeat('%', 12));
# Make the first page dirty for table t1 # Make the first page dirty for table t1
......
...@@ -159,6 +159,8 @@ where name = 'test/t1'; ...@@ -159,6 +159,8 @@ where name = 'test/t1';
flush tables t1 for export; flush tables t1 for export;
unlock tables; unlock tables;
set global innodb_log_checkpoint_now=1;
begin; begin;
insert into t1 values (6, repeat('%', 12)); insert into t1 values (6, repeat('%', 12));
......
...@@ -400,10 +400,19 @@ Datafile::validate_for_recovery() ...@@ -400,10 +400,19 @@ Datafile::validate_for_recovery()
err = validate_first_page(0); err = validate_first_page(0);
switch (err) { switch (err) {
case DB_SUCCESS:
case DB_TABLESPACE_EXISTS: case DB_TABLESPACE_EXISTS:
break; 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: default:
/* Re-open the file in read-write mode Attempt to restore /* Re-open the file in read-write mode Attempt to restore
page 0 from doublewrite and read the space ID from a survey page 0 from doublewrite and read the space ID from a survey
...@@ -414,23 +423,30 @@ Datafile::validate_for_recovery() ...@@ -414,23 +423,30 @@ Datafile::validate_for_recovery()
return(err); return(err);
} }
err = find_space_id(); if (!m_defer) {
if (err != DB_SUCCESS || m_space_id == 0) { err = find_space_id();
ib::error() << "Datafile '" << m_filepath << "' is" if (err != DB_SUCCESS || m_space_id == 0) {
" corrupted. Cannot determine the space ID from" ib::error() << "Datafile '" << m_filepath
" the first 64 pages."; << "' is corrupted. Cannot determine "
return(err); "the space ID from the first 64 pages.";
return(err);
}
} }
if (m_space_id == ULINT_UNDEFINED) { if (m_space_id == ULINT_UNDEFINED) {
return DB_SUCCESS; /* empty file */ return DB_SUCCESS; /* empty file */
} }
if (restore_from_doublewrite()) { if (restore_from_doublewrite()) {
if (m_defer) {
return err;
}
return(DB_CORRUPTION); return(DB_CORRUPTION);
} }
/* Free the previously read first page and then re-validate. */ /* Free the previously read first page and then re-validate. */
free_first_page(); free_first_page();
m_defer = false;
err = validate_first_page(0); 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