diff options
author | Vladislav Vaintroub <wlad@mariadb.com> | 2022-02-20 20:48:31 +0100 |
---|---|---|
committer | Vladislav Vaintroub <wlad@mariadb.com> | 2022-02-20 22:00:42 +0100 |
commit | 24ec144c63b36402adaff2bc12aaabefa40bdd51 (patch) | |
tree | a830fcea67cfb38822ce437bf242246ea0dfd809 | |
parent | 4e667b96389a0d77836770b05d78110caec66f9d (diff) | |
download | mariadb-git-24ec144c63b36402adaff2bc12aaabefa40bdd51.tar.gz |
MDEV-27901 Windows : expensive system calls used to calculate file system block sizebb-10.2-wlad
The result is not used anywhere but in the output of Innodb information
schema, but this can take as much as 7%CPU (only) on a benchmark.
Fix to move fs blocksize calculate to where it is used.
-rw-r--r-- | storage/innobase/handler/i_s.cc | 29 | ||||
-rw-r--r-- | storage/innobase/os/os0file.cc | 72 |
2 files changed, 37 insertions, 64 deletions
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 1111d974ad0..fb7f0e5ecbb 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -6745,6 +6745,9 @@ static ST_FIELD_INFO innodb_sys_tablespaces_fields_info[]= END_OF_ST_FIELD_INFO }; + +extern size_t os_file_get_fs_block_size(const char *path); + /**********************************************************************//** Function to fill INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES with information collected by scanning SYS_TABLESPACESS table. @@ -6814,11 +6817,10 @@ i_s_dict_fill_sys_tablespaces( OK(fields[SYS_TABLESPACES_ZIP_PAGE_SIZE]->store( page_size.physical(), true)); - os_file_stat_t stat; + size_t fs_block_size = 0; os_file_size_t file; memset(&file, 0xff, sizeof(file)); - memset(&stat, 0x0, sizeof(stat)); if (fil_space_t* s = fil_space_acquire_silent(space)) { const char *filepath = s->chain.start @@ -6828,36 +6830,19 @@ i_s_dict_fill_sys_tablespaces( } file = os_file_get_size(filepath); - - /* Get the file system (or Volume) block size. */ - switch (dberr_t err = os_file_get_status(filepath, &stat, - false, false)) { - case DB_FAIL: - ib::warn() - << "File '" << filepath << "', failed to get " - << "stats"; - break; - - case DB_SUCCESS: - case DB_NOT_FOUND: - break; - - default: - ib::error() << "File '" << filepath << "' " << err; - break; - } + fs_block_size= os_file_get_fs_block_size(filepath); file_done: fil_space_release(s); } if (file.m_total_size == static_cast<os_offset_t>(~0)) { - stat.block_size = 0; + fs_block_size = 0; file.m_total_size = 0; file.m_alloc_size = 0; } - OK(fields[SYS_TABLESPACES_FS_BLOCK_SIZE]->store(stat.block_size, true)); + OK(fields[SYS_TABLESPACES_FS_BLOCK_SIZE]->store(fs_block_size, true)); OK(fields[SYS_TABLESPACES_FILE_SIZE]->store(file.m_total_size, true)); diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 48be5256ab1..fbfbdb27c0c 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -4795,48 +4795,6 @@ os_file_get_status_win32( CloseHandle(fh); } } - stat_info->block_size = 0; - - /* What follows, is calculation of FS block size, which is not important - (it is just shown in I_S innodb tables). The error to calculate it will be ignored.*/ - char volname[MAX_PATH]; - BOOL result = GetVolumePathName(path, volname, MAX_PATH); - static bool warned_once = false; - if (!result) { - if (!warned_once) { - ib::warn() - << "os_file_get_status_win32: " - << "Failed to get the volume path name for: " - << path - << "- OS error number " << GetLastError(); - warned_once = true; - } - return(DB_SUCCESS); - } - - DWORD sectorsPerCluster; - DWORD bytesPerSector; - DWORD numberOfFreeClusters; - DWORD totalNumberOfClusters; - - result = GetDiskFreeSpace( - (LPCSTR) volname, - §orsPerCluster, - &bytesPerSector, - &numberOfFreeClusters, - &totalNumberOfClusters); - - if (!result) { - if (!warned_once) { - ib::warn() - << "GetDiskFreeSpace(" << volname << ",...) " - << "failed " - << "- OS error number " << GetLastError(); - warned_once = true; - } - return(DB_SUCCESS); - } - stat_info->block_size = bytesPerSector * sectorsPerCluster; } else { stat_info->type = OS_FILE_TYPE_UNKNOWN; } @@ -5736,6 +5694,36 @@ os_is_sparse_file_supported(os_file_t fh) #endif /* _WIN32 */ } +/* + Get file system block size, by path. + + This is expensive on Windows, and not very useful in general, + (only shown in some I_S table), so we keep that out of usual + stat. +*/ +size_t os_file_get_fs_block_size(const char *path) +{ +#ifdef _WIN32 + char volname[MAX_PATH]; + if (!GetVolumePathName(path, volname, MAX_PATH)) + return 0; + DWORD sectorsPerCluster; + DWORD bytesPerSector; + DWORD numberOfFreeClusters; + DWORD totalNumberOfClusters; + + if (GetDiskFreeSpace(volname, §orsPerCluster, &bytesPerSector, + &numberOfFreeClusters, &totalNumberOfClusters)) + return ((size_t) bytesPerSector) * sectorsPerCluster; +#else + os_file_stat_t info; + if (os_file_get_status(path, &info, false, false) == DB_SUCCESS) + return info.block_size; +#endif + return 0; +} + + /** This function returns information about the specified file @param[in] path pathname of the file @param[out] stat_info information of a file in a directory |