Commit bd1fe261 authored by Arun Kuruvila's avatar Arun Kuruvila

Bug #26880757: MYISAM_USE_MMAP=1 ON WINDOWS FREQUENTLY DOES

               NOT UPDATE FILE ON DISK

Description:- When the server variable, "myisam_use_mmap" is
enabled, MyISAM tables on windows are not updating the file
on disk even when the server variable "flush" is set to 1.
This is inturn making the table corrupted when encountering
a power failure.

Analysis:- When the server variable "myisam_use_mmap" is set,
files of MyISAM tables will be memory mapped using the OS
APIs mmap()/munmap()/msync() on Unix and CreateFileMapping()
/UnmapViewOfFile()/FlushViewOfFile() on Windows. msync() and
FlushViewOfFile() is responsible for flushing the changes
made to the in-core copy of a file that was mapped into
memory using mmap()/CreateFileMapping() back to the
file system.  FLUSH is determined by the OS unless
explicitly called using msync()/FlushViewOfFile().

When the server variables "myisam_use_mmap" and "flush" are
enabled, MyISAM is only flushing the files from file system
cache to disc using "mysql_file_sync()" and not the memory
mapped file from memory to FS cache using "my_msync()".
["my_msync()" inturn calls  msync() on Unix and
FlushViewOfFile() on Windows.

Fix:- As part of the fix, if server variable
"myisam_use_mmap" is enabled along with  "flush",
"my_msync()" is invoked to flush the data in memory to file
system cache and followed by "mysql_file_sync()" which will
flush the data from file system cache to disk.
parent a542209b
/* Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
......@@ -103,6 +103,8 @@ int mi_lock_database(MI_INFO *info, int lock_type)
share->changed=0;
if (myisam_flush)
{
if (share->file_map)
my_msync(info->dfile, share->file_map, share->mmaped_length, MS_SYNC);
if (mysql_file_sync(share->kfile, MYF(0)))
error= my_errno;
if (mysql_file_sync(info->dfile, MYF(0)))
......@@ -450,6 +452,8 @@ int _mi_writeinfo(register MI_INFO *info, uint operation)
#ifdef _WIN32
if (myisam_flush)
{
if (share->file_map)
my_msync(info->dfile, share->file_map, share->mmaped_length, MS_SYNC);
mysql_file_sync(share->kfile, 0);
mysql_file_sync(info->dfile, 0);
}
......
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