diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2018-03-19 18:12:37 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2018-03-20 15:31:39 +0200 |
commit | e0a0fe7d8124b9f395a6c97f538693e729a0b043 (patch) | |
tree | 67c907dfefe03d5734ef0f8ba6f1bd3821026284 | |
parent | a80af35a85d329f3ac1456b5931ffc541c8e54c2 (diff) | |
download | mariadb-git-e0a0fe7d8124b9f395a6c97f538693e729a0b043.tar.gz |
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.
-rw-r--r-- | mysql-test/suite/innodb/r/default_row_format_compatibility.result | 3 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/default_row_format_compatibility.test | 7 | ||||
-rw-r--r-- | storage/innobase/os/os0file.cc | 22 | ||||
-rw-r--r-- | storage/innobase/row/row0import.cc | 9 | ||||
-rw-r--r-- | storage/xtradb/os/os0file.cc | 46 | ||||
-rw-r--r-- | storage/xtradb/row/row0import.cc | 9 |
6 files changed, 66 insertions, 30 deletions
diff --git a/mysql-test/suite/innodb/r/default_row_format_compatibility.result b/mysql-test/suite/innodb/r/default_row_format_compatibility.result index 741241ddba0..6ba83f04136 100644 --- a/mysql-test/suite/innodb/r/default_row_format_compatibility.result +++ b/mysql-test/suite/innodb/r/default_row_format_compatibility.result @@ -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 diff --git a/mysql-test/suite/innodb/t/default_row_format_compatibility.test b/mysql-test/suite/innodb/t/default_row_format_compatibility.test index 17ab21ca06b..0f433b1fcfe 100644 --- a/mysql-test/suite/innodb/t/default_row_format_compatibility.test +++ b/mysql-test/suite/innodb/t/default_row_format_compatibility.test @@ -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) diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index fb6ef815476..81614549702 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -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 @@ try_again: 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 @@ try_again: "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 @@ try_again: 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 @@ try_again: "Tried to read " ULINTPF " bytes at offset " UINT64PF ". Was only able to read %ld.", n, offset, (lint) ret); + return FALSE; } #endif /* __WIN__ */ #ifdef __WIN__ diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 5977bd1a77b..c00eb57f91d 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -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; diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index 634ebb2af49..6a63f31b37a 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -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 @@ try_again: 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 @@ try_again: "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 @@ try_again: 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 @@ try_again: "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 @@ retry: 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) { diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc index 5977bd1a77b..c00eb57f91d 100644 --- a/storage/xtradb/row/row0import.cc +++ b/storage/xtradb/row/row0import.cc @@ -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; |