Commit 2e8b0c56 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-21933 INFORMATION_SCHEMA.INNODB_SYS_TABLESPACES accesses SYS_DATAFILES

All tablespace metadata is buffered in fil_system. There is a LRU
mechanism, but that only controls the opening and closing of
fil_node_t::handle.

It is much more efficient and less error-prone to access data file names
by looking up the fil_space_t object rather than by essentially joining
each row with an access to SYS_DATAFILES via the InnoDB internal SQL parser.

dict_get_first_path(): Declare static. The function may only be needed
when loading or updating the data dictionary. Also, change a condition
in order to avoid a bogus GCC 10 -Wstringop-overflow warning for
mem_strdupl() about len==ULINT_UNDEFINED.

i_s_sys_tablespaces_fill_table(): Do not access other InnoDB internal
dictionary tables than SYS_TABLESPACES.
parent 47382a2f
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2016, 2019, MariaDB Corporation. Copyright (c) 2016, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -805,7 +805,7 @@ dict_process_sys_datafiles( ...@@ -805,7 +805,7 @@ dict_process_sys_datafiles(
@param[in] space_id Tablespace ID @param[in] space_id Tablespace ID
@return First filepath (caller must invoke ut_free() on it) @return First filepath (caller must invoke ut_free() on it)
@retval NULL if no SYS_DATAFILES entry was found. */ @retval NULL if no SYS_DATAFILES entry was found. */
char* static char*
dict_get_first_path( dict_get_first_path(
ulint space_id) ulint space_id)
{ {
...@@ -863,7 +863,7 @@ dict_get_first_path( ...@@ -863,7 +863,7 @@ dict_get_first_path(
ut_ad(len > 0); ut_ad(len > 0);
ut_ad(len < OS_FILE_MAX_PATH); ut_ad(len < OS_FILE_MAX_PATH);
if (len > 0 && len != UNIV_SQL_NULL) { if (len > 0 && len < UNIV_SQL_NULL) {
filepath = mem_strdupl( filepath = mem_strdupl(
reinterpret_cast<const char*>(field), reinterpret_cast<const char*>(field),
len); len);
......
...@@ -8057,31 +8057,24 @@ i_s_dict_fill_sys_tablespaces( ...@@ -8057,31 +8057,24 @@ i_s_dict_fill_sys_tablespaces(
OK(fields[SYS_TABLESPACES_ZIP_PAGE_SIZE]->store( OK(fields[SYS_TABLESPACES_ZIP_PAGE_SIZE]->store(
page_size.physical(), true)); page_size.physical(), true));
char* filepath = NULL;
if (FSP_FLAGS_HAS_DATA_DIR(cflags)) {
mutex_enter(&dict_sys->mutex);
filepath = dict_get_first_path(space);
mutex_exit(&dict_sys->mutex);
}
if (filepath == NULL) {
filepath = fil_make_filepath(NULL, name, IBD, false);
}
os_file_stat_t stat; os_file_stat_t stat;
os_file_size_t file; os_file_size_t file;
memset(&file, 0xff, sizeof(file)); memset(&file, 0xff, sizeof(file));
memset(&stat, 0x0, sizeof(stat)); memset(&stat, 0x0, sizeof(stat));
if (filepath != NULL) { if (fil_space_t* s = fil_space_acquire_silent(space)) {
const char *filepath = s->chain.start
? s->chain.start->name : NULL;
if (!filepath) {
goto file_done;
}
file = os_file_get_size(filepath); file = os_file_get_size(filepath);
/* Get the file system (or Volume) block size. */ /* Get the file system (or Volume) block size. */
dberr_t err = os_file_get_status(filepath, &stat, false, false); switch (dberr_t err = os_file_get_status(filepath, &stat,
false, false)) {
switch(err) {
case DB_FAIL: case DB_FAIL:
ib::warn() ib::warn()
<< "File '" << filepath << "', failed to get " << "File '" << filepath << "', failed to get "
...@@ -8099,7 +8092,8 @@ i_s_dict_fill_sys_tablespaces( ...@@ -8099,7 +8092,8 @@ i_s_dict_fill_sys_tablespaces(
break; break;
} }
ut_free(filepath); file_done:
fil_space_release(s);
} }
if (file.m_total_size == static_cast<os_offset_t>(~0)) { if (file.m_total_size == static_cast<os_offset_t>(~0)) {
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2019, MariaDB Corporation. Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software the terms of the GNU General Public License as published by the Free Software
...@@ -88,14 +88,6 @@ dict_get_first_table_name_in_db( ...@@ -88,14 +88,6 @@ dict_get_first_table_name_in_db(
/*============================*/ /*============================*/
const char* name); /*!< in: database name which ends to '/' */ const char* name); /*!< in: database name which ends to '/' */
/** Get the first filepath from SYS_DATAFILES for a given space_id.
@param[in] space_id Tablespace ID
@return First filepath (caller must invoke ut_free() on it)
@retval NULL if no SYS_DATAFILES entry was found. */
char*
dict_get_first_path(
ulint space_id);
/** Make sure the data_file_name is saved in dict_table_t if needed. /** Make sure the data_file_name is saved in dict_table_t if needed.
Try to read it from the fil_system first, then from SYS_DATAFILES. Try to read it from the fil_system first, then from SYS_DATAFILES.
@param[in] table Table object @param[in] table Table object
......
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