Skip to content

Commit

Permalink
MDEV-12396 IMPORT TABLESPACE: Do not retry partial reads
Browse files Browse the repository at this point in the history
fil_iterate(), fil_tablespace_iterate(): Replace os_file_read()
with os_file_read_no_error_handling().

os_file_read_func(), os_file_read_no_error_handling_func():
Do not retry partial reads. There used to be an infinite amount
of retries. Because InnoDB extends both data and log files upfront,
partial reads should be impossible during normal operation.
  • Loading branch information
dr-m committed Mar 20, 2018
1 parent a80af35 commit e0a0fe7
Show file tree
Hide file tree
Showing 6 changed files with 66 additions and 30 deletions.
Expand Up @@ -39,6 +39,9 @@ SHOW TABLE STATUS LIKE 'tab';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
tab InnoDB # Compact # # # # # # NULL # NULL NULL latin1_swedish_ci NULL
ALTER TABLE tab DISCARD TABLESPACE;
call mtr.add_suppression("InnoDB: Tried to read .* bytes at offset 0");
ALTER TABLE tab IMPORT TABLESPACE;
ERROR HY000: Internal error: Cannot reset LSNs in table '"test"."tab"' : I/O error
ALTER TABLE tab IMPORT TABLESPACE;
SELECT * FROM tab;
a
Expand Down
Expand Up @@ -81,7 +81,14 @@ SHOW TABLE STATUS LIKE 'tab';
ALTER TABLE tab DISCARD TABLESPACE;

# Move the *ibd,*.cfg file into orginal location
--copy_file $MYSQLD_DATADIR/tab.cfg $MYSQLD_DATADIR/test/tab.ibd
--move_file $MYSQLD_DATADIR/tab.cfg $MYSQLD_DATADIR/test/tab.cfg

call mtr.add_suppression("InnoDB: Tried to read .* bytes at offset 0");

--error ER_INTERNAL_ERROR
ALTER TABLE tab IMPORT TABLESPACE;
--remove_file $MYSQLD_DATADIR/test/tab.ibd
--move_file $MYSQLD_DATADIR/tab.ibd $MYSQLD_DATADIR/test/tab.ibd

# Check import is successful (because same row_format)
Expand Down
22 changes: 19 additions & 3 deletions storage/innobase/os/os0file.cc
Expand Up @@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2013, 2017, MariaDB Corporation.
Copyright (c) 2013, 2018, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted
by Percona Inc.. Those modifications are
Expand Down Expand Up @@ -2842,8 +2842,15 @@ os_file_read_func(

MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_READS, monitor);

if (ret && len == n) {
if (!ret) {
} else if (len == n) {
return(TRUE);
} else {
ib_logf(IB_LOG_LEVEL_ERROR,
"Tried to read " ULINTPF " bytes at offset "
UINT64PF ". Was only able to read %lu.",
n, offset, ret);
return FALSE;
}
#else /* __WIN__ */
ibool retry;
Expand All @@ -2866,6 +2873,7 @@ os_file_read_func(
"Tried to read " ULINTPF " bytes at offset "
UINT64PF ". Was only able to read %ld.",
n, offset, (lint) ret);
return FALSE;
}
#endif /* __WIN__ */
#ifdef __WIN__
Expand Down Expand Up @@ -2964,8 +2972,15 @@ os_file_read_no_error_handling_func(

MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_READS, monitor);

if (ret && len == n) {
if (!ret) {
} else if (len == n) {
return(TRUE);
} else {
ib_logf(IB_LOG_LEVEL_ERROR,
"Tried to read " ULINTPF " bytes at offset "
UINT64PF ". Was only able to read %lu.",
n, offset, len);
return FALSE;
}
#else /* __WIN__ */
ibool retry;
Expand All @@ -2988,6 +3003,7 @@ os_file_read_no_error_handling_func(
"Tried to read " ULINTPF " bytes at offset "
UINT64PF ". Was only able to read %ld.",
n, offset, (lint) ret);
return FALSE;
}
#endif /* __WIN__ */
#ifdef __WIN__
Expand Down
9 changes: 4 additions & 5 deletions storage/innobase/row/row0import.cc
Expand Up @@ -44,9 +44,7 @@ Created 2012-02-08 by Sunny Bains.

#include <vector>

