diff options
author | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2021-11-15 18:19:53 +0530 |
---|---|---|
committer | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2021-11-29 21:31:58 +0530 |
commit | cab8f4b552d234c8642f87fae28ecb098392c381 (patch) | |
tree | 4d472d1ab37818b13a4d964a5decb467bd078434 | |
parent | 5f22e83a295c0439f1c73a6f666a3b58f2397632 (diff) | |
download | mariadb-git-cab8f4b552d234c8642f87fae28ecb098392c381.tar.gz |
MDEV-27014 InnoDB fails to restore page 0 from the doublewrite buffer
InnoDB fails to restore page0 from doublewrite buffer when the
tablespace is being deferred. In that case, InnoDB doesn't find
INIT_PAGE redo log record for page0 and it leads to failure.
InnoDB should recovery page0 from doublewrite buffer.
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 2 | ||||
-rw-r--r-- | storage/innobase/fsp/fsp0file.cc | 32 | ||||
-rw-r--r-- | storage/innobase/include/fsp0file.h | 3 |
3 files changed, 26 insertions, 11 deletions
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 681cee32fd5..00ee1c71981 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -2576,7 +2576,7 @@ fil_ibd_load( /* Read and validate the first page of the tablespace. Assign a tablespace name based on the tablespace type. */ - switch (file.validate_for_recovery()) { + switch (file.validate_for_recovery(&space_id)) { os_offset_t minimum_size; case DB_SUCCESS: deferred_space = file.m_defer; diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc index 9a552e6dc5c..fbf87843550 100644 --- a/storage/innobase/fsp/fsp0file.cc +++ b/storage/innobase/fsp/fsp0file.cc @@ -387,10 +387,11 @@ exist and be successfully opened. We initially open it in read-only mode because we just want to read the SpaceID. However, if the first page is corrupt and needs to be restored from the doublewrite buffer, we will reopen it in write mode and ry to restore that page. +@param space_id space id to validate for recovery @retval DB_SUCCESS if tablespace is valid, DB_ERROR if not. m_is_valid is also set true on success, else false. */ dberr_t -Datafile::validate_for_recovery() +Datafile::validate_for_recovery(ulint *space_id) { dberr_t err; @@ -433,15 +434,25 @@ Datafile::validate_for_recovery() } } - if (m_space_id == ULINT_UNDEFINED) { - return DB_SUCCESS; /* empty file */ + bool empty_tablespace= (m_space_id == ULINT_UNDEFINED); + if (empty_tablespace && space_id) { + /* Set space id to find out whether + the page exist in double write buffer */ + m_space_id = *space_id; } if (restore_from_doublewrite()) { - if (m_defer) { + if (!m_defer) { + return DB_CORRUPTION; + } else if (!empty_tablespace) { return err; + } else { + /* Reset the space id. InnoDB + could rebuild the page0 + from redo log */ + m_space_id = ULINT_UNDEFINED; + return DB_SUCCESS; /* empty file */ } - return(DB_CORRUPTION); } /* Free the previously read first page and then re-validate. */ @@ -769,10 +780,13 @@ Datafile::restore_from_doublewrite() in the doublewrite buffer, then the recovery is going to fail now. Hence this is treated as an error. */ - ib::error() - << "Corrupted page " << page_id - << " of datafile '" << m_filepath - << "' could not be found in the doublewrite buffer."; + if (!m_defer) { + ib::error() + << "Corrupted page " << page_id + << " of datafile '" << m_filepath + << "' could not be found in the " + << "doublewrite buffer."; + } return(true); } diff --git a/storage/innobase/include/fsp0file.h b/storage/innobase/include/fsp0file.h index 8c11d61c5aa..5978e2d0576 100644 --- a/storage/innobase/include/fsp0file.h +++ b/storage/innobase/include/fsp0file.h @@ -207,9 +207,10 @@ public: However, if the first page is corrupt and needs to be restored from the doublewrite buffer, we will reopen it in write mode and ry to restore that page. + @param space_id space id to validate for recovery @retval DB_SUCCESS if tablespace is valid, DB_ERROR if not. m_is_valid is also set true on success, else false. */ - dberr_t validate_for_recovery() + dberr_t validate_for_recovery(ulint *space_id=nullptr) MY_ATTRIBUTE((warn_unused_result)); /** Checks the consistency of the first page of a datafile when the |