Commit a98009ab authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

MDEV-12201 innodb_flush_method are not available on Windows

 Remove srv_win_file_flush_method

- Rename srv_unix_file_flush_method to srv_file_flush_method, and
  rename constants to remove UNIX from them, i.e SRV_UNIX_FSYNC=>SRV_FSYNC

- Add SRV_ALL_O_DIRECT_FSYNC corresponding to current Windows default
(no buffering for either log or data, flush on both log and data)

- change os_file_open on Windows to behave identically to Unix wrt
O_DIRECT and O_DSYNC settings. map O_DIRECT to FILE_FLAG_NO_BUFFERING and
O_DSYNC to FILE_FLAG_WRITE_THROUGH

- remove various #ifdef _WIN32
parent 8e05953d
--source include/not_embedded.inc
--source include/have_innodb.inc
--source include/not_windows.inc
--disable_query_log
CALL mtr.add_suppression(".*Failed to set O_DIRECT on file.*");
......
......@@ -156,14 +156,10 @@ initialized. */
fil_system_t* fil_system = NULL;
/** Determine if user has explicitly disabled fsync(). */
#ifndef _WIN32
# define fil_buffering_disabled(s) \
((s)->purpose == FIL_TYPE_TABLESPACE \
&& srv_unix_file_flush_method \
== SRV_UNIX_O_DIRECT_NO_FSYNC)
#else /* _WIN32 */
# define fil_buffering_disabled(s) (0)
#endif /* __WIN32 */
&& srv_file_flush_method \
== SRV_O_DIRECT_NO_FSYNC)
/** Determine if the space id is a user tablespace id or not.
@param[in] space_id Space ID to check
......
......@@ -646,39 +646,34 @@ extern PSI_stage_info srv_stage_alter_table_read_pk_internal_sort;
extern PSI_stage_info srv_stage_buffer_pool_load;
#endif /* HAVE_PSI_STAGE_INTERFACE */
#ifndef _WIN32
/** Alternatives for the file flush option in Unix; see the InnoDB manual
about what these mean */
enum srv_unix_flush_t {
SRV_UNIX_FSYNC = 1, /*!< fsync, the default */
SRV_UNIX_O_DSYNC, /*!< open log files in O_SYNC mode */
SRV_UNIX_LITTLESYNC, /*!< do not call os_file_flush()
enum srv_flush_t {
SRV_FSYNC = 1, /*!< fsync, the default */
SRV_O_DSYNC, /*!< open log files in O_SYNC mode */
SRV_LITTLESYNC, /*!< do not call os_file_flush()
when writing data files, but do flush
after writing to log files */
SRV_UNIX_NOSYNC, /*!< do not flush after writing */
SRV_UNIX_O_DIRECT, /*!< invoke os_file_set_nocache() on
SRV_NOSYNC, /*!< do not flush after writing */
SRV_O_DIRECT, /*!< invoke os_file_set_nocache() on
data files. This implies using
non-buffered IO but still using fsync,
the reason for which is that some FS
do not flush meta-data when
unbuffered IO happens */
SRV_UNIX_O_DIRECT_NO_FSYNC
SRV_O_DIRECT_NO_FSYNC,
/*!< do not use fsync() when using
direct IO i.e.: it can be set to avoid
the fsync() call that we make when
using SRV_UNIX_O_DIRECT. However, in
this case user/DBA should be sure about
the integrity of the meta-data */
SRV_ALL_O_DIRECT_FSYNC
/*!< Traditional Windows appoach to open
all files without caching, and do FileFlushBuffers()*/
};
extern enum srv_unix_flush_t srv_unix_file_flush_method;
#else
/** Alternatives for file i/o in Windows */
enum srv_win_flush_t {
SRV_WIN_IO_NORMAL = 1, /*!< buffered I/O */
SRV_WIN_IO_UNBUFFERED /*!< unbuffered I/O; this is the default */
};
extern enum srv_win_flush_t srv_win_file_flush_method;
#endif /* _WIN32 */
extern enum srv_flush_t srv_file_flush_method;
/** Alternatives for srv_force_recovery. Non-zero values are intended
to help the user get a damaged database up so that he can dump intact
......
......@@ -942,20 +942,17 @@ log_io_complete(
/* It was a checkpoint write */
group = (log_group_t*)((ulint) group - 1);
#ifdef _WIN32
fil_flush(group->space_id);
#else
switch (srv_unix_file_flush_method) {
case SRV_UNIX_O_DSYNC:
case SRV_UNIX_NOSYNC:
switch (srv_file_flush_method) {
case SRV_O_DSYNC:
case SRV_NOSYNC:
break;
case SRV_UNIX_FSYNC:
case SRV_UNIX_LITTLESYNC:
case SRV_UNIX_O_DIRECT:
case SRV_UNIX_O_DIRECT_NO_FSYNC:
case SRV_FSYNC:
case SRV_LITTLESYNC:
case SRV_O_DIRECT:
case SRV_O_DIRECT_NO_FSYNC:
fil_flush(group->space_id);
}
#endif /* _WIN32 */
DBUG_PRINT("ib_log", ("checkpoint info written to group %u",
unsigned(group->id)));
......@@ -1176,11 +1173,8 @@ log_write_flush_to_disk_low()
calling os_event_set()! */
ut_a(log_sys->n_pending_flushes == 1); /* No other threads here */
#ifndef _WIN32
bool do_flush = srv_unix_file_flush_method != SRV_UNIX_O_DSYNC;
#else
bool do_flush = true;
#endif
bool do_flush = srv_file_flush_method != SRV_O_DSYNC;
if (do_flush) {
fil_flush(SRV_LOG_SPACE_FIRST_ID);
}
......@@ -1413,13 +1407,12 @@ log_write_up_to(
srv_stats.log_padded.add(pad_size);
log_sys->write_lsn = write_lsn;
#ifndef _WIN32
if (srv_unix_file_flush_method == SRV_UNIX_O_DSYNC) {
if (srv_file_flush_method == SRV_O_DSYNC) {
/* O_SYNC means the OS did not buffer the log file at all:
so we have also flushed to disk what we have written */
log_sys->flushed_to_disk_lsn = log_sys->write_lsn;
}
#endif /* !_WIN32 */
log_write_mutex_exit();
......@@ -1771,18 +1764,16 @@ log_checkpoint(
recv_apply_hashed_log_recs(true);
}
#ifndef _WIN32
switch (srv_unix_file_flush_method) {
case SRV_UNIX_NOSYNC:
switch (srv_file_flush_method) {
case SRV_NOSYNC:
break;
case SRV_UNIX_O_DSYNC:
case SRV_UNIX_FSYNC:
case SRV_UNIX_LITTLESYNC:
case SRV_UNIX_O_DIRECT:
case SRV_UNIX_O_DIRECT_NO_FSYNC:
case SRV_O_DSYNC:
case SRV_FSYNC:
case SRV_LITTLESYNC:
case SRV_O_DIRECT:
case SRV_O_DIRECT_NO_FSYNC:
fil_flush_file_spaces(FIL_TYPE_TABLESPACE);
}
#endif /* !_WIN32 */
log_mutex_enter();
......
......@@ -2683,8 +2683,8 @@ os_file_create_simple_func(
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)) {
&& (srv_file_flush_method == SRV_O_DIRECT
|| srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC)) {
os_file_set_nocache(file, name, mode_str);
}
......@@ -2955,7 +2955,7 @@ os_file_create_func(
if (!read_only
&& type == OS_LOG_FILE
&& srv_unix_file_flush_method == SRV_UNIX_O_DSYNC) {
&& srv_file_flush_method == SRV_O_DSYNC) {
create_flag |= O_SYNC;
}
......@@ -2992,8 +2992,8 @@ os_file_create_func(
if (!read_only
&& *success
&& (type != OS_LOG_FILE && type != OS_DATA_TEMP_FILE)
&& (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT
|| srv_unix_file_flush_method == SRV_UNIX_O_DIRECT_NO_FSYNC)) {
&& (srv_file_flush_method == SRV_O_DIRECT
|| srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC)) {
os_file_set_nocache(file, name, mode_str);
}
......@@ -4212,20 +4212,55 @@ os_file_create_func(
return(OS_FILE_CLOSED);
}
#ifdef UNIV_NON_BUFFERED_IO
if (type == OS_LOG_FILE) {
/* There is not reason to use buffered write to logs.*/
attributes |= FILE_FLAG_NO_BUFFERING;
}
switch (srv_file_flush_method)
{
case SRV_O_DSYNC:
if (type == OS_LOG_FILE) {
/* Map O_SYNC to FILE_WRITE_THROUGH */
attributes |= FILE_FLAG_WRITE_THROUGH;
}
break;
case SRV_O_DIRECT_NO_FSYNC:
case SRV_O_DIRECT:
if (type == OS_DATA_FILE) {
attributes |= FILE_FLAG_NO_BUFFERING;
}
break;
case SRV_ALL_O_DIRECT_FSYNC:
/*Traditional Windows behavior, no buffering for any files.*/
attributes |= FILE_FLAG_NO_BUFFERING;
break;
case SRV_FSYNC:
case SRV_LITTLESYNC:
break;
case SRV_NOSYNC:
/* Let Windows cache manager handle all writes.*/
attributes &= ~(FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING);
break;
default:
ut_a(false); /* unknown flush mode.*/
}
// TODO: Create a bug, this looks wrong. The flush log
// parameter is dynamic.
if (type == OS_LOG_FILE && srv_flush_log_at_trx_commit == 2) {
/* Do not use unbuffered i/o for the log files because
value 2 denotes that we do not flush the log at every
commit, but only once per second */
} else if (srv_win_file_flush_method == SRV_WIN_IO_UNBUFFERED) {
attributes |= FILE_FLAG_NO_BUFFERING;
attributes &= ~(FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING);
}
#endif /* UNIV_NON_BUFFERED_IO */
DWORD access = GENERIC_READ;
......
......@@ -308,11 +308,10 @@ a heavier load on the I/O sub system. */
ulong srv_insert_buffer_batch_size = 20;
char* srv_file_flush_method_str = NULL;
#ifndef _WIN32
enum srv_unix_flush_t srv_unix_file_flush_method = SRV_UNIX_FSYNC;
#else
enum srv_win_flush_t srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
#endif /* _WIN32 */
enum srv_flush_t srv_file_flush_method = IF_WIN(SRV_ALL_O_DIRECT_FSYNC,SRV_FSYNC);
ulint srv_max_n_open_files = 300;
......
......@@ -1555,38 +1555,30 @@ innobase_start_or_create_for_mysql(void)
if (srv_file_flush_method_str == NULL) {
/* These are the default options */
#ifndef _WIN32
srv_unix_file_flush_method = SRV_UNIX_FSYNC;
srv_file_flush_method = IF_WIN(SRV_ALL_O_DIRECT_FSYNC,SRV_FSYNC);
} else if (0 == ut_strcmp(srv_file_flush_method_str, "fsync")) {
srv_unix_file_flush_method = SRV_UNIX_FSYNC;
srv_file_flush_method = SRV_FSYNC;
} else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DSYNC")) {
srv_unix_file_flush_method = SRV_UNIX_O_DSYNC;
srv_file_flush_method = SRV_O_DSYNC;
} else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DIRECT")) {
srv_unix_file_flush_method = SRV_UNIX_O_DIRECT;
srv_file_flush_method = SRV_O_DIRECT;
} else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DIRECT_NO_FSYNC")) {
srv_unix_file_flush_method = SRV_UNIX_O_DIRECT_NO_FSYNC;
srv_file_flush_method = SRV_O_DIRECT_NO_FSYNC;
} else if (0 == ut_strcmp(srv_file_flush_method_str, "littlesync")) {
srv_unix_file_flush_method = SRV_UNIX_LITTLESYNC;
srv_file_flush_method = SRV_LITTLESYNC;
} else if (0 == ut_strcmp(srv_file_flush_method_str, "nosync")) {
srv_unix_file_flush_method = SRV_UNIX_NOSYNC;
#else
srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
srv_file_flush_method = SRV_NOSYNC;
#ifdef _WIN32
} else if (0 == ut_strcmp(srv_file_flush_method_str, "normal")) {
srv_win_file_flush_method = SRV_WIN_IO_NORMAL;
srv_use_native_aio = FALSE;
srv_file_flush_method = SRV_FSYNC;
} else if (0 == ut_strcmp(srv_file_flush_method_str, "unbuffered")) {
srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
srv_use_native_aio = FALSE;
} else if (0 == ut_strcmp(srv_file_flush_method_str,
"async_unbuffered")) {
srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
#endif /* _WIN32 */
} else {
ib::error() << "Unrecognized value "
......
......@@ -1802,11 +1802,7 @@ trx_flush_log_if_needed_low(
lsn_t lsn) /*!< in: lsn up to which logs are to be
flushed. */
{
#ifdef _WIN32
bool flush = true;
#else
bool flush = srv_unix_file_flush_method != SRV_UNIX_NOSYNC;
#endif /* _WIN32 */
bool flush = srv_file_flush_method != SRV_NOSYNC;
switch (srv_flush_log_at_trx_commit) {
case 3:
......
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