Commit f71c45c7 authored by Jan Lindström's avatar Jan Lindström

MDEV-9678: Data Directory bug

    Problem was that link file (.isl) is also opened using O_DIRECT
    mode and if this fails the whole create table fails on internal
    error.

    Fixed by not using O_DIRECT on link files as they are used only
    on create table and startup and do not contain real data.
    O_DIRECT failures are successfully ignored for data files
    if O_DIRECT is not supported by file system on used
    data directory.
parent 37f915c1
/*****************************************************************************
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 */
......
......@@ -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
......
......@@ -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
......
......@@ -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");
}
}
......
......@@ -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 */
......
......@@ -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);
}
......
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