diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-03-13 08:07:02 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-03-13 08:07:02 +0200 |
commit | 2e8b0c56a0f78508e62d1527eda2d7c3d9ebdf9a (patch) | |
tree | b8d8ae5d355932d4198881b4d32e0ef478501b2b | |
parent | 47382a2f8c8a6ddd9a363963fcdc75c4eb6a6583 (diff) | |
download | mariadb-git-2e8b0c56a0f78508e62d1527eda2d7c3d9ebdf9a.tar.gz |
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.
-rw-r--r-- | storage/innobase/dict/dict0load.cc | 6 | ||||
-rw-r--r-- | storage/innobase/handler/i_s.cc | 26 | ||||
-rw-r--r-- | storage/innobase/include/dict0load.h | 10 |
3 files changed, 14 insertions, 28 deletions
diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index 8ed947f04cf..486f3c1081c 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -1,7 +1,7 @@ /***************************************************************************** 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 the terms of the GNU General Public License as published by the Free Software @@ -805,7 +805,7 @@ err_len: @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* +static char* dict_get_first_path( ulint space_id) { @@ -863,7 +863,7 @@ dict_get_first_path( ut_ad(len > 0); ut_ad(len < OS_FILE_MAX_PATH); - if (len > 0 && len != UNIV_SQL_NULL) { + if (len > 0 && len < UNIV_SQL_NULL) { filepath = mem_strdupl( reinterpret_cast<const char*>(field), len); diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index b32d703f79e..960bd8113db 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -8057,31 +8057,24 @@ i_s_dict_fill_sys_tablespaces( OK(fields[SYS_TABLESPACES_ZIP_PAGE_SIZE]->store( 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_size_t file; memset(&file, 0xff, sizeof(file)); 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); /* Get the file system (or Volume) block size. */ - dberr_t err = os_file_get_status(filepath, &stat, false, false); - - switch(err) { + switch (dberr_t err = os_file_get_status(filepath, &stat, + false, false)) { case DB_FAIL: ib::warn() << "File '" << filepath << "', failed to get " @@ -8099,7 +8092,8 @@ i_s_dict_fill_sys_tablespaces( break; } - ut_free(filepath); +file_done: + fil_space_release(s); } if (file.m_total_size == static_cast<os_offset_t>(~0)) { diff --git a/storage/innobase/include/dict0load.h b/storage/innobase/include/dict0load.h index 79440533ab2..b288c0b337a 100644 --- a/storage/innobase/include/dict0load.h +++ b/storage/innobase/include/dict0load.h @@ -1,7 +1,7 @@ /***************************************************************************** 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 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( /*============================*/ 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. Try to read it from the fil_system first, then from SYS_DATAFILES. @param[in] table Table object |