summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVladislav Vaintroub <wlad@mariadb.com>2022-02-20 20:48:31 +0100
committerVladislav Vaintroub <wlad@mariadb.com>2022-02-20 22:00:42 +0100
commit24ec144c63b36402adaff2bc12aaabefa40bdd51 (patch)
treea830fcea67cfb38822ce437bf242246ea0dfd809
parent4e667b96389a0d77836770b05d78110caec66f9d (diff)
downloadmariadb-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.cc29
-rw-r--r--storage/innobase/os/os0file.cc72
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,
- &sectorsPerCluster,
- &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, &sectorsPerCluster, &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