mirror of
https://github.com/MariaDB/server.git
synced 2025-12-07 17:42:39 +03:00
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.
This commit is contained in:
@@ -51,7 +51,7 @@ IF(CMAKE_C_COMPILER MATCHES "icl")
|
|||||||
ENDIF()
|
ENDIF()
|
||||||
|
|
||||||
ADD_DEFINITIONS(-D_WINDOWS -D__WIN__ -D_CRT_SECURE_NO_DEPRECATE)
|
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
|
# We do not want the windows.h macros min/max
|
||||||
ADD_DEFINITIONS(-DNOMINMAX)
|
ADD_DEFINITIONS(-DNOMINMAX)
|
||||||
# Speed up build process excluding unused header files
|
# Speed up build process excluding unused header files
|
||||||
|
|||||||
@@ -1691,6 +1691,31 @@ os_file_set_atomic_writes(
|
|||||||
#endif
|
#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
|
NOTE! Use the corresponding macro os_file_create(), not directly
|
||||||
this function!
|
this function!
|
||||||
@@ -1851,6 +1876,18 @@ os_file_create_func(
|
|||||||
(LPCTSTR) name, access, share_mode, NULL,
|
(LPCTSTR) name, access, share_mode, NULL,
|
||||||
create_flag, attributes, 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) {
|
if (file.m_file == INVALID_HANDLE_VALUE) {
|
||||||
const char* operation;
|
const char* operation;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user