Skip to content
Permalink
Browse files
MDEV-30132 Crash after recovery, with InnoDB: Tried to read ...
os_file_read(): Merged with os_file_read_no_error_handling().
Crashing on a partial page read is as unhelpful as crashing on a
corrupted page read (commit 0b47c12).
Report the file name if it is available via IORequest.
  • Loading branch information
dr-m committed Nov 30, 2022
1 parent fc1403d commit 15ab2e1
Show file tree
Hide file tree
Showing 15 changed files with 92 additions and 254 deletions.
@@ -561,8 +561,8 @@ datafile_read(datafile_cur_t *cursor)
}

if (os_file_read(IORequestRead,
cursor->file, cursor->buf, cursor->buf_offset,
to_read) != DB_SUCCESS) {
cursor->file, cursor->buf, cursor->buf_offset,
to_read, nullptr) != DB_SUCCESS) {
return(XB_FIL_CUR_ERROR);
}

@@ -188,18 +188,15 @@ log_online_read_bitmap_page(
{
ulint checksum;
ulint actual_checksum;
ibool success;

ut_a(bitmap_file->size >= MODIFIED_PAGE_BLOCK_SIZE);
ut_a(bitmap_file->offset
<= bitmap_file->size - MODIFIED_PAGE_BLOCK_SIZE);
ut_a(bitmap_file->offset % MODIFIED_PAGE_BLOCK_SIZE == 0);
success = os_file_read(IORequestRead,
bitmap_file->file, page, bitmap_file->offset,
MODIFIED_PAGE_BLOCK_SIZE) == DB_SUCCESS;

if (UNIV_UNLIKELY(!success)) {

if (DB_SUCCESS !=
os_file_read(IORequestRead, bitmap_file->file, page,
bitmap_file->offset, MODIFIED_PAGE_BLOCK_SIZE,
nullptr)) {
/* The following call prints an error message */
os_file_get_last_error(TRUE);
msg("InnoDB: Warning: failed reading changed page bitmap "
@@ -223,7 +223,7 @@ xb_fil_cur_open(
if (!node->space->crypt_data
&& os_file_read(IORequestRead,
node->handle, cursor->buf, 0,
cursor->page_size) == DB_SUCCESS) {
cursor->page_size, nullptr) == DB_SUCCESS) {
mysql_mutex_lock(&fil_system.mutex);
if (!node->space->crypt_data) {
node->space->crypt_data = fil_space_read_crypt_data(
@@ -415,7 +415,7 @@ xb_fil_cur_result_t xb_fil_cur_read(xb_fil_cur_t* cursor,
cursor->buf_page_no = static_cast<unsigned>(offset / page_size);

if (os_file_read(IORequestRead, cursor->file, cursor->buf, offset,
(ulint) to_read) != DB_SUCCESS) {
(ulint) to_read, nullptr) != DB_SUCCESS) {
ret = XB_FIL_CUR_ERROR;
goto func_exit;
}
@@ -3827,7 +3827,7 @@ static dberr_t xb_assign_undo_space_start()
byte* page = static_cast<byte*>
(aligned_malloc(srv_page_size, srv_page_size));

if (os_file_read(IORequestRead, file, page, 0, srv_page_size)
if (os_file_read(IORequestRead, file, page, 0, srv_page_size, nullptr)
!= DB_SUCCESS) {
msg("Reading first page failed.\n");
error = DB_ERROR;
@@ -3839,7 +3839,7 @@ static dberr_t xb_assign_undo_space_start()
retry:
if (os_file_read(IORequestRead, file, page,
TRX_SYS_PAGE_NO << srv_page_size_shift,
srv_page_size) != DB_SUCCESS) {
srv_page_size, nullptr) != DB_SUCCESS) {
msg("Reading TRX_SYS page failed.");
error = DB_ERROR;
goto func_exit;
@@ -5347,7 +5347,8 @@ xtrabackup_apply_delta(
offset = ((incremental_buffers * (page_size / 4))
<< page_size_shift);
if (os_file_read(IORequestRead, src_file,
incremental_buffer, offset, page_size)
incremental_buffer, offset, page_size,
nullptr)
!= DB_SUCCESS) {
goto error;
}
@@ -5380,7 +5381,7 @@ xtrabackup_apply_delta(
/* read whole of the cluster */
if (os_file_read(IORequestRead, src_file,
incremental_buffer,
offset, page_in_buffer * page_size)
offset, page_in_buffer * page_size, nullptr)
!= DB_SUCCESS) {
goto error;
}
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -253,7 +253,7 @@ dberr_t buf_dblwr_t::init_or_load_pages(pfs_os_file_t file, const char *path)
/* Read the TRX_SYS header to check if we are using the doublewrite buffer */
dberr_t err= os_file_read(IORequestRead, file, read_buf,
TRX_SYS_PAGE_NO << srv_page_size_shift,
srv_page_size);
srv_page_size, nullptr);

if (err != DB_SUCCESS)
{
@@ -285,7 +285,7 @@ dberr_t buf_dblwr_t::init_or_load_pages(pfs_os_file_t file, const char *path)
/* Read the pages from the doublewrite buffer to memory */
err= os_file_read(IORequestRead, file, write_buf,
block1.page_no() << srv_page_size_shift,
size << srv_page_size_shift);
size << srv_page_size_shift, nullptr);

if (err != DB_SUCCESS)
{
@@ -296,7 +296,7 @@ dberr_t buf_dblwr_t::init_or_load_pages(pfs_os_file_t file, const char *path)
err= os_file_read(IORequestRead, file,
write_buf + (size << srv_page_size_shift),
block2.page_no() << srv_page_size_shift,
size << srv_page_size_shift);
size << srv_page_size_shift, nullptr);
if (err != DB_SUCCESS)
{
ib::error() << "Failed to read the second double write buffer extent";
@@ -2750,10 +2750,6 @@ fil_io_t fil_space_t::io(const IORequest &type, os_offset_t offset, size_t len,
buf, offset, len);
}

/* We an try to recover the page from the double write buffer if
the decompression fails or the page is corrupt. */

ut_a(type.type == IORequest::DBLWR_RECOVER || err == DB_SUCCESS);
if (!type.is_async()) {
if (type.is_write()) {
release_sync_write:
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2021, MariaDB Corporation.
Copyright (c) 2017, 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
@@ -263,12 +263,11 @@ Datafile::read_first_page(bool read_only_mode)

ulint n_read = 0;

err = os_file_read_no_error_handling(
err = os_file_read(
IORequestReadPartial, m_handle, m_first_page, 0,
page_size, &n_read);

if (err == DB_SUCCESS) {
ut_a(n_read == page_size);
break;
}

@@ -664,7 +663,7 @@ Datafile::find_space_id()

for (ulint j = 0; j < page_count; ++j) {
if (os_file_read(IORequestRead, m_handle, page,
j * page_size, page_size)) {
j * page_size, page_size, nullptr)) {
ib::info()
<< "READ FAIL: page_no:" << j;
continue;
@@ -582,12 +582,8 @@ The wrapper functions have the prefix of "innodb_". */
# define os_file_close(file) \
pfs_os_file_close_func(file, __FILE__, __LINE__)

# define os_file_read(type, file, buf, offset, n) \
pfs_os_file_read_func(type, file, buf, offset, n, __FILE__, __LINE__)

# define os_file_read_no_error_handling(type, file, buf, offset, n, o) \
pfs_os_file_read_no_error_handling_func( \
type, file, buf, offset, n, o, __FILE__, __LINE__)
# define os_file_read(type, file, buf, offset, n, o) \
pfs_os_file_read_func(type, file, buf, offset, n,o, __FILE__, __LINE__)

# define os_file_write(type, name, file, buf, offset, n) \
pfs_os_file_write_func(type, name, file, buf, offset, \
@@ -727,31 +723,6 @@ os_file_read() which requests a synchronous read operation.
UNIV_INLINE
dberr_t
pfs_os_file_read_func(
const IORequest& type,
pfs_os_file_t file,
void* buf,
os_offset_t offset,
ulint n,
const char* src_file,
uint src_line);

/** NOTE! Please use the corresponding macro os_file_read_no_error_handling(),
not directly this function!
This is the performance schema instrumented wrapper function for
os_file_read_no_error_handling_func() which requests a synchronous
read operation.
@param[in] type IO request context
@param[in] file Open file handle
@param[out] buf buffer where to read
@param[in] offset file offset where to read
@param[in] n number of bytes to read
@param[out] o number of bytes actually read
@param[in] src_file file name where func invoked
@param[in] src_line line where the func invoked
@return DB_SUCCESS if request was successful */
UNIV_INLINE
dberr_t
pfs_os_file_read_no_error_handling_func(
const IORequest& type,
pfs_os_file_t file,
void* buf,
@@ -882,11 +853,8 @@ to original un-instrumented file I/O APIs */

# define os_file_close(file) os_file_close_func(file)

# define os_file_read(type, file, buf, offset, n) \
os_file_read_func(type, file, buf, offset, n)

# define os_file_read_no_error_handling(type, file, buf, offset, n, o) \
os_file_read_no_error_handling_func(type, file, buf, offset, n, o)
# define os_file_read(type, file, buf, offset, n, o) \
os_file_read_func(type, file, buf, offset, n, o)

# define os_file_write(type, name, file, buf, offset, n) \
os_file_write_func(type, name, file, buf, offset, n)
@@ -991,14 +959,16 @@ Requests a synchronous read operation.
@param[out] buf buffer where to read
@param[in] offset file offset where to read
@param[in] n number of bytes to read
@param[out] o number of bytes actually read
@return DB_SUCCESS if request was successful */
dberr_t
os_file_read_func(
const IORequest& type,
os_file_t file,
void* buf,
os_offset_t offset,
ulint n)
ulint n,
ulint* o)
MY_ATTRIBUTE((warn_unused_result));

/** Rewind file to its start, read at most size - 1 bytes from it to str, and
@@ -1013,27 +983,6 @@ os_file_read_string(
char* str,
ulint size);

/** NOTE! Use the corresponding macro os_file_read_no_error_handling(),
not directly this function!
Requests a synchronous positioned read operation. This function does not do
any error handling. In case of error it returns FALSE.
@param[in] type IO request context
@param[in] file Open file handle
@param[out] buf buffer where to read
@param[in] offset file offset where to read
@param[in] n number of bytes to read
@param[out] o number of bytes actually read
@return DB_SUCCESS or error code */
dberr_t
os_file_read_no_error_handling_func(
const IORequest& type,
os_file_t file,
void* buf,
os_offset_t offset,
ulint n,
ulint* o)
MY_ATTRIBUTE((warn_unused_result));

/** NOTE! Use the corresponding macro os_file_write(), not directly this
function!
Requests a synchronous write operation.
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2010, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2013, 2020, 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
@@ -210,6 +210,7 @@ os_file_read() which requests a synchronous read operation.
@param[out] buf buffer where to read
@param[in] offset file offset where to read
@param[in] n number of bytes to read
@param[out] o number of bytes actually read
@param[in] src_file file name where func invoked
@param[in] src_line line where the func invoked
@return DB_SUCCESS if request was successful */
@@ -221,6 +222,7 @@ pfs_os_file_read_func(
void* buf,
os_offset_t offset,
ulint n,
ulint* o,
const char* src_file,
uint src_line)
{
@@ -232,47 +234,7 @@ pfs_os_file_read_func(

dberr_t result;

result = os_file_read_func(type, file, buf, offset, n);

register_pfs_file_io_end(locker, n);

return(result);
}

/** NOTE! Please use the corresponding macro os_file_read_no_error_handling(),
not directly this function!
This is the performance schema instrumented wrapper function for
os_file_read_no_error_handling_func() which requests a synchronous
read operation.
@param[in] type IO request context
@param[in] file Open file handle
@param[out] buf buffer where to read
@param[in] offset file offset where to read
@param[in] n number of bytes to read
@param[out] o number of bytes actually read
@param[in] src_file file name where func invoked
@param[in] src_line line where the func invoked
@return DB_SUCCESS if request was successful */
UNIV_INLINE
dberr_t
pfs_os_file_read_no_error_handling_func(
const IORequest& type,
pfs_os_file_t file,
void* buf,
os_offset_t offset,
ulint n,
ulint* o,
const char* src_file,
uint src_line)
{
PSI_file_locker_state state;
struct PSI_file_locker* locker = NULL;

register_pfs_file_io_begin(
&state, locker, file, n, PSI_FILE_READ, src_file, src_line);

dberr_t result = os_file_read_no_error_handling_func(
type, file, buf, offset, n, o);
result = os_file_read_func(type, file, buf, offset, n, o);

register_pfs_file_io_end(locker, n);

@@ -275,7 +275,8 @@ dberr_t file_os_io::close() noexcept

dberr_t file_os_io::read(os_offset_t offset, span<byte> buf) noexcept
{
return os_file_read(IORequestRead, m_fd, buf.data(), offset, buf.size());
return os_file_read(IORequestRead, m_fd, buf.data(), offset, buf.size(),
nullptr);
}

dberr_t file_os_io::write(const char *path, os_offset_t offset,

0 comments on commit 15ab2e1

Please sign in to comment.