From 1ee0d09a2bc2b7c6131ffde19c6b4246ab3f2147 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 22 Sep 2023 12:11:57 +0200 Subject: [PATCH] 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() --- storage/innobase/os/os0file.cc | 42 +++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 832f5e05658..71e48da0dec 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -7358,36 +7358,40 @@ static bool is_volume_on_ssd(const char *volume_mount_point) } #include -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 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 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))) {