Skip to content

Commit

Permalink
MDEV-26631 InnoDB fails to fetch page from doublewrite buffer
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Thirunarayanan committed Sep 24, 2021
1 parent d953611 commit 7697216
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 8 deletions.
1 change: 1 addition & 0 deletions mysql-test/suite/innodb/r/doublewrite.result
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions mysql-test/suite/innodb/t/doublewrite.test
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down
32 changes: 24 additions & 8 deletions storage/innobase/fsp/fsp0file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -414,23 +423,30 @@ Datafile::validate_for_recovery()
return(err);
}

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.";
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.";
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);
}

Expand Down

0 comments on commit 7697216

Please sign in to comment.