diff options
author | Vladislav Vaintroub <wlad@mariadb.com> | 2020-10-27 20:54:03 +0100 |
---|---|---|
committer | Vladislav Vaintroub <wlad@mariadb.com> | 2020-10-28 08:30:31 +0100 |
commit | 9478368d8193a7ccc14a1b336ef767aed500909c (patch) | |
tree | e15abbd66712a75ce93b5cade26da3f6e79df6fe /storage/innobase/os | |
parent | db56f9b8521077c119d700927510c7a0e54bd820 (diff) | |
download | mariadb-git-9478368d8193a7ccc14a1b336ef767aed500909c.tar.gz |
MDEV-24037 Use NtFlushBuffersFileEx(FLUSH_FLAGS_FILE_DATA_SYNC_ONLY) on Windows
This avoids flushing file metadata on NTFS , and writing to <drive>:\$Log
file. With heavy write workload this can consume up to 1/3 of the
server's IO bandwidth.
Reviewed by : Marko
Diffstat (limited to 'storage/innobase/os')
-rw-r--r-- | storage/innobase/os/os0file.cc | 59 |
1 files changed, 38 insertions, 21 deletions
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 3afb68d26a1..24134479d8e 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -1891,39 +1891,56 @@ os_file_status_win32( return(true); } +/* Dynamically load NtFlushBuffersFileEx, used in os_file_flush_func */ +#include <winternl.h> +typedef NTSTATUS(WINAPI* pNtFlushBuffersFileEx)( + HANDLE FileHandle, ULONG Flags, PVOID Parameters, ULONG ParametersSize, + PIO_STATUS_BLOCK IoStatusBlock); + +static pNtFlushBuffersFileEx my_NtFlushBuffersFileEx + = (pNtFlushBuffersFileEx)GetProcAddress(GetModuleHandle("ntdll"), + "NtFlushBuffersFileEx"); + /** NOTE! Use the corresponding macro os_file_flush(), not directly this function! Flushes the write buffers of a given file to the disk. @param[in] file handle to a file @return true if success */ -bool -os_file_flush_func( - os_file_t file) +bool os_file_flush_func(os_file_t file) { - ++os_n_fsyncs; - - BOOL ret = FlushFileBuffers(file); + ++os_n_fsyncs; + static bool disable_datasync; - if (ret) { - return(true); - } + if (my_NtFlushBuffersFileEx && !disable_datasync) + { + IO_STATUS_BLOCK iosb{}; + NTSTATUS status= my_NtFlushBuffersFileEx( + file, FLUSH_FLAGS_FILE_DATA_SYNC_ONLY, nullptr, 0, &iosb); + if (!status) + return true; + /* + NtFlushBuffersFileEx(FLUSH_FLAGS_FILE_DATA_SYNC_ONLY) might fail + unless on Win10+, and maybe non-NTFS. Switch to using FlushFileBuffers(). + */ + disable_datasync= true; + } - /* Since Windows returns ERROR_INVALID_FUNCTION if the 'file' is - actually a raw device, we choose to ignore that error if we are using - raw disks */ + if (FlushFileBuffers(file)) + return true; - if (srv_start_raw_disk_in_use && GetLastError() - == ERROR_INVALID_FUNCTION) { - return(true); - } + /* Since Windows returns ERROR_INVALID_FUNCTION if the 'file' is + actually a raw device, we choose to ignore that error if we are using + raw disks */ + if (srv_start_raw_disk_in_use && GetLastError() == ERROR_INVALID_FUNCTION) + return true; - os_file_handle_error(NULL, "flush"); + os_file_handle_error(nullptr, "flush"); - /* It is a fatal error if a file flush does not succeed, because then - the database can get corrupt on disk */ - ut_error; + /* It is a fatal error if a file flush does not succeed, because then + the database can get corrupt on disk */ + ut_error; - return(false); + return false; } /** Retrieves the last error number if an error occurs in a file io function. |