mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 04:53:01 +01:00
224 lines
6.3 KiB
C++
224 lines
6.3 KiB
C++
/*****************************************************************************
|
|
|
|
Copyright (c) 2014, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
|
Copyright (c) 2019, 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
|
|
Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
|
|
|
|
*****************************************************************************/
|
|
|
|
/**************************************************//**
|
|
@file ut/ut0new.cc
|
|
Instrumented memory allocator.
|
|
|
|
Created May 26, 2014 Vasil Dimov
|
|
*******************************************************/
|
|
|
|
#include "univ.i"
|
|
|
|
/** Maximum number of retries to allocate memory. */
|
|
const size_t alloc_max_retries = 60;
|
|
|
|
/** Keys for registering allocations with performance schema.
|
|
Keep this list alphabetically sorted. */
|
|
#ifdef BTR_CUR_HASH_ADAPT
|
|
PSI_memory_key mem_key_ahi;
|
|
#endif /* BTR_CUR_HASH_ADAPT */
|
|
PSI_memory_key mem_key_buf_buf_pool;
|
|
PSI_memory_key mem_key_dict_stats_bg_recalc_pool_t;
|
|
PSI_memory_key mem_key_dict_stats_index_map_t;
|
|
PSI_memory_key mem_key_dict_stats_n_diff_on_level;
|
|
PSI_memory_key mem_key_other;
|
|
PSI_memory_key mem_key_row_log_buf;
|
|
PSI_memory_key mem_key_row_merge_sort;
|
|
PSI_memory_key mem_key_std;
|
|
|
|
#ifdef UNIV_PFS_MEMORY
|
|
|
|
/** Auxiliary array of performance schema 'PSI_memory_info'.
|
|
Each allocation appears in
|
|
performance_schema.memory_summary_global_by_event_name (and alike) in the form
|
|
of e.g. 'memory/innodb/NAME' where the last component NAME is picked from
|
|
the list below:
|
|
1. If key is specified, then the respective name is used
|
|
2. Without a specified key, allocations from inside std::* containers use
|
|
mem_key_std
|
|
3. Without a specified key, allocations from outside std::* pick up the key
|
|
based on the file name, and if file name is not found in the predefined list
|
|
(in ut_new_boot()) then mem_key_other is used.
|
|
Keep this list alphabetically sorted. */
|
|
static PSI_memory_info pfs_info[] = {
|
|
#ifdef BTR_CUR_HASH_ADAPT
|
|
{&mem_key_ahi, "adaptive hash index", 0},
|
|
#endif /* BTR_CUR_HASH_ADAPT */
|
|
{&mem_key_buf_buf_pool, "buf_buf_pool", 0},
|
|
{&mem_key_dict_stats_bg_recalc_pool_t, "dict_stats_bg_recalc_pool_t", 0},
|
|
{&mem_key_dict_stats_index_map_t, "dict_stats_index_map_t", 0},
|
|
{&mem_key_dict_stats_n_diff_on_level, "dict_stats_n_diff_on_level", 0},
|
|
{&mem_key_other, "other", 0},
|
|
{&mem_key_row_log_buf, "row_log_buf", 0},
|
|
{&mem_key_row_merge_sort, "row_merge_sort", 0},
|
|
{&mem_key_std, "std", 0},
|
|
};
|
|
|
|
/** Map used for default performance schema keys, based on file name of the
|
|
caller. The key is the file name of the caller and the value is a pointer
|
|
to a PSI_memory_key variable to be passed to performance schema methods.
|
|
We use ut_strcmp_functor because by default std::map will compare the pointers
|
|
themselves (cont char*) and not do strcmp(). */
|
|
typedef std::map<const char*, PSI_memory_key*, ut_strcmp_functor>
|
|
mem_keys_auto_t;
|
|
|
|
/** Map of filename/pfskey, used for tracing allocations that have not
|
|
provided a manually created pfs key. This map is only ever modified (bulk
|
|
insert) at startup in a single-threaded environment by ut_new_boot().
|
|
Later it is only read (only std::map::find() is called) from multithreaded
|
|
environment, thus it is not protected by any latch. */
|
|
static mem_keys_auto_t mem_keys_auto;
|
|
|
|
#endif /* UNIV_PFS_MEMORY */
|
|
|
|
/** Setup the internal objects needed for UT_NEW() to operate.
|
|
This must be called before the first call to UT_NEW(). */
|
|
void
|
|
ut_new_boot()
|
|
{
|
|
#ifdef UNIV_PFS_MEMORY
|
|
static const char* auto_event_names[] = {
|
|
/* Keep this list alphabetically sorted. */
|
|
"btr0btr",
|
|
"btr0bulk",
|
|
"btr0cur",
|
|
"btr0pcur",
|
|
"btr0sea",
|
|
"buf0buf",
|
|
"buf0dblwr",
|
|
"buf0dump",
|
|
"buf0flu",
|
|
"buf0lru",
|
|
"dict0dict",
|
|
"dict0mem",
|
|
"dict0stats",
|
|
"dict0stats_bg",
|
|
"eval0eval",
|
|
"fil0fil",
|
|
"fsp0file",
|
|
"fsp0space",
|
|
"fsp0sysspace",
|
|
"fts0ast",
|
|
"fts0config",
|
|
"fts0fts",
|
|
"fts0opt",
|
|
"fts0pars",
|
|
"fts0que",
|
|
"fts0sql",
|
|
"gis0sea",
|
|
"ha0ha",
|
|
"ha_innodb",
|
|
"handler0alter",
|
|
"hash0hash",
|
|
"i_s",
|
|
"ibuf0ibuf",
|
|
"lexyy",
|
|
"lock0lock",
|
|
"log0log",
|
|
"log0recv",
|
|
"mem0mem",
|
|
"os0event",
|
|
"os0file",
|
|
"page0cur",
|
|
"page0zip",
|
|
"pars0lex",
|
|
"read0read",
|
|
"rem0rec",
|
|
"row0ftsort",
|
|
"row0import",
|
|
"row0log",
|
|
"row0merge",
|
|
"row0mysql",
|
|
"row0sel",
|
|
"row0trunc",
|
|
"srv0conc",
|
|
"srv0srv",
|
|
"srv0start",
|
|
"sync0arr",
|
|
"sync0debug",
|
|
"sync0rw",
|
|
"sync0types",
|
|
"trx0i_s",
|
|
"trx0purge",
|
|
"trx0roll",
|
|
"trx0rseg",
|
|
"trx0sys",
|
|
"trx0trx",
|
|
"trx0undo",
|
|
"ut0list",
|
|
"ut0mem",
|
|
"ut0mutex",
|
|
"ut0pool",
|
|
"ut0rbt",
|
|
"ut0wqueue",
|
|
};
|
|
static const size_t n_auto = UT_ARR_SIZE(auto_event_names);
|
|
static PSI_memory_key auto_event_keys[n_auto];
|
|
static PSI_memory_info pfs_info_auto[n_auto];
|
|
|
|
for (size_t i = 0; i < n_auto; i++) {
|
|
|
|
const std::pair<mem_keys_auto_t::iterator, bool> ret
|
|
MY_ATTRIBUTE((unused))
|
|
= mem_keys_auto.insert(
|
|
mem_keys_auto_t::value_type(auto_event_names[i],
|
|
&auto_event_keys[i]));
|
|
|
|
/* ret.second is true if new element has been inserted */
|
|
ut_a(ret.second);
|
|
|
|
/* e.g. "btr0btr" */
|
|
pfs_info_auto[i].m_name = auto_event_names[i];
|
|
|
|
/* a pointer to the pfs key */
|
|
pfs_info_auto[i].m_key = &auto_event_keys[i];
|
|
|
|
pfs_info_auto[i].m_flags = 0;
|
|
}
|
|
|
|
PSI_MEMORY_CALL(register_memory)("innodb",
|
|
pfs_info,
|
|
UT_ARR_SIZE(pfs_info));
|
|
PSI_MEMORY_CALL(register_memory)("innodb",
|
|
pfs_info_auto,
|
|
n_auto);
|
|
#endif /* UNIV_PFS_MEMORY */
|
|
}
|
|
|
|
#ifdef UNIV_PFS_MEMORY
|
|
|
|
/** Retrieve a memory key (registered with PFS), given a portion of the file
|
|
name of the caller.
|
|
@param[in] file portion of the filename - basename without an extension
|
|
@return registered memory key or PSI_NOT_INSTRUMENTED if not found */
|
|
PSI_memory_key
|
|
ut_new_get_key_by_file(
|
|
const char* file)
|
|
{
|
|
mem_keys_auto_t::const_iterator el = mem_keys_auto.find(file);
|
|
|
|
if (el != mem_keys_auto.end()) {
|
|
return(*(el->second));
|
|
}
|
|
|
|
return(PSI_NOT_INSTRUMENTED);
|
|
}
|
|
|
|
#endif /* UNIV_PFS_MEMORY */
|