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