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().
This commit is contained in:
Marko Mäkelä 2019-12-04 20:01:04 +02:00
parent 2352f51625
commit 504202bd7f
7 changed files with 59 additions and 83 deletions

View File

@ -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: 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("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("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: A bad Space ID was found in datafile");
call mtr.add_suppression("InnoDB: Checksum mismatch 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 --enable_query_log
--source include/restart_mysqld.inc --source include/restart_mysqld.inc

View File

@ -341,7 +341,17 @@ Datafile::read_first_page(bool read_only_mode)
} }
if (m_order == 0) { 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); m_flags = fsp_header_get_flags(m_first_page);
if (!fil_space_t::is_valid_flags(m_flags, m_space_id)) { if (!fil_space_t::is_valid_flags(m_flags, m_space_id)) {
ulint cflags = fsp_flags_convert_from_101(m_flags); ulint cflags = fsp_flags_convert_from_101(m_flags);

View File

@ -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 /** Try to extend a single-table tablespace so that a page would fit in the
data file. data file.
@param[in,out] space tablespace @param[in,out] space tablespace

View File

@ -302,14 +302,6 @@ inline bool xdes_is_free(const xdes_t *descr, ulint offset)
#ifndef UNIV_INNOCHECKSUM #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. /** Read a tablespace header field.
@param[in] page first page of a tablespace @param[in] page first page of a tablespace
@param[in] field the header field @param[in] field the header field

View File

@ -4464,17 +4464,20 @@ bool fil_node_t::read_page0(bool first)
return false; return false;
} }
byte* buf2 = static_cast<byte*>(ut_malloc_nokey(2 * psize)); page_t *page= static_cast<byte*>(aligned_malloc(psize, psize));
if (os_file_read(IORequestRead, handle, page, 0, psize)
/* Align the memory for file i/o if we might have O_DIRECT set */ != DB_SUCCESS) {
byte* page = static_cast<byte*>(ut_align(buf2, psize));
IORequest request(IORequest::READ);
if (os_file_read(request, handle, page, 0, psize) != DB_SUCCESS) {
ib::error() << "Unable to read first page of file " << name; ib::error() << "Unable to read first page of file " << name;
ut_free(buf2); corrupted:
aligned_free(page);
return false; 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); ulint flags = fsp_header_get_flags(page);
const ulint size = fsp_header_get_field(page, FSP_SIZE); const ulint size = fsp_header_get_field(page, FSP_SIZE);
const ulint free_limit = fsp_header_get_field(page, FSP_FREE_LIMIT); const ulint free_limit = fsp_header_get_field(page, FSP_FREE_LIMIT);
@ -4489,8 +4492,7 @@ invalid:
<< ib::hex(space->flags) << ib::hex(space->flags)
<< " but found " << ib::hex(flags) << " but found " << ib::hex(flags)
<< " in the file " << name; << " in the file " << name;
ut_free(buf2); goto corrupted;
return false;
} }
ulint cf = cflags & ~FSP_FLAGS_MEM_MASK; ulint cf = cflags & ~FSP_FLAGS_MEM_MASK;
@ -4511,7 +4513,7 @@ invalid:
space->crypt_data = fil_space_read_crypt_data( space->crypt_data = fil_space_read_crypt_data(
fil_space_t::zip_size(flags), page); fil_space_t::zip_size(flags), page);
} }
ut_free(buf2); aligned_free(page);
if (UNIV_UNLIKELY(space_id != space->id)) { if (UNIV_UNLIKELY(space_id != space->id)) {
ib::error() << "Expected tablespace id " << space->id ib::error() << "Expected tablespace id " << space->id

View File

@ -1903,36 +1903,25 @@ clear_page_max_trx_id:
/** Validate the space flags and update tablespace header page. /** Validate the space flags and update tablespace header page.
@param block block read from file, not from the buffer pool. @param block block read from file, not from the buffer pool.
@retval DB_SUCCESS or error code */ @retval DB_SUCCESS or error code */
inline inline dberr_t PageConverter::update_header(buf_block_t* block) UNIV_NOTHROW
dberr_t
PageConverter::update_header(
buf_block_t* block) UNIV_NOTHROW
{ {
/* Check for valid header */ byte *frame= get_frame(block);
switch (fsp_header_get_space_id(get_frame(block))) { if (memcmp_aligned<4>(FIL_PAGE_SPACE_ID + frame,
case 0: FSP_HEADER_OFFSET + FSP_SPACE_ID + frame, 4))
return(DB_CORRUPTION); ib::warn() << "Space id check in the header failed: ignored";
case ULINT_UNDEFINED: else if (!mach_read_from_4(FIL_PAGE_SPACE_ID + frame))
ib::warn() << "Space id check in the header failed: ignored"; return DB_CORRUPTION;
}
memset(get_frame(block) + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION,0,8); memset(frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8);
/* Write back the adjusted flags. */ /* Write space_id to the tablespace header, page 0. */
mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS mach_write_to_4(FIL_PAGE_SPACE_ID + frame, get_space_id());
+ get_frame(block), m_space_flags); 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);
/* Write space_id to the tablespace header, page 0. */ return DB_SUCCESS;
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);
} }
/** Update the page, set the space id, max trx id and index id. /** Update the page, set the space id, max trx id and index id.

View File

@ -599,7 +599,6 @@ static ulint trx_rseg_get_n_undo_tablespaces()
@retval 0 on failure */ @retval 0 on failure */
static ulint srv_undo_tablespace_open(bool create, const char* name, ulint i) static ulint srv_undo_tablespace_open(bool create, const char* name, ulint i)
{ {
pfs_os_file_t fh;
bool success; bool success;
char undo_name[sizeof "innodb_undo000"]; char undo_name[sizeof "innodb_undo000"];
ulint space_id= 0; 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( pfs_os_file_t fh= os_file_create(innodb_data_file_key, name, OS_FILE_OPEN |
innodb_data_file_key, name, OS_FILE_OPEN OS_FILE_ON_ERROR_NO_EXIT |
| OS_FILE_ON_ERROR_NO_EXIT | OS_FILE_ON_ERROR_SILENT, OS_FILE_ON_ERROR_SILENT,
OS_FILE_AIO, OS_DATA_FILE, srv_read_only_mode, &success); OS_FILE_AIO, OS_DATA_FILE,
srv_read_only_mode, &success);
if (!success) if (!success)
return 0; return 0;
@ -644,11 +644,20 @@ err_exit:
return err; return err;
} }
fsp_flags= mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); uint32_t id= mach_read_from_4(FIL_PAGE_SPACE_ID + page);
uint32_t id= fsp_header_get_space_id(page);
if (id == 0 || id >= SRV_LOG_SPACE_FIRST_ID || 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; err= DB_CORRUPTION;
goto err_exit; goto err_exit;
} }