Skip to content

Commit 0897a25

Browse files
committed
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.
1 parent 3d4beee commit 0897a25

File tree

2 files changed

+38
-1
lines changed

2 files changed

+38
-1
lines changed

cmake/os/Windows.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ IF(CMAKE_C_COMPILER MATCHES "icl")
5151
ENDIF()
5252

5353
ADD_DEFINITIONS(-D_WINDOWS -D__WIN__ -D_CRT_SECURE_NO_DEPRECATE)
54-
ADD_DEFINITIONS(-D_WIN32_WINNT=0x0501)
54+
ADD_DEFINITIONS(-D_WIN32_WINNT=0x0A00)
5555
# We do not want the windows.h macros min/max
5656
ADD_DEFINITIONS(-DNOMINMAX)
5757
# Speed up build process excluding unused header files

storage/xtradb/os/os0file.cc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,6 +1691,31 @@ os_file_set_atomic_writes(
16911691
#endif
16921692
}
16931693

1694+
/** Check that IO of specific size is possible for the file
1695+
opened with FILE_FLAG_NO_BUFFERING.
1696+
1697+
The requirement is that IO is multiple of the disk sector size.
1698+
1699+
@param[in] file file handle
1700+
@param[in] io_size expected io size
1701+
@return true - unbuffered io of requested size is possible, false otherwise.
1702+
1703+
@note: this function only works correctly with Windows 8 or later,
1704+
(GetFileInformationByHandleEx with FileStorageInfo is only supported there).
1705+
It will return true on earlier Windows version.
1706+
*/
1707+
static bool unbuffered_io_possible(HANDLE file, size_t io_size)
1708+
{
1709+
FILE_STORAGE_INFO info;
1710+
if (GetFileInformationByHandleEx(
1711+
file, FileStorageInfo, &info, sizeof(info))) {
1712+
ULONG sector_size = info.LogicalBytesPerSector;
1713+
if (sector_size)
1714+
return io_size % sector_size == 0;
1715+
}
1716+
return true;
1717+
}
1718+
16941719
/****************************************************************//**
16951720
NOTE! Use the corresponding macro os_file_create(), not directly
16961721
this function!
@@ -1851,6 +1876,18 @@ os_file_create_func(
18511876
(LPCTSTR) name, access, share_mode, NULL,
18521877
create_flag, attributes, NULL);
18531878

1879+
/* If FILE_FLAG_NO_BUFFERING was set, check if this can work at all,
1880+
for expected IO sizes. Reopen without the unbuffered flag, if it is won't work*/
1881+
if ((file.m_file != INVALID_HANDLE_VALUE)
1882+
&& (attributes & FILE_FLAG_NO_BUFFERING)
1883+
&& (type == OS_LOG_FILE)
1884+
&& !unbuffered_io_possible(file.m_file, OS_FILE_LOG_BLOCK_SIZE)) {
1885+
ut_a(CloseHandle(file.m_file));
1886+
attributes &= ~FILE_FLAG_NO_BUFFERING;
1887+
create_flag = OPEN_ALWAYS;
1888+
continue;
1889+
}
1890+
18541891
if (file.m_file == INVALID_HANDLE_VALUE) {
18551892
const char* operation;
18561893

0 commit comments

Comments
 (0)