/** The size of the buffer to use for IO. Note: os_file_read() doesn't expect
reads to fail. If you set the buffer size to be greater than a multiple of the
file size then it will assert. TODO: Fix this limitation of the IO functions.
/** The size of the buffer to use for IO.
@param n - page size of the tablespace.
@retval number of pages */
#define IO_BUFFER_SIZE(n) ((1024 * 1024) / n)
Expand Down Expand Up @@ -3427,7 +3425,8 @@ fil_iterate(
? iter.crypt_io_buffer : io_buffer;
byte* const writeptr = readptr;

if (!os_file_read(iter.file, readptr, offset, n_bytes)) {
if (!os_file_read_no_error_handling(iter.file, readptr,
offset, n_bytes)) {
ib_logf(IB_LOG_LEVEL_ERROR, "os_file_read() failed");
return DB_IO_ERROR;
}
Expand Down Expand Up @@ -3713,7 +3712,7 @@ fil_tablespace_iterate(

/* Read the first page and determine the page and zip size. */

if (!os_file_read(file, page, 0, UNIV_PAGE_SIZE)) {
if (!os_file_read_no_error_handling(file, page, 0, UNIV_PAGE_SIZE)) {

err = DB_IO_ERROR;

Expand Down
46 changes: 29 additions & 17 deletions storage/xtradb/os/os0file.cc
Expand Up @@ -2,7 +2,7 @@
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2013, 2017, MariaDB Corporation.
Copyright (c) 2013, 2018, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted
by Percona Inc.. Those modifications are
Expand Down Expand Up @@ -3169,15 +3169,21 @@ os_file_read_func(
overlapped.hEvent = win_get_syncio_event();
ret = ReadFile(file, buf, n, NULL, &overlapped);
if (ret) {
ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, FALSE);
}
else if(GetLastError() == ERROR_IO_PENDING) {
ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, TRUE);
ret = GetOverlappedResult(file, &overlapped, &len, FALSE);
} else if (GetLastError() == ERROR_IO_PENDING) {
ret = GetOverlappedResult(file, &overlapped, &len, TRUE);
}
MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_READS, monitor);

if (ret && len == n) {
if (!ret) {
} else if (len == n) {
return(TRUE);
} else {
ib_logf(IB_LOG_LEVEL_ERROR,
"Tried to read " ULINTPF " bytes at offset "
UINT64PF ". Was only able to read %lu.",
n, offset, ret);
return FALSE;
}
#else /* __WIN__ */
ibool retry;
Expand All @@ -3204,6 +3210,7 @@ os_file_read_func(
"Tried to read " ULINTPF " bytes at offset "
UINT64PF ". Was only able to read %ld.",
n, offset, (lint) ret);
return FALSE;
}
#endif /* __WIN__ */
retry = os_file_handle_error(NULL, "read", __FILE__, __LINE__);
Expand Down Expand Up @@ -3272,15 +3279,21 @@ os_file_read_no_error_handling_func(
overlapped.hEvent = win_get_syncio_event();
ret = ReadFile(file, buf, n, NULL, &overlapped);
if (ret) {
ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, FALSE);
}
else if(GetLastError() == ERROR_IO_PENDING) {
ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, TRUE);
ret = GetOverlappedResult(file, &overlapped, &len, FALSE);
} else if (GetLastError() == ERROR_IO_PENDING) {
ret = GetOverlappedResult(file, &overlapped, &len, TRUE);
}
MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_READS, monitor);

if (ret && len == n) {
if (!ret) {
} else if (len == n) {
return(TRUE);
} else {
ib_logf(IB_LOG_LEVEL_ERROR,
"Tried to read " ULINTPF " bytes at offset "
UINT64PF ". Was only able to read %lu.",
n, offset, len);
return FALSE;
}
#else /* __WIN__ */
ibool retry;
Expand All @@ -3303,6 +3316,7 @@ os_file_read_no_error_handling_func(
"Tried to read " ULINTPF " bytes at offset "
UINT64PF ". Was only able to read %ld.",
n, offset, (lint) ret);
return FALSE;
}
#endif /* __WIN__ */
retry = os_file_handle_error_no_exit(NULL, "read", FALSE, __FILE__, __LINE__);
Expand Down Expand Up @@ -3383,10 +3397,9 @@ os_file_write_func(
overlapped.hEvent = win_get_syncio_event();
ret = WriteFile(file, buf, n, NULL, &overlapped);
if (ret) {
ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, FALSE);
}
else if ( GetLastError() == ERROR_IO_PENDING) {
ret = GetOverlappedResult(file, &overlapped, (DWORD *)&len, TRUE);
ret = GetOverlappedResult(file, &overlapped, &len, FALSE);
} else if (GetLastError() == ERROR_IO_PENDING) {
ret = GetOverlappedResult(file, &overlapped, &len, TRUE);
}

MONITOR_ATOMIC_DEC_LOW(MONITOR_OS_PENDING_WRITES, monitor);
Expand Down Expand Up @@ -6588,8 +6601,7 @@ os_file_trim(
DWORD tmp;
if (ret) {
ret = GetOverlappedResult(slot->file, &overlapped, &tmp, FALSE);
}
else if (GetLastError() == ERROR_IO_PENDING) {
} else if (GetLastError() == ERROR_IO_PENDING) {
ret = GetOverlappedResult(slot->file, &overlapped, &tmp, TRUE);
}
if (!ret) {
Expand Down
9 changes: 4 additions & 5 deletions storage/xtradb/row/row0import.cc
Expand Up @@ -44,9 +44,7 @@ Created 2012-02-08 by Sunny Bains.

#include <vector>

/** The size of the buffer to use for IO. Note: os_file_read() doesn't expect
reads to fail. If you set the buffer size to be greater than a multiple of the
file size then it will assert. TODO: Fix this limitation of the IO functions.
/** The size of the buffer to use for IO.
@param n - page size of the tablespace.
@retval number of pages */
#define IO_BUFFER_SIZE(n) ((1024 * 1024) / n)
Expand Down Expand Up @@ -3427,7 +3425,8 @@ fil_iterate(
? iter.crypt_io_buffer : io_buffer;
byte* const writeptr = readptr;

if (!os_file_read(iter.file, readptr, offset, n_bytes)) {
if (!os_file_read_no_error_handling(iter.file, readptr,
offset, n_bytes)) {
ib_logf(IB_LOG_LEVEL_ERROR, "os_file_read() failed");
return DB_IO_ERROR;
}
Expand Down Expand Up @@ -3713,7 +3712,7 @@ fil_tablespace_iterate(

/* Read the first page and determine the page and zip size. */

if (!os_file_read(file, page, 0, UNIV_PAGE_SIZE)) {
if (!os_file_read_no_error_handling(file, page, 0, UNIV_PAGE_SIZE)) {

err = DB_IO_ERROR;

Expand Down

0 comments on commit e0a0fe7

Please sign in to comment.