summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-06-27 09:49:49 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2022-06-27 09:49:49 +0300
commitc86b1389de5fe44fbd659bb50d95017bc19324a5 (patch)
tree7e015ea44bd74ec85a1e905aa6f19251002d6182
parent2c1aaa666401140633c26fc0fb7757bda4e8bf88 (diff)
downloadmariadb-git-c86b1389de5fe44fbd659bb50d95017bc19324a5.tar.gz
MDEV-28389: Simplify the InnoDB corrupted page output
buf_page_print(): Dump the buffer page 32 bytes (64 hexadecimal digits) per line. In this way, the limitation in mtr ("Data too long for column 'line'") will not be triggered. Also, do not bother decoding the page contents, because everything is present in the hexadecimal output. dict_index_find_on_id_low(): Merge to dict_index_get_if_in_cache_low(). The direct call in buf_page_print() was prone to crashing, in case the table definition was concurrently evicted or dropped from the data dictionary cache.
-rw-r--r--storage/innobase/buf/buf0buf.cc196
-rw-r--r--storage/innobase/dict/dict0dict.cc58
-rw-r--r--storage/innobase/handler/i_s.cc7
-rw-r--r--storage/innobase/include/dict0dict.h12
4 files changed, 39 insertions, 234 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index aa6a6169db5..70ee0f58dc2 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -2,7 +2,7 @@
Copyright (c) 1995, 2021, Oracle and/or its affiliates.
Copyright (c) 2008, Google Inc.
-Copyright (c) 2013, 2021, MariaDB Corporation.
+Copyright (c) 2013, 2022, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -68,6 +68,7 @@ Created 11/5/1995 Heikki Tuuri
#include <new>
#include <map>
#include <sstream>
+#include "log.h"
#ifndef UNIV_INNOCHECKSUM
#include "fil0pagecompress.h"
#include "fsp0pagecompress.h"
@@ -1222,188 +1223,35 @@ buf_madvise_do_dump()
}
#endif
+static inline byte hex_to_ascii(byte hex_digit)
+{
+ return hex_digit <= 9 ? '0' + hex_digit : ('a' - 10) + hex_digit;
+}
+
/** Dump a page to stderr.
@param[in] read_buf database page
@param[in] page_size page size */
-UNIV_INTERN
-void
-buf_page_print(const byte* read_buf, const page_size_t& page_size)
+ATTRIBUTE_COLD
+void buf_page_print(const byte *read_buf, const page_size_t &page_size)
{
- dict_index_t* index;
-
#ifndef UNIV_DEBUG
- ib::info() << "Page dump in ascii and hex ("
- << page_size.physical() << " bytes):";
+ const size_t size= page_size.physical();
+ const byte * const end= read_buf + size;
+ sql_print_information("InnoDB: Page dump (%zu bytes):", size);
- ut_print_buf(stderr, read_buf, page_size.physical());
- fputs("\nInnoDB: End of page dump\n", stderr);
-#endif
+ do
+ {
+ byte row[64];
- if (page_size.is_compressed()) {
- /* Print compressed page. */
- ib::info() << "Compressed page type ("
- << fil_page_get_type(read_buf)
- << "); stored checksum in field1 "
- << mach_read_from_4(
- read_buf + FIL_PAGE_SPACE_OR_CHKSUM)
- << "; calculated checksums for field1: "
- << buf_checksum_algorithm_name(
- SRV_CHECKSUM_ALGORITHM_CRC32)
- << " "
- << page_zip_calc_checksum(
- read_buf, page_size.physical(),
- SRV_CHECKSUM_ALGORITHM_CRC32)
-#ifdef INNODB_BUG_ENDIAN_CRC32
- << "/"
- << page_zip_calc_checksum(
- read_buf, page_size.physical(),
- SRV_CHECKSUM_ALGORITHM_CRC32, true)
-#endif
- << ", "
- << buf_checksum_algorithm_name(
- SRV_CHECKSUM_ALGORITHM_INNODB)
- << " "
- << page_zip_calc_checksum(
- read_buf, page_size.physical(),
- SRV_CHECKSUM_ALGORITHM_INNODB)
- << ", "
- << buf_checksum_algorithm_name(
- SRV_CHECKSUM_ALGORITHM_NONE)
- << " "
- << page_zip_calc_checksum(
- read_buf, page_size.physical(),
- SRV_CHECKSUM_ALGORITHM_NONE)
- << "; page LSN "
- << mach_read_from_8(read_buf + FIL_PAGE_LSN)
- << "; page number (if stored to page"
- << " already) "
- << mach_read_from_4(read_buf + FIL_PAGE_OFFSET)
- << "; space id (if stored to page already) "
- << mach_read_from_4(
- read_buf + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
+ for (byte *r= row; r != &row[64]; r+= 2, read_buf++)
+ r[0]= hex_to_ascii(*read_buf >> 4), r[1]= hex_to_ascii(*read_buf & 15);
- } else {
- const uint32_t crc32 = buf_calc_page_crc32(read_buf);
-#ifdef INNODB_BUG_ENDIAN_CRC32
- const uint32_t crc32_legacy = buf_calc_page_crc32(read_buf,
- true);
-#endif /* INNODB_BUG_ENDIAN_CRC32 */
- ulint page_type = fil_page_get_type(read_buf);
-
- ib::info() << "Uncompressed page, stored checksum in field1 "
- << mach_read_from_4(
- read_buf + FIL_PAGE_SPACE_OR_CHKSUM)
- << ", calculated checksums for field1: "
- << buf_checksum_algorithm_name(
- SRV_CHECKSUM_ALGORITHM_CRC32) << " "
- << crc32
-#ifdef INNODB_BUG_ENDIAN_CRC32
- << "/" << crc32_legacy
-#endif
- << ", "
- << buf_checksum_algorithm_name(
- SRV_CHECKSUM_ALGORITHM_INNODB) << " "
- << buf_calc_page_new_checksum(read_buf)
- << ", "
- << " page type " << page_type << " == "
- << fil_get_page_type_name(page_type) << "."
- << buf_checksum_algorithm_name(
- SRV_CHECKSUM_ALGORITHM_NONE) << " "
- << BUF_NO_CHECKSUM_MAGIC
- << ", stored checksum in field2 "
- << mach_read_from_4(read_buf + page_size.logical()
- - FIL_PAGE_END_LSN_OLD_CHKSUM)
- << ", calculated checksums for field2: "
- << buf_checksum_algorithm_name(
- SRV_CHECKSUM_ALGORITHM_CRC32) << " "
- << crc32
-#ifdef INNODB_BUG_ENDIAN_CRC32
- << "/" << crc32_legacy
-#endif
- << ", "
- << buf_checksum_algorithm_name(
- SRV_CHECKSUM_ALGORITHM_INNODB) << " "
- << buf_calc_page_old_checksum(read_buf)
- << ", "
- << buf_checksum_algorithm_name(
- SRV_CHECKSUM_ALGORITHM_NONE) << " "
- << BUF_NO_CHECKSUM_MAGIC
- << ", page LSN "
- << mach_read_from_4(read_buf + FIL_PAGE_LSN)
- << " "
- << mach_read_from_4(read_buf + FIL_PAGE_LSN + 4)
- << ", low 4 bytes of LSN at page end "
- << mach_read_from_4(read_buf + page_size.logical()
- - FIL_PAGE_END_LSN_OLD_CHKSUM + 4)
- << ", page number (if stored to page already) "
- << mach_read_from_4(read_buf + FIL_PAGE_OFFSET)
- << ", space id (if created with >= MySQL-4.1.1"
- " and stored already) "
- << mach_read_from_4(
- read_buf + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
- }
-
- switch (fil_page_get_type(read_buf)) {
- index_id_t index_id;
- case FIL_PAGE_INDEX:
- case FIL_PAGE_TYPE_INSTANT:
- case FIL_PAGE_RTREE:
- index_id = btr_page_get_index_id(read_buf);
- ib::info() << "Page may be an index page where"
- " index id is " << index_id;
+ sql_print_information("InnoDB: %.*s", 64, row);
+ }
+ while (read_buf != end);
- index = dict_index_find_on_id_low(index_id);
- if (index) {
- ib::info()
- << "Index " << index_id
- << " is " << index->name
- << " in table " << index->table->name;
- }
- break;
- case FIL_PAGE_UNDO_LOG:
- fputs("InnoDB: Page may be an undo log page\n", stderr);
- break;
- case FIL_PAGE_INODE:
- fputs("InnoDB: Page may be an 'inode' page\n", stderr);
- break;
- case FIL_PAGE_IBUF_FREE_LIST:
- fputs("InnoDB: Page may be an insert buffer free list page\n",
- stderr);
- break;
- case FIL_PAGE_TYPE_ALLOCATED:
- fputs("InnoDB: Page may be a freshly allocated page\n",
- stderr);
- break;
- case FIL_PAGE_IBUF_BITMAP:
- fputs("InnoDB: Page may be an insert buffer bitmap page\n",
- stderr);
- break;
- case FIL_PAGE_TYPE_SYS:
- fputs("InnoDB: Page may be a system page\n",
- stderr);
- break;
- case FIL_PAGE_TYPE_TRX_SYS:
- fputs("InnoDB: Page may be a transaction system page\n",
- stderr);
- break;
- case FIL_PAGE_TYPE_FSP_HDR:
- fputs("InnoDB: Page may be a file space header page\n",
- stderr);
- break;
- case FIL_PAGE_TYPE_XDES:
- fputs("InnoDB: Page may be an extent descriptor page\n",
- stderr);
- break;
- case FIL_PAGE_TYPE_BLOB:
- fputs("InnoDB: Page may be a BLOB page\n",
- stderr);
- break;
- case FIL_PAGE_TYPE_ZBLOB:
- case FIL_PAGE_TYPE_ZBLOB2:
- fputs("InnoDB: Page may be a compressed BLOB page\n",
- stderr);
- break;
- }
+ sql_print_information("InnoDB: End of page dump");
+#endif
}
# ifdef PFS_GROUP_BUFFER_SYNC
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index f8c276fe75c..9f99a88982e 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2021, MariaDB Corporation.
+Copyright (c) 2013, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1352,48 +1352,6 @@ dict_table_find_index_on_id(
return(NULL);
}
-/**********************************************************************//**
-Looks for an index with the given id. NOTE that we do not reserve
-the dictionary mutex: this function is for emergency purposes like
-printing info of a corrupt database page!
-@return index or NULL if not found in cache */
-dict_index_t*
-dict_index_find_on_id_low(
-/*======================*/
- index_id_t id) /*!< in: index id */
-{
- dict_table_t* table;
-
- /* This can happen if the system tablespace is the wrong page size */
- if (dict_sys == NULL) {
- return(NULL);
- }
-
- for (table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
- table != NULL;
- table = UT_LIST_GET_NEXT(table_LRU, table)) {
-
- dict_index_t* index = dict_table_find_index_on_id(table, id);
-
- if (index != NULL) {
- return(index);
- }
- }
-
- for (table = UT_LIST_GET_FIRST(dict_sys->table_non_LRU);
- table != NULL;
- table = UT_LIST_GET_NEXT(table_LRU, table)) {
-
- dict_index_t* index = dict_table_find_index_on_id(table, id);
-
- if (index != NULL) {
- return(index);
- }
- }
-
- return(NULL);
-}
-
/** Function object to remove a foreign key constraint from the
referenced_set of the referenced table. The foreign key object is
also removed from the dictionary cache. The foreign key constraint
@@ -4939,9 +4897,19 @@ dict_index_get_if_in_cache_low(
/*===========================*/
index_id_t index_id) /*!< in: index id */
{
- ut_ad(mutex_own(&dict_sys->mutex));
+ ut_ad(mutex_own(&dict_sys->mutex));
+
+ for (dict_table_t *table= UT_LIST_GET_FIRST(dict_sys->table_LRU);
+ table; table= UT_LIST_GET_NEXT(table_LRU, table))
+ if (dict_index_t *index= dict_table_find_index_on_id(table, index_id))
+ return index;
+
+ for (dict_table_t *table = UT_LIST_GET_FIRST(dict_sys->table_non_LRU);
+ table; table= UT_LIST_GET_NEXT(table_LRU, table))
+ if (dict_index_t *index= dict_table_find_index_on_id(table, index_id))
+ return index;
- return(dict_index_find_on_id_low(index_id));
+ return NULL;
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 8fc40aa2856..ff0bb9b9129 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2007, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2014, 2021, MariaDB Corporation.
+Copyright (c) 2014, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1405,9 +1405,8 @@ i_s_cmp_per_index_fill_low(
for (iter = snap.begin(), i = 0; iter != snap.end(); iter++, i++) {
- dict_index_t* index = dict_index_find_on_id_low(iter->first);
-
- if (index != NULL) {
+ if (dict_index_t* index
+ = dict_index_get_if_in_cache_low(iter->first)) {
char db_utf8[MAX_DB_UTF8_LEN];
char table_utf8[MAX_TABLE_UTF8_LEN];
diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h
index 6f0479a6e77..93fcfc75ff5 100644
--- a/storage/innobase/include/dict0dict.h
+++ b/storage/innobase/include/dict0dict.h
@@ -2,7 +2,7 @@
Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2021, MariaDB Corporation.
+Copyright (c) 2013, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1033,16 +1033,6 @@ dict_table_copy_types(
const dict_table_t* table) /*!< in: table */
MY_ATTRIBUTE((nonnull));
/**********************************************************************//**
-Looks for an index with the given id. NOTE that we do not reserve
-the dictionary mutex: this function is for emergency purposes like
-printing info of a corrupt database page!
-@return index or NULL if not found from cache */
-dict_index_t*
-dict_index_find_on_id_low(
-/*======================*/
- index_id_t id) /*!< in: index id */
- MY_ATTRIBUTE((warn_unused_result));
-/**********************************************************************//**
Make room in the table cache by evicting an unused table. The unused table
should not be part of FK relationship and currently not used in any user
transaction. There is no guarantee that it will remove a table.