当前位置:网站首页>MySQL source code --table_ cache

MySQL source code --table_ cache

2022-06-13 07:36:00 Fish is not fish

One .table_cache Related parameters

1.open_files_limit
2.max_connections
3.table_open_cache
4.table_definition_cache

problem ?

I often see myself my.cnf The sum of the four values set is in MySQL The values seen in are different .

I modified one of the parameters , Structure found that all the above four parameters have changed .
How much should the parameter be set ?

Two . Initialization of source code analysis

1. Constant definition

Source location :/sql/sql_const.h

#define TABLE_OPEN_CACHE_MIN 400
#define TABLE_OPEN_CACHE_DEFAULT 2000
#define TABLE_DEF_CACHE_DEFAULT 400
#define MAX_CONNECTIONS_DEFAULT 151
#define TABLE_DEF_CACHE_MIN 400

Source location :/mysql-5.7.33/my_global.h

#ifdef _WIN32
#define MY_FILE_MIN 2048
#else
#define MY_FILE_MIN 0
#endif

#ifdef _WIN32
#define MY_NFILE (16384 + MY_FILE_MIN)
#else
#define MY_NFILE 64
#endif

#define OS_FILE_LIMIT UINT_MAX

2. Variable static file

Source location :/mysql-5.7.33/sql/sys_vars.cc

static Sys_var_ulong Sys_open_files_limit(
       "open_files_limit",
       "If this is not 0, then mysqld will use this value to reserve file "
       "descriptors to use with setrlimit(). If this value is 0 then mysqld "
       "will reserve max_connections*5 or max_connections + table_open_cache*2 "
       "(whichever is larger) number of file descriptors",
       READ_ONLY GLOBAL_VAR(open_files_limit), CMD_LINE(REQUIRED_ARG),
       VALID_RANGE(0, OS_FILE_LIMIT), DEFAULT(0), BLOCK_SIZE(1),
       NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(NULL), ON_UPDATE(NULL),
       NULL,
       sys_var::PARSE_EARLY);

static Sys_var_ulong Sys_max_connections(
       "max_connections", "The number of simultaneous clients allowed",
       GLOBAL_VAR(max_connections), CMD_LINE(REQUIRED_ARG),
       VALID_RANGE(1, 100000),
       DEFAULT(MAX_CONNECTIONS_DEFAULT),
       BLOCK_SIZE(1),
       NO_MUTEX_GUARD,
       NOT_IN_BINLOG,
       ON_CHECK(0),
       ON_UPDATE(0),
       NULL,
       sys_var::PARSE_EARLY);


static bool fix_table_cache_size(sys_var *self, THD *thd, enum_var_type type)
{
    
  table_cache_size_per_instance= table_cache_size / table_cache_instances;
  return false;
}

static Sys_var_ulong Sys_table_cache_size(
       "table_open_cache", "The number of cached open tables "
       "(total for all table cache instances)",
       GLOBAL_VAR(table_cache_size), CMD_LINE(REQUIRED_ARG),
       VALID_RANGE(1, 512*1024), DEFAULT(TABLE_OPEN_CACHE_DEFAULT),
       BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(NULL),
       ON_UPDATE(fix_table_cache_size),
       NULL,
       sys_var::PARSE_EARLY);

static Sys_var_ulong Sys_table_cache_instances(
       "table_open_cache_instances", "The number of table cache instances",
       READ_ONLY GLOBAL_VAR(table_cache_instances), CMD_LINE(REQUIRED_ARG),
       VALID_RANGE(1, Table_cache_manager::MAX_TABLE_CACHES),
       DEFAULT(Table_cache_manager::DEFAULT_MAX_TABLE_CACHES),
       BLOCK_SIZE(1), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(NULL),
       ON_UPDATE(NULL), NULL,
       sys_var::PARSE_EARLY);

static Sys_var_ulong Sys_table_def_size(
       "table_definition_cache",
       "The number of cached table definitions",
       GLOBAL_VAR(table_def_size),
       CMD_LINE(REQUIRED_ARG, OPT_TABLE_DEFINITION_CACHE),
       VALID_RANGE(TABLE_DEF_CACHE_MIN, 512*1024),
       DEFAULT(TABLE_DEF_CACHE_DEFAULT),
       BLOCK_SIZE(1),
       NO_MUTEX_GUARD,
       NOT_IN_BINLOG,
       ON_CHECK(NULL),
       ON_UPDATE(NULL),
       NULL,
       sys_var::PARSE_EARLY);

3、 ... and . The specific process of source code analysis

1. Initialization flow

