mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01: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:
parent
3d4beee1a9
commit
0897a25c0f
2 changed files with 38 additions and 1 deletions
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in a new issue