Commit e0a0fe7d authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-12396 IMPORT TABLESPACE: Do not retry partial reads

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.
parent a80af35a
......@@ -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
......
......@@ -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)
......
......@@ -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
......@@ -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;
......@@ -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__
......@@ -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;
......@@ -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__
......
......@@ -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)
......@@ -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;
}
......@@ -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;
......
......@@ -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
......@@ -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;
......@@ -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__);
......@@ -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;
......@@ -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__);
......@@ -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);
......@@ -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) {
......
......@@ -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)
......@@ -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;
}
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment