Commit 0897a25c authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

MDEV-16596 : Windows - redo log does not work on native 4K sector disks.

Disks with native 4K sectors need 4K alignment and size for  unbuffered IO
(i.e for files opened with FILE_FLAG_NO_BUFFERING)

Innodb opens redo log with FILE_FLAG_NO_BUFFERING, however it always does
512byte IOs. Thus, the IO on 4K native sectors will fail, rendering
Innodb non-functional.

The fix is to check whether OS_FILE_LOG_BLOCK_SIZE is multiple of logical
sector size, and if it is not, reopen the redo log without
FILE_FLAG_NO_BUFFERING flag.
parent 3d4beee1
......@@ -51,7 +51,7 @@ IF(CMAKE_C_COMPILER MATCHES "icl")
ENDIF()
ADD_DEFINITIONS(-D_WINDOWS -D__WIN__ -D_CRT_SECURE_NO_DEPRECATE)
ADD_DEFINITIONS(-D_WIN32_WINNT=0x0501)
ADD_DEFINITIONS(-D_WIN32_WINNT=0x0A00)
# We do not want the windows.h macros min/max
ADD_DEFINITIONS(-DNOMINMAX)
# Speed up build process excluding unused header files
......
......@@ -1691,6 +1691,31 @@ os_file_set_atomic_writes(
#endif
}
/** Check that IO of specific size is possible for the file
opened with FILE_FLAG_NO_BUFFERING.
The requirement is that IO is multiple of the disk sector size.
@param[in] file file handle
@param[in] io_size expected io size
@return true - unbuffered io of requested size is possible, false otherwise.
@note: this function only works correctly with Windows 8 or later,
(GetFileInformationByHandleEx with FileStorageInfo is only supported there).
It will return true on earlier Windows version.
*/
static bool unbuffered_io_possible(HANDLE file, size_t io_size)
{
FILE_STORAGE_INFO info;
if (GetFileInformationByHandleEx(
file, FileStorageInfo, &info, sizeof(info))) {
ULONG sector_size = info.LogicalBytesPerSector;
if (sector_size)
return io_size % sector_size == 0;
}
return true;
}
/****************************************************************//**
NOTE! Use the corresponding macro os_file_create(), not directly
this function!
......@@ -1851,6 +1876,18 @@ os_file_create_func(
(LPCTSTR) name, access, share_mode, NULL,
create_flag, attributes, NULL);
/* If FILE_FLAG_NO_BUFFERING was set, check if this can work at all,
for expected IO sizes. Reopen without the unbuffered flag, if it is won't work*/
if ((file.m_file != INVALID_HANDLE_VALUE)
&& (attributes & FILE_FLAG_NO_BUFFERING)
&& (type == OS_LOG_FILE)
&& !unbuffered_io_possible(file.m_file, OS_FILE_LOG_BLOCK_SIZE)) {
ut_a(CloseHandle(file.m_file));
attributes &= ~FILE_FLAG_NO_BUFFERING;
create_flag = OPEN_ALWAYS;
continue;
}
if (file.m_file == INVALID_HANDLE_VALUE) {
const char* operation;
......
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