Location :/mysql-5.7.33/sql/mysqld.cc

#endif
init_sql_statement_names();
sys_var_init(); // System parameter initialization 
ulong requested_open_files; //requested_open_files  Very important variables 
adjust_related_options(&requested_open_files); //

#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
if (ho_error == 0)
{
    
if (!opt_help && !opt_bootstrap)
{
    
/* Add sizing hints from the server sizing parameters. */ // The following parameters will be adjusted according to the relevant parameters of the server , That is to say adjust_related_options This function returns the value to set the following parameters 
pfs_param.m_hints.m_table_definition_cache= table_def_size;
pfs_param.m_hints.m_table_open_cache= table_cache_size;
pfs_param.m_hints.m_max_connections= max_connections;
pfs_param.m_hints.m_open_files_limit= requested_open_files;
pfs_param.m_hints.m_max_prepared_stmt_count= max_prepared_stmt_count;

PSI_hook= initialize_performance_schema(&pfs_param);
if (PSI_hook == NULL && pfs_param.m_enabled)
{
    
pfs_param.m_enabled= false;
sql_print_warning("Performance schema disabled (reason: init failed).");
}
}
}
#else
.......
void adjust_related_options(ulong *requested_open_files)
{
    
/* In bootstrap, disable grant tables (we are about to create them) */
if (opt_bootstrap)
opt_noacl= 1;
// Because these parameters will affect each other's values , So we can see the initialization sequence of these parameters , And dependency is key  
/* The order is critical here, because of dependencies. */
adjust_open_files_limit(requested_open_files);
adjust_max_connections(*requested_open_files);
adjust_table_cache_size(*requested_open_files);
adjust_table_def_size();
}
...........

2.open_files_limit relevant

Location :/mysql-5.7.33/sql/mysqld.cc

void adjust_open_files_limit(ulong *requested_open_files)
{
    
  ulong limit_1;
  ulong limit_2;
  ulong limit_3;
  ulong request_open_files;
  ulong effective_open_files;

  /* MyISAM requires two file handles per table. */
  limit_1= 10 + max_connections + table_cache_size * 2;

  /* We are trying to allocate no less than max_connections*5 file handles (i.e. we are trying to set the limit so that they will be available). */
  limit_2= max_connections * 5;

  /* Try to allocate no less than 5000 by default. */
  limit_3= open_files_limit ? open_files_limit : 5000;

  request_open_files= max<ulong>(max<ulong>(limit_1, limit_2), limit_3);

  /* Notice: my_set_max_open_files() may return more than requested. */
  effective_open_files= my_set_max_open_files(request_open_files);   // This function is very important , The following values should be judged according to this  my_set_max_open_files

  if (effective_open_files < request_open_files)
  {
    
    if (open_files_limit == 0)
    {
    
      sql_print_warning("Changed limits: max_open_files: %lu (requested %lu)",
                        effective_open_files, request_open_files);
    }
    else
    {
    
      sql_print_warning("Could not increase number of max_open_files to "
                        "more than %lu (request: %lu)",
                        effective_open_files, request_open_files);
    }
  }

  open_files_limit= effective_open_files;
  if (requested_open_files)
    *requested_open_files= min<ulong>(effective_open_files, request_open_files);
}

my_set_max_open_files

/* Change number of open files SYNOPSIS: my_set_max_open_files() files Number of requested files RETURN number of files available for open */

uint my_set_max_open_files(uint files)
{
    
  struct st_my_file_info *tmp;
  DBUG_ENTER("my_set_max_open_files");
  DBUG_PRINT("enter",("files: %u my_file_limit: %u", files, my_file_limit));

  files+= MY_FILE_MIN;   //0 
  files= set_max_open_files(MY_MIN(files, OS_FILE_LIMIT));  //OS_FILE_LIMIT = UINT_MAX  The type is  unsigned int  The maximum value of the variable . 4294967295, This is supposed to be 0
  if (files <= MY_NFILE)
    DBUG_RETURN(files);

  if (!(tmp= (struct st_my_file_info*) my_malloc(key_memory_my_file_info,
                                                 sizeof(*tmp) * files,
						 MYF(MY_WME))))
    DBUG_RETURN(MY_NFILE);

  /* Copy any initialized files */
  memcpy((char*) tmp, (char*) my_file_info,
         sizeof(*tmp) * MY_MIN(my_file_limit, files));
  memset((tmp + my_file_limit), 0, 
        MY_MAX((int) (files - my_file_limit), 0) * sizeof(*tmp));
  my_free_open_file_info();			/* Free if already allocated */
  my_file_info= tmp;
  my_file_limit= files;
  DBUG_PRINT("exit",("files: %u", files));
  DBUG_RETURN(files);
}



