Commit 24ec144c authored by Vladislav Vaintroub's avatar Vladislav Vaintroub

MDEV-27901 Windows : expensive system calls used to calculate file system block size


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.
parent 4e667b96
......@@ -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));
......
......@@ -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
......
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