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()
This commit is contained in:
parent
89a493d64c
commit
1ee0d09a2b
@ -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);
|
||||
}
|
||||
|
||||
/* Try cached volume info first.*/
|
||||
std::string volume_path_str(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;
|
||||
|
||||
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))) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user