/* This value is certainly wrong on all 64bit platforms, and also wrong on many 32bit platforms. It is better to get a compile error, than to use a wrong value. #ifndef RLIM_INFINITY #define RLIM_INFINITY ((uint) 0xffffffff) #endif */

static uint set_max_open_files(uint max_file_limit)
{
    
  struct rlimit rlimit;
  uint old_cur;
  DBUG_ENTER("set_max_open_files");
  DBUG_PRINT("enter",("files: %u", max_file_limit));

  if (!getrlimit(RLIMIT_NOFILE,&rlimit))    // Judge if you are successful , get open file The current value of the  ulimit -n / Or this in the service LimitNOFILE
  {
    
    old_cur= (uint) rlimit.rlim_cur;    // Get RLIMIT_NOFILE Soft limit 
    DBUG_PRINT("info", ("rlim_cur: %u rlim_max: %u",
      (uint) rlimit.rlim_cur,
      (uint) rlimit.rlim_max));
    if (rlimit.rlim_cur == (rlim_t) RLIM_INFINITY)  //RLIM_INFINITY Indicates that there is no restriction on resources , If you get a value of unlimited
      rlimit.rlim_cur = max_file_limit;
    if (rlimit.rlim_cur >= max_file_limit)
      DBUG_RETURN(rlimit.rlim_cur);   /* purecov: inspected */
    rlimit.rlim_cur= rlimit.rlim_max= max_file_limit;
    if (setrlimit(RLIMIT_NOFILE, &rlimit))
      max_file_limit= old_cur;      /* Use original value */   //655350
    else
    {
    
      rlimit.rlim_cur= 0;     /* Safety if next call fails */
      (void) getrlimit(RLIMIT_NOFILE,&rlimit);  //655350
      DBUG_PRINT("info", ("rlim_cur: %u", (uint) rlimit.rlim_cur));
      if (rlimit.rlim_cur)      /* If call didn't fail */
  max_file_limit= (uint) rlimit.rlim_cur;  //655350
    }
  }
  DBUG_PRINT("exit",("max_file_limit: %u", max_file_limit));
  DBUG_RETURN(max_file_limit);
}

#else
static uint set_max_open_files(uint max_file_limit)
{
    
  /* We don't know the limit. Return best guess */
  return MY_MIN(max_file_limit, OS_FILE_LIMIT);
}

3.max_connection

void adjust_max_connections(ulong requested_open_files)
{
    
ulong limit;

limit= requested_open_files - 10 - TABLE_OPEN_CACHE_MIN * 2;

if (limit < max_connections)
{
    
sql_print_warning("Changed limits: max_connections: %lu (requested %lu)",
limit, max_connections);

// This can be done unprotected since it is only called on startup.
max_connections= limit;
}
}

4.table_open_cache

void adjust_table_cache_size(ulong requested_open_files)
{
    
ulong limit;

limit= max<ulong>((requested_open_files - 10 - max_connections) / 2,
TABLE_OPEN_CACHE_MIN);

if (limit < table_cache_size)
{
    
sql_print_warning("Changed limits: table_open_cache: %lu (requested %lu)",
limit, table_cache_size);

table_cache_size= limit;
}

table_cache_size_per_instance= table_cache_size / table_cache_instances;
}

5.table_definition_cache

void adjust_table_def_size()
{
    
ulong default_value;
sys_var *var;

default_value= min<ulong> (400 + table_cache_size / 2, 2000);
var= intern_find_sys_var(STRING_WITH_LEN("table_definition_cache"));
DBUG_ASSERT(var != NULL);
var->update_default(default_value);

if (! table_definition_cache_specified)
table_def_size= default_value;
}

Four . Value

1.open_files_limit

limit_1= 10 + max_connections + table_cache_size * 2;
limit_2= max_connections * 5;
limit_3= open_files_limit ? open_files_limit : 5000;
request_open_files= max(max(limit_1, limit_2), limit_3);

2.max_connections

min(requested_open_files - 10 - TABLE_OPEN_CACHE_MIN * 2,max_connections)

3.table_open_cache

min(max((requested_open_files - 10 - max_connections) / 2, TABLE_OPEN_CACHE_MIN),table_cache_size)

4.table_definition_cache

Values in the configuration file take precedence

min (400 + table_cache_size / 2, 2000)

So when we really have a problem , We should start with max_connections Go get started . Then adjust other parameters .

原网站

版权声明
本文为[Fish is not fish]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202270547441898.html