Commit 1ee0d09a authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

MDEV-32228 speedup opening tablespaces on Windows

is_file_on_ssd() is more expensive than it should be.
It caches the results by volume name, but still calls GetVolumePathName()
every time, which, as procmon shows, opens multiple directories in
filesystem hierarchy (db directory, datadir, and all ancestors)

The fix is to cache SSD status by volume serial ID, which is cheap to
retrieve with GetFileInformationByHandleEx()
parent 89a493d6
......@@ -7358,36 +7358,40 @@ static bool is_volume_on_ssd(const char *volume_mount_point)
}
#include <unordered_map>
static bool is_file_on_ssd(char *file_path)
static bool is_path_on_ssd(char *file_path)
{
/* Cache of volume_path => volume_info, protected by rwlock.*/
static std::unordered_map<std::string, bool> cache;
static SRWLOCK lock= SRWLOCK_INIT;
/* Preset result, in case something fails, e.g we're on network drive.*/
char volume_path[MAX_PATH];
if (!GetVolumePathName(file_path, volume_path, array_elements(volume_path)))
return false;
return is_volume_on_ssd(volume_path);
}
static bool is_file_on_ssd(HANDLE handle, char *file_path)
{
ULONGLONG volume_serial_number;
FILE_ID_INFO info;
if(!GetFileInformationByHandleEx(handle, FileIdInfo, &info, sizeof(info)))
return false;
volume_serial_number= info.VolumeSerialNumber;
/* Try cached volume info first.*/
std::string volume_path_str(volume_path);
static std::unordered_map<ULONGLONG, bool> cache;
static SRWLOCK lock= SRWLOCK_INIT;
bool found;
bool result;
AcquireSRWLockShared(&lock);
auto e= cache.find(volume_path_str);
auto e= cache.find(volume_serial_number);
if ((found= e != cache.end()))
result= e->second;
ReleaseSRWLockShared(&lock);
if (found)
return result;
result= is_volume_on_ssd(volume_path);
/* Update cache */
AcquireSRWLockExclusive(&lock);
cache[volume_path_str]= result;
ReleaseSRWLockExclusive(&lock);
if (!found)
{
result= is_path_on_ssd(file_path);
/* Update cache */
AcquireSRWLockExclusive(&lock);
cache[volume_serial_number]= result;
ReleaseSRWLockExclusive(&lock);
}
return result;
}
......@@ -7427,7 +7431,7 @@ void fil_node_t::find_metadata(os_file_t file
space->atomic_write_supported = space->purpose == FIL_TYPE_TEMPORARY
|| space->purpose == FIL_TYPE_IMPORT;
#ifdef _WIN32
on_ssd = is_file_on_ssd(name);
on_ssd = is_file_on_ssd(file, name);
FILE_STORAGE_INFO info;
if (GetFileInformationByHandleEx(
file, FileStorageInfo, &info, sizeof(info))) {
......
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