From bd1fe2613a920d3c193f2d72d84ac8d954e4f3f6 Mon Sep 17 00:00:00 2001 From: Arun Kuruvila Date: Thu, 26 Oct 2017 18:07:36 +0530 Subject: 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. --- storage/myisam/mi_locking.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'storage/myisam/mi_locking.c') diff --git a/storage/myisam/mi_locking.c b/storage/myisam/mi_locking.c index 98c2a6c7549..4a33e838fb9 100644 --- a/storage/myisam/mi_locking.c +++ b/storage/myisam/mi_locking.c @@ -1,4 +1,4 @@ -/* 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); } -- cgit v1.2.1