diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 928c72cf546..d918b21d779 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2015, Oracle and/or its affiliates. -Copyright (c) 2013, 2015, MariaDB Corporation. +Copyright (c) 2013, 2016, 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 @@ -3207,10 +3207,12 @@ fil_create_link_file( } link_filepath = fil_make_isl_name(tablename); - + /* Note that OS_FILE_READ_WRITE_CACHED used here to avoid + unnecessary errors on O_DIRECT, link files are not really + a data files. */ file = os_file_create_simple_no_error_handling( innodb_file_data_key, link_filepath, - OS_FILE_CREATE, OS_FILE_READ_WRITE, &success, 0); + OS_FILE_CREATE, OS_FILE_READ_WRITE_CACHED, &success, 0); if (!success) { /* The following call will print an error message */ diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index c610e1790eb..dff5ebd524c 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -128,7 +128,10 @@ enum os_file_create_t { #define OS_FILE_READ_ONLY 333 #define OS_FILE_READ_WRITE 444 #define OS_FILE_READ_ALLOW_DELETE 555 /* for mysqlbackup */ - +#define OS_FILE_READ_WRITE_CACHED 666 /* OS_FILE_READ_WRITE but never + O_DIRECT. Only for + os_file_create_simple_no_error_handling + currently. */ /* Options for file_create */ #define OS_FILE_AIO 61 #define OS_FILE_NORMAL 62 @@ -542,7 +545,7 @@ UNIV_INTERN void os_file_set_nocache( /*================*/ - int fd, /*!< in: file descriptor to alter */ + os_file_t fd, /*!< in: file descriptor to alter */ const char* file_name, /*!< in: file name, used in the diagnostic message */ const char* operation_name);/*!< in: "open" or "create"; used in the diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index dd6b066c647..965a978b962 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -2,7 +2,7 @@ Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2015, MariaDB Corporation. +Copyright (c) 2013, 2016, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Percona Inc.. Those modifications are @@ -1350,7 +1350,8 @@ os_file_create_simple_func( access = GENERIC_READ; - } else if (access_type == OS_FILE_READ_WRITE) { + } else if (access_type == OS_FILE_READ_WRITE + || access_type == OS_FILE_READ_WRITE_CACHED) { access = GENERIC_READ | GENERIC_WRITE; } else { ib_logf(IB_LOG_LEVEL_ERROR, @@ -1454,7 +1455,8 @@ os_file_create_simple_func( #ifdef USE_FILE_LOCK if (!srv_read_only_mode && *success - && access_type == OS_FILE_READ_WRITE + && (access_type == OS_FILE_READ_WRITE + || access_type == OS_FILE_READ_WRITE_CACHED) && os_file_lock(file, name)) { *success = FALSE; @@ -1468,6 +1470,31 @@ os_file_create_simple_func( return(file); } +/** Disable OS I/O caching on the file if the file type and server +configuration requires it. +@param file handle to the file +@param name name of the file, for diagnostics +@param mode_str operation on the file, for diagnostics +@param type OS_LOG_FILE or OS_DATA_FILE +@param access_type if OS_FILE_READ_WRITE_CACHED, then caching will be disabled +unconditionally, ignored otherwise */ +static +void +os_file_set_nocache_if_needed(os_file_t file, const char* name, + const char *mode_str, ulint type, + ulint access_type) +{ + if (srv_read_only_mode || access_type == OS_FILE_READ_WRITE_CACHED) { + return; + } + + if (type == OS_DATA_FILE + && (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT + || (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT_NO_FSYNC))) { + os_file_set_nocache(file, name, mode_str); + } +} + /****************************************************************//** NOTE! Use the corresponding macro os_file_create_simple_no_error_handling(), not directly this function! @@ -1523,7 +1550,8 @@ os_file_create_simple_no_error_handling_func( access = GENERIC_READ; } else if (srv_read_only_mode) { access = GENERIC_READ; - } else if (access_type == OS_FILE_READ_WRITE) { + } else if (access_type == OS_FILE_READ_WRITE + || access_type == OS_FILE_READ_WRITE_CACHED) { access = GENERIC_READ | GENERIC_WRITE; } else if (access_type == OS_FILE_READ_ALLOW_DELETE) { @@ -1595,7 +1623,8 @@ os_file_create_simple_no_error_handling_func( } else { ut_a(access_type == OS_FILE_READ_WRITE - || access_type == OS_FILE_READ_ALLOW_DELETE); + || access_type == OS_FILE_READ_ALLOW_DELETE + || access_type == OS_FILE_READ_WRITE_CACHED); create_flag = O_RDWR; } @@ -1627,18 +1656,16 @@ os_file_create_simple_no_error_handling_func( /* This function is always called for data files, we should disable OS caching (O_DIRECT) here as we do in os_file_create_func(), so we open the same file in the same mode, see man page of open(2). */ - if (!srv_read_only_mode - && *success - && (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT - || srv_unix_file_flush_method == SRV_UNIX_O_DIRECT_NO_FSYNC)) { - - os_file_set_nocache(file, name, mode_str); + if (*success) { + os_file_set_nocache_if_needed(file, name, mode_str, + OS_DATA_FILE, access_type); } #ifdef USE_FILE_LOCK if (!srv_read_only_mode && *success - && access_type == OS_FILE_READ_WRITE + && (access_type == OS_FILE_READ_WRITE + || access_type == OS_FILE_READ_WRITE_CACHED) && os_file_lock(file, name)) { *success = FALSE; @@ -1677,7 +1704,7 @@ UNIV_INTERN void os_file_set_nocache( /*================*/ - int fd /*!< in: file descriptor to alter */ + os_file_t fd /*!< in: file descriptor to alter */ __attribute__((unused)), const char* file_name /*!< in: used in the diagnostic message */ @@ -2007,13 +2034,8 @@ os_file_create_func( /* We disable OS caching (O_DIRECT) only on data files */ - if (!srv_read_only_mode - && *success - && type != OS_LOG_FILE - && (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT - || srv_unix_file_flush_method == SRV_UNIX_O_DIRECT_NO_FSYNC)) { - - os_file_set_nocache(file, name, mode_str); + if (*success) { + os_file_set_nocache_if_needed(file, name, mode_str, type, 0); } #ifdef USE_FILE_LOCK diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 94cf20b79f6..294facf9723 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -3454,7 +3454,7 @@ row_merge_file_create( if (merge_file->fd >= 0) { if (srv_disable_sort_file_cache) { - os_file_set_nocache(merge_file->fd, + os_file_set_nocache((os_file_t)merge_file->fd, "row0merge.cc", "sort"); } } diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index 5f0c52b5cc8..b60a0e9ddaf 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -3240,9 +3240,12 @@ fil_create_link_file( link_filepath = fil_make_isl_name(tablename); + /* Note that OS_FILE_READ_WRITE_CACHED used here to avoid + unnecessary errors on O_DIRECT, link files are not really + a data files. */ file = os_file_create_simple_no_error_handling( innodb_file_data_key, link_filepath, - OS_FILE_CREATE, OS_FILE_READ_WRITE, &success, 0); + OS_FILE_CREATE, OS_FILE_READ_WRITE_CACHED, &success, 0); if (!success) { /* The following call will print an error message */ diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index 7f13c1656ee..a8533f1bb9e 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -2,7 +2,7 @@ Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2015, MariaDB Corporation. +Copyright (c) 2013, 2016, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Percona Inc.. Those modifications are @@ -1422,7 +1422,8 @@ os_file_create_simple_func( access = GENERIC_READ; - } else if (access_type == OS_FILE_READ_WRITE) { + } else if (access_type == OS_FILE_READ_WRITE + || access_type == OS_FILE_READ_WRITE_CACHED) { access = GENERIC_READ | GENERIC_WRITE; } else { ib_logf(IB_LOG_LEVEL_ERROR, @@ -1526,7 +1527,8 @@ os_file_create_simple_func( #ifdef USE_FILE_LOCK if (!srv_read_only_mode && *success - && access_type == OS_FILE_READ_WRITE + && (access_type == OS_FILE_READ_WRITE + || access_type == OS_FILE_READ_WRITE_CACHED) && os_file_lock(file, name)) { *success = FALSE; @@ -1554,15 +1556,16 @@ os_file_set_nocache_if_needed(os_file_t file, const char* name, const char *mode_str, ulint type, ulint access_type) { - if (srv_read_only_mode || access_type == OS_FILE_READ_WRITE_CACHED) + if (srv_read_only_mode || access_type == OS_FILE_READ_WRITE_CACHED) { return; + } if (srv_unix_file_flush_method == SRV_UNIX_ALL_O_DIRECT - || (type != OS_LOG_FILE + || (type == OS_LOG_FILE && (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT - || (srv_unix_file_flush_method - == SRV_UNIX_O_DIRECT_NO_FSYNC)))) + || (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT_NO_FSYNC)))) { os_file_set_nocache(file, name, mode_str); + } } /****************************************************************//** @@ -2154,8 +2157,9 @@ os_file_create_func( } while (retry); - if (*success) { + /* We disable OS caching (O_DIRECT) only on data files */ + if (*success) { os_file_set_nocache_if_needed(file, name, mode_str, type, 0); }