summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-12-04 20:01:04 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2019-12-04 20:01:04 +0200
commit504202bd7fe7d7e85039fface189e721d1aeff7a (patch)
treefe2e05a38f661b30dcfb0eef2a3df30be55eb568
parent2352f51625e5045649c7190774c8a200f3388359 (diff)
downloadmariadb-git-504202bd7fe7d7e85039fface189e721d1aeff7a.tar.gz
MDEV-21216: Remove fsp_header_get_space_id()
The function fsp_header_get_space_id() returns ulint instead of uint32_t, only to be able to complain that the two adjacent tablespace ID fields in the page differ. Remove the function, and merge the check to the callers. Also, make some more use of aligned_malloc().
-rw-r--r--mysql-test/suite/innodb/t/doublewrite.test5
-rw-r--r--storage/innobase/fsp/fsp0file.cc12
-rw-r--r--storage/innobase/fsp/fsp0fsp.cc27
-rw-r--r--storage/innobase/include/fsp0fsp.h8
-rw-r--r--storage/innobase/os/os0file.cc24
-rw-r--r--storage/innobase/row/row0import.cc47
-rw-r--r--storage/innobase/srv/srv0start.cc25
7 files changed, 62 insertions, 86 deletions
diff --git a/mysql-test/suite/innodb/t/doublewrite.test b/mysql-test/suite/innodb/t/doublewrite.test
index 87ff74a7d51..3bcc5d835e5 100644
--- a/mysql-test/suite/innodb/t/doublewrite.test
+++ b/mysql-test/suite/innodb/t/doublewrite.test
@@ -19,8 +19,9 @@ call mtr.add_suppression("InnoDB: New log files created");
call mtr.add_suppression("InnoDB: Cannot create doublewrite buffer: the first file in innodb_data_file_path must be at least (3|6|12)M\\.");
call mtr.add_suppression("InnoDB: Database creation was aborted");
call mtr.add_suppression("Plugin 'InnoDB' (init function returned error|registration as a STORAGE ENGINE failed)");
-call mtr.add_suppression("InnoDB: A bad Space ID was found in datafile.*");
-call mtr.add_suppression("InnoDB: Checksum mismatch in datafile: .*");
+call mtr.add_suppression("InnoDB: A bad Space ID was found in datafile");
+call mtr.add_suppression("InnoDB: Checksum mismatch in datafile: ");
+call mtr.add_suppression("InnoDB: Inconsistent tablespace ID in .*t1\\.ibd");
--enable_query_log
--source include/restart_mysqld.inc
diff --git a/storage/innobase/fsp/fsp0file.cc b/storage/innobase/fsp/fsp0file.cc
index c21a75687e6..a005ae5dff4 100644
--- a/storage/innobase/fsp/fsp0file.cc
+++ b/storage/innobase/fsp/fsp0file.cc
@@ -341,7 +341,17 @@ Datafile::read_first_page(bool read_only_mode)
}
if (m_order == 0) {
- m_space_id = fsp_header_get_space_id(m_first_page);
+ if (memcmp_aligned<4>(FIL_PAGE_SPACE_ID + m_first_page,
+ FSP_HEADER_OFFSET + FSP_SPACE_ID
+ + m_first_page, 4)) {
+ ib::error()
+ << "Inconsistent tablespace ID in "
+ << m_filepath;
+ return DB_CORRUPTION;
+ }
+
+ m_space_id = mach_read_from_4(FIL_PAGE_SPACE_ID
+ + m_first_page);
m_flags = fsp_header_get_flags(m_first_page);
if (!fil_space_t::is_valid_flags(m_flags, m_space_id)) {
ulint cflags = fsp_flags_convert_from_101(m_flags);
diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc
index 25fd9b0aabf..260de1eadea 100644
--- a/storage/innobase/fsp/fsp0fsp.cc
+++ b/storage/innobase/fsp/fsp0fsp.cc
@@ -612,33 +612,6 @@ void fsp_header_init(fil_space_t* space, ulint size, mtr_t* mtr)
}
}
-/**********************************************************************//**
-Reads the space id from the first page of a tablespace.
-@return space id, ULINT UNDEFINED if error */
-ulint
-fsp_header_get_space_id(
-/*====================*/
- const page_t* page) /*!< in: first page of a tablespace */
-{
- ulint fsp_id;
- ulint id;
-
- fsp_id = mach_read_from_4(FSP_HEADER_OFFSET + page + FSP_SPACE_ID);
-
- id = mach_read_from_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
-
- DBUG_EXECUTE_IF("fsp_header_get_space_id_failure",
- id = ULINT_UNDEFINED;);
-
- if (id != fsp_id) {
- ib::error() << "Space ID in fsp header is " << fsp_id
- << ", but in the page header it is " << id << ".";
- return(ULINT_UNDEFINED);
- }
-
- return(id);
-}
-
/** Try to extend a single-table tablespace so that a page would fit in the
data file.
@param[in,out] space tablespace
diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h
index 05494553177..48a1ef5de8b 100644
--- a/storage/innobase/include/fsp0fsp.h
+++ b/storage/innobase/include/fsp0fsp.h
@@ -302,14 +302,6 @@ inline bool xdes_is_free(const xdes_t *descr, ulint offset)
#ifndef UNIV_INNOCHECKSUM
/* @} */
-/**********************************************************************//**
-Reads the space id from the first page of a tablespace.
-@return space id, ULINT UNDEFINED if error */
-ulint
-fsp_header_get_space_id(
-/*====================*/
- const page_t* page); /*!< in: first page of a tablespace */
-
/** Read a tablespace header field.
@param[in] page first page of a tablespace
@param[in] field the header field
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index d4bf270217b..4b43b1f50b0 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -4464,17 +4464,20 @@ bool fil_node_t::read_page0(bool first)
return false;
}
- byte* buf2 = static_cast<byte*>(ut_malloc_nokey(2 * psize));
-
- /* Align the memory for file i/o if we might have O_DIRECT set */
- byte* page = static_cast<byte*>(ut_align(buf2, psize));
- IORequest request(IORequest::READ);
- if (os_file_read(request, handle, page, 0, psize) != DB_SUCCESS) {
+ page_t *page= static_cast<byte*>(aligned_malloc(psize, psize));
+ if (os_file_read(IORequestRead, handle, page, 0, psize)
+ != DB_SUCCESS) {
ib::error() << "Unable to read first page of file " << name;
- ut_free(buf2);
+corrupted:
+ aligned_free(page);
return false;
}
- const ulint space_id = fsp_header_get_space_id(page);
+
+ const ulint space_id = memcmp_aligned<4>(
+ FIL_PAGE_SPACE_ID + page,
+ FSP_HEADER_OFFSET + FSP_SPACE_ID + page, 4)
+ ? ULINT_UNDEFINED
+ : mach_read_from_4(FIL_PAGE_SPACE_ID + page);
ulint flags = fsp_header_get_flags(page);
const ulint size = fsp_header_get_field(page, FSP_SIZE);
const ulint free_limit = fsp_header_get_field(page, FSP_FREE_LIMIT);
@@ -4489,8 +4492,7 @@ invalid:
<< ib::hex(space->flags)
<< " but found " << ib::hex(flags)
<< " in the file " << name;
- ut_free(buf2);
- return false;
+ goto corrupted;
}
ulint cf = cflags & ~FSP_FLAGS_MEM_MASK;
@@ -4511,7 +4513,7 @@ invalid:
space->crypt_data = fil_space_read_crypt_data(
fil_space_t::zip_size(flags), page);
}
- ut_free(buf2);
+ aligned_free(page);
if (UNIV_UNLIKELY(space_id != space->id)) {
ib::error() << "Expected tablespace id " << space->id
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 321c7d21a6c..beca1cffc10 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -1903,36 +1903,25 @@ clear_page_max_trx_id:
/** Validate the space flags and update tablespace header page.
@param block block read from file, not from the buffer pool.
@retval DB_SUCCESS or error code */
-inline
-dberr_t
-PageConverter::update_header(
- buf_block_t* block) UNIV_NOTHROW
+inline dberr_t PageConverter::update_header(buf_block_t* block) UNIV_NOTHROW
{
- /* Check for valid header */
- switch (fsp_header_get_space_id(get_frame(block))) {
- case 0:
- return(DB_CORRUPTION);
- case ULINT_UNDEFINED:
- ib::warn() << "Space id check in the header failed: ignored";
- }
-
- memset(get_frame(block) + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,0,8);
-
- /* Write back the adjusted flags. */
- mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS
- + get_frame(block), m_space_flags);
-
- /* Write space_id to the tablespace header, page 0. */
- mach_write_to_4(
- get_frame(block) + FSP_HEADER_OFFSET + FSP_SPACE_ID,
- get_space_id());
-
- /* This is on every page in the tablespace. */
- mach_write_to_4(
- get_frame(block) + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID,
- get_space_id());
-
- return(DB_SUCCESS);
+ byte *frame= get_frame(block);
+ if (memcmp_aligned<4>(FIL_PAGE_SPACE_ID + frame,
+ FSP_HEADER_OFFSET + FSP_SPACE_ID + frame, 4))
+ ib::warn() << "Space id check in the header failed: ignored";
+ else if (!mach_read_from_4(FIL_PAGE_SPACE_ID + frame))
+ return DB_CORRUPTION;
+
+ memset(frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8);
+
+ /* Write space_id to the tablespace header, page 0. */
+ mach_write_to_4(FIL_PAGE_SPACE_ID + frame, get_space_id());
+ memcpy_aligned<4>(FSP_HEADER_OFFSET + FSP_SPACE_ID + frame,
+ FIL_PAGE_SPACE_ID + frame, 4);
+ /* Write back the adjusted flags. */
+ mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + frame, m_space_flags);
+
+ return DB_SUCCESS;
}
/** Update the page, set the space id, max trx id and index id.
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 0556bcd65bb..3ea2f967b68 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -599,7 +599,6 @@ static ulint trx_rseg_get_n_undo_tablespaces()
@retval 0 on failure */
static ulint srv_undo_tablespace_open(bool create, const char* name, ulint i)
{
- pfs_os_file_t fh;
bool success;
char undo_name[sizeof "innodb_undo000"];
ulint space_id= 0;
@@ -620,10 +619,11 @@ static ulint srv_undo_tablespace_open(bool create, const char* name, ulint i)
}
}
- fh = os_file_create(
- innodb_data_file_key, name, OS_FILE_OPEN
- | OS_FILE_ON_ERROR_NO_EXIT | OS_FILE_ON_ERROR_SILENT,
- OS_FILE_AIO, OS_DATA_FILE, srv_read_only_mode, &success);
+ pfs_os_file_t fh= os_file_create(innodb_data_file_key, name, OS_FILE_OPEN |
+ OS_FILE_ON_ERROR_NO_EXIT |
+ OS_FILE_ON_ERROR_SILENT,
+ OS_FILE_AIO, OS_DATA_FILE,
+ srv_read_only_mode, &success);
if (!success)
return 0;
@@ -644,11 +644,20 @@ err_exit:
return err;
}
- fsp_flags= mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page);
- uint32_t id= fsp_header_get_space_id(page);
+ uint32_t id= mach_read_from_4(FIL_PAGE_SPACE_ID + page);
if (id == 0 || id >= SRV_LOG_SPACE_FIRST_ID ||
- buf_page_is_corrupted(false, page, fsp_flags))
+ memcmp_aligned<4>(FIL_PAGE_SPACE_ID + page,
+ FSP_HEADER_OFFSET + FSP_SPACE_ID + page, 4))
+ {
+ ib::error() << "Inconsistent tablespace ID in file " << name;
+ err= DB_CORRUPTION;
+ goto err_exit;
+ }
+
+ fsp_flags= mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page);
+ if (buf_page_is_corrupted(false, page, fsp_flags))
{
+ ib::error() << "Checksum mismatch in the first page of file " << name;
err= DB_CORRUPTION;
goto err_exit;
}