summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2023-02-16 08:28:14 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2023-02-16 08:28:14 +0200
commit9c15799462d6a2673a6158eb1717d222c07cced4 (patch)
tree26c401f3f76f3cb994942f58147d0fb010c54ddf
parentcc27e5fd0e3fd9eec3feb7f52685a3de7c0b4a57 (diff)
downloadmariadb-git-9c15799462d6a2673a6158eb1717d222c07cced4.tar.gz
MDEV-30397: MariaDB crash due to DB_FAIL reported for a corrupted page
buf_read_page_low(): Map the buf_page_t::read_complete() return value DB_FAIL to DB_PAGE_CORRUPTED. The purpose of the DB_FAIL return value is to avoid error log noise when read-ahead brings in an unused page that is typically filled with NUL bytes. If a synchronous read is bringing in a corrupted page where the page frame does not contain the expected tablespace identifier and page number, that must be treated as an attempt to read a corrupted page. The correct error code for this is DB_PAGE_CORRUPTED. The error code DB_FAIL is not handled by row_mysql_handle_errors(). This was missed in commit 0b47c126e31cddda1e94588799599e138400bcf8 (MDEV-13542).
-rw-r--r--storage/innobase/buf/buf0buf.cc6
-rw-r--r--storage/innobase/buf/buf0rea.cc3
-rw-r--r--storage/innobase/include/buf0buf.h3
3 files changed, 8 insertions, 4 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 644d8680484..b17c49ab751 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -3449,8 +3449,7 @@ or decrypt/decompress just failed.
@retval DB_SUCCESS if page has been read and is not corrupted
@retval DB_PAGE_CORRUPTED if page based on checksum check is corrupted
@retval DB_DECRYPTION_FAILED if page post encryption checksum matches but
-after decryption normal page checksum does not match.
-@retval DB_TABLESPACE_DELETED if accessed tablespace is not found */
+after decryption normal page checksum does not match. */
static dberr_t buf_page_check_corrupt(buf_page_t *bpage,
const fil_node_t &node)
{
@@ -3507,7 +3506,8 @@ static dberr_t buf_page_check_corrupt(buf_page_t *bpage,
@param node data file
@return whether the operation succeeded
@retval DB_PAGE_CORRUPTED if the checksum fails
-@retval DB_DECRYPTION_FAILED if the page cannot be decrypted */
+@retval DB_DECRYPTION_FAILED if the page cannot be decrypted
+@retval DB_FAIL if the page contains the wrong ID */
dberr_t buf_page_t::read_complete(const fil_node_t &node)
{
const page_id_t expected_id{id()};
diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc
index 2f15fa62796..b20b105a4c4 100644
--- a/storage/innobase/buf/buf0rea.cc
+++ b/storage/innobase/buf/buf0rea.cc
@@ -331,6 +331,9 @@ nothing_read:
/* The i/o was already completed in space->io() */
*err = bpage->read_complete(*fio.node);
space->release();
+ if (*err == DB_FAIL) {
+ *err = DB_PAGE_CORRUPTED;
+ }
}
return true;
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index d33c5513dc5..b4d8c8b76ac 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -773,7 +773,8 @@ public:
@param node data file
@return whether the operation succeeded
@retval DB_PAGE_CORRUPTED if the checksum fails
- @retval DB_DECRYPTION_FAILED if the page cannot be decrypted */
+ @retval DB_DECRYPTION_FAILED if the page cannot be decrypted
+ @retval DB_FAIL if the page contains the wrong ID */
dberr_t read_complete(const fil_node_t &node);
/** Note that a block is no longer dirty, while not removing