Commit 3fa2673f authored by Sergey Glukhov's avatar Sergey Glukhov
Browse files

Bug#39955 SELECT on INFORMATION_SCHEMA.GLOBAL_VARIABLES takes too long

VARIABLE_VALUE field is decreased to 1024 symbols.
(affected I_S tables: GLOBAL_VARIABLES, SESSION_VARIABLES,
 GLOBAL_STATUS, SESSION_STATUS).
The only variable which can be longer than 1024 is
init_connect. The variable will be truncated with warning.
Additional fix:
Added where condition filter which speed up queries which
have where condition with expressions which use VARIABLE_NAME
field.
parent 45deeca2
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -1651,4 +1651,51 @@ id select_type table type possible_keys key key_len ref rows Extra
explain select count(*) from information_schema.views;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	views	ALL	NULL	NULL	NULL	NULL	NULL	Open_frm_only; Scanned all databases
set global init_connect="drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;";
select * from information_schema.global_variables where variable_name='init_connect';
VARIABLE_NAME	VARIABLE_VALUE
INIT_CONNECT	drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists t1;
drop table if exists t1;drop table if exists
Warnings:
Warning	1265	Data truncated for column 'VARIABLE_VALUE' at row 1
set global init_connect="";
End of 5.1 tests.
+3 −3
Original line number Diff line number Diff line
@@ -100,19 +100,19 @@ drop table t1;
show variables like "wait_timeout%";
Catalog	Database	Table	Table_alias	Column	Column_alias	Type	Length	Max length	Is_null	Flags	Decimals	Charsetnr
def			VARIABLES	VARIABLE_NAME	Variable_name	253	64	12	N	1	0	8
def			VARIABLES	VARIABLE_VALUE	Value	253	20480	5	Y	0	0	8
def			VARIABLES	VARIABLE_VALUE	Value	253	1024	5	Y	0	0	8
Variable_name	Value
wait_timeout	28800
show variables like "WAIT_timeout%";
Catalog	Database	Table	Table_alias	Column	Column_alias	Type	Length	Max length	Is_null	Flags	Decimals	Charsetnr
def			VARIABLES	VARIABLE_NAME	Variable_name	253	64	12	N	1	0	8
def			VARIABLES	VARIABLE_VALUE	Value	253	20480	5	Y	0	0	8
def			VARIABLES	VARIABLE_VALUE	Value	253	1024	5	Y	0	0	8
Variable_name	Value
wait_timeout	28800
show variables like "this_doesn't_exists%";
Catalog	Database	Table	Table_alias	Column	Column_alias	Type	Length	Max length	Is_null	Flags	Decimals	Charsetnr
def			VARIABLES	VARIABLE_NAME	Variable_name	253	64	0	N	1	0	8
def			VARIABLES	VARIABLE_VALUE	Value	253	20480	0	Y	0	0	8
def			VARIABLES	VARIABLE_VALUE	Value	253	1024	0	Y	0	0	8
Variable_name	Value
show table status from test like "this_doesn't_exists%";
Catalog	Database	Table	Table_alias	Column	Column_alias	Type	Length	Max length	Is_null	Flags	Decimals	Charsetnr
+8 −8
Original line number Diff line number Diff line
@@ -110,9 +110,9 @@ NULL information_schema FILES UPDATE_COUNT 13 NULL YES bigint NULL NULL 19 0 NUL
NULL	information_schema	FILES	UPDATE_TIME	34	NULL	YES	datetime	NULL	NULL	NULL	NULL	NULL	NULL	datetime			select	
NULL	information_schema	FILES	VERSION	25	NULL	YES	bigint	NULL	NULL	19	0	NULL	NULL	bigint(21) unsigned			select	
NULL	information_schema	GLOBAL_STATUS	VARIABLE_NAME	1		NO	varchar	64	192	NULL	NULL	utf8	utf8_general_ci	varchar(64)			select	
NULL	information_schema	GLOBAL_STATUS	VARIABLE_VALUE	2	NULL	YES	varchar	20480	61440	NULL	NULL	utf8	utf8_general_ci	varchar(20480)			select	
NULL	information_schema	GLOBAL_STATUS	VARIABLE_VALUE	2	NULL	YES	varchar	1024	3072	NULL	NULL	utf8	utf8_general_ci	varchar(1024)			select	
NULL	information_schema	GLOBAL_VARIABLES	VARIABLE_NAME	1		NO	varchar	64	192	NULL	NULL	utf8	utf8_general_ci	varchar(64)			select	
NULL	information_schema	GLOBAL_VARIABLES	VARIABLE_VALUE	2	NULL	YES	varchar	20480	61440	NULL	NULL	utf8	utf8_general_ci	varchar(20480)			select	
NULL	information_schema	GLOBAL_VARIABLES	VARIABLE_VALUE	2	NULL	YES	varchar	1024	3072	NULL	NULL	utf8	utf8_general_ci	varchar(1024)			select	
NULL	information_schema	KEY_COLUMN_USAGE	COLUMN_NAME	7		NO	varchar	64	192	NULL	NULL	utf8	utf8_general_ci	varchar(64)			select	
NULL	information_schema	KEY_COLUMN_USAGE	CONSTRAINT_CATALOG	1	NULL	YES	varchar	512	1536	NULL	NULL	utf8	utf8_general_ci	varchar(512)			select	
NULL	information_schema	KEY_COLUMN_USAGE	CONSTRAINT_NAME	3		NO	varchar	64	192	NULL	NULL	utf8	utf8_general_ci	varchar(64)			select	
@@ -213,9 +213,9 @@ NULL information_schema SCHEMA_PRIVILEGES PRIVILEGE_TYPE 4 NO varchar 64 192 NU
NULL	information_schema	SCHEMA_PRIVILEGES	TABLE_CATALOG	2	NULL	YES	varchar	512	1536	NULL	NULL	utf8	utf8_general_ci	varchar(512)			select	
NULL	information_schema	SCHEMA_PRIVILEGES	TABLE_SCHEMA	3		NO	varchar	64	192	NULL	NULL	utf8	utf8_general_ci	varchar(64)			select	
NULL	information_schema	SESSION_STATUS	VARIABLE_NAME	1		NO	varchar	64	192	NULL	NULL	utf8	utf8_general_ci	varchar(64)			select	
NULL	information_schema	SESSION_STATUS	VARIABLE_VALUE	2	NULL	YES	varchar	20480	61440	NULL	NULL	utf8	utf8_general_ci	varchar(20480)			select	
NULL	information_schema	SESSION_STATUS	VARIABLE_VALUE	2	NULL	YES	varchar	1024	3072	NULL	NULL	utf8	utf8_general_ci	varchar(1024)			select	
NULL	information_schema	SESSION_VARIABLES	VARIABLE_NAME	1		NO	varchar	64	192	NULL	NULL	utf8	utf8_general_ci	varchar(64)			select	
NULL	information_schema	SESSION_VARIABLES	VARIABLE_VALUE	2	NULL	YES	varchar	20480	61440	NULL	NULL	utf8	utf8_general_ci	varchar(20480)			select	
NULL	information_schema	SESSION_VARIABLES	VARIABLE_VALUE	2	NULL	YES	varchar	1024	3072	NULL	NULL	utf8	utf8_general_ci	varchar(1024)			select	
NULL	information_schema	STATISTICS	CARDINALITY	10	NULL	YES	bigint	NULL	NULL	19	0	NULL	NULL	bigint(21)			select	
NULL	information_schema	STATISTICS	COLLATION	9	NULL	YES	varchar	1	3	NULL	NULL	utf8	utf8_general_ci	varchar(1)			select	
NULL	information_schema	STATISTICS	COLUMN_NAME	8		NO	varchar	64	192	NULL	NULL	utf8	utf8_general_ci	varchar(64)			select	
@@ -464,9 +464,9 @@ NULL information_schema FILES CHECKSUM bigint NULL NULL NULL NULL bigint(21) uns
3.0000	information_schema	FILES	STATUS	varchar	20	60	utf8	utf8_general_ci	varchar(20)
3.0000	information_schema	FILES	EXTRA	varchar	255	765	utf8	utf8_general_ci	varchar(255)
3.0000	information_schema	GLOBAL_STATUS	VARIABLE_NAME	varchar	64	192	utf8	utf8_general_ci	varchar(64)
3.0000	information_schema	GLOBAL_STATUS	VARIABLE_VALUE	varchar	20480	61440	utf8	utf8_general_ci	varchar(20480)
3.0000	information_schema	GLOBAL_STATUS	VARIABLE_VALUE	varchar	1024	3072	utf8	utf8_general_ci	varchar(1024)
3.0000	information_schema	GLOBAL_VARIABLES	VARIABLE_NAME	varchar	64	192	utf8	utf8_general_ci	varchar(64)
3.0000	information_schema	GLOBAL_VARIABLES	VARIABLE_VALUE	varchar	20480	61440	utf8	utf8_general_ci	varchar(20480)
3.0000	information_schema	GLOBAL_VARIABLES	VARIABLE_VALUE	varchar	1024	3072	utf8	utf8_general_ci	varchar(1024)
3.0000	information_schema	KEY_COLUMN_USAGE	CONSTRAINT_CATALOG	varchar	512	1536	utf8	utf8_general_ci	varchar(512)
3.0000	information_schema	KEY_COLUMN_USAGE	CONSTRAINT_SCHEMA	varchar	64	192	utf8	utf8_general_ci	varchar(64)
3.0000	information_schema	KEY_COLUMN_USAGE	CONSTRAINT_NAME	varchar	64	192	utf8	utf8_general_ci	varchar(64)
@@ -567,9 +567,9 @@ NULL information_schema ROUTINES LAST_ALTERED datetime NULL NULL NULL NULL datet
3.0000	information_schema	SCHEMA_PRIVILEGES	PRIVILEGE_TYPE	varchar	64	192	utf8	utf8_general_ci	varchar(64)
3.0000	information_schema	SCHEMA_PRIVILEGES	IS_GRANTABLE	varchar	3	9	utf8	utf8_general_ci	varchar(3)
3.0000	information_schema	SESSION_STATUS	VARIABLE_NAME	varchar	64	192	utf8	utf8_general_ci	varchar(64)
3.0000	information_schema	SESSION_STATUS	VARIABLE_VALUE	varchar	20480	61440	utf8	utf8_general_ci	varchar(20480)
3.0000	information_schema	SESSION_STATUS	VARIABLE_VALUE	varchar	1024	3072	utf8	utf8_general_ci	varchar(1024)
3.0000	information_schema	SESSION_VARIABLES	VARIABLE_NAME	varchar	64	192	utf8	utf8_general_ci	varchar(64)
3.0000	information_schema	SESSION_VARIABLES	VARIABLE_VALUE	varchar	20480	61440	utf8	utf8_general_ci	varchar(20480)
3.0000	information_schema	SESSION_VARIABLES	VARIABLE_VALUE	varchar	1024	3072	utf8	utf8_general_ci	varchar(1024)
3.0000	information_schema	STATISTICS	TABLE_CATALOG	varchar	512	1536	utf8	utf8_general_ci	varchar(512)
3.0000	information_schema	STATISTICS	TABLE_SCHEMA	varchar	64	192	utf8	utf8_general_ci	varchar(64)
3.0000	information_schema	STATISTICS	TABLE_NAME	varchar	64	192	utf8	utf8_general_ci	varchar(64)
+27 −0
Original line number Diff line number Diff line
@@ -1346,4 +1346,31 @@ explain select count(*) from information_schema.tables;
explain select count(*) from information_schema.columns;
explain select count(*) from information_schema.views;

#
# Bug#39955 SELECT on INFORMATION_SCHEMA.GLOBAL_VARIABLES takes too long
#
set global init_connect="drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;\
drop table if exists t1;drop table if exists t1;";
select * from information_schema.global_variables where variable_name='init_connect';
set global init_connect="";

--echo End of 5.1 tests.
+31 −18
Original line number Diff line number Diff line
@@ -83,6 +83,7 @@ static void store_key_options(THD *thd, String *packet, TABLE *table,
static void
append_algorithm(TABLE_LIST *table, String *buff);

static COND * make_cond_for_info_schema(COND *cond, TABLE_LIST *table);

/***************************************************************************
** List all table types supported
@@ -2072,7 +2073,8 @@ static bool show_status_array(THD *thd, const char *wild,
                              enum enum_var_type value_type,
                              struct system_status_var *status_var,
                              const char *prefix, TABLE *table,
                              bool ucase_names)
                              bool ucase_names,
                              COND *cond)
{
  MY_ALIGNED_BYTE_ARRAY(buff_data, SHOW_VAR_FUNC_BUFF_SIZE, long);
  char * const buff= (char *) &buff_data;
@@ -2082,8 +2084,12 @@ static bool show_status_array(THD *thd, const char *wild,
  int len;
  LEX_STRING null_lex_str;
  SHOW_VAR tmp, *var;
  COND *partial_cond= 0;
  enum_check_fields save_count_cuted_fields= thd->count_cuted_fields;
  bool res= FALSE;
  DBUG_ENTER("show_status_array");

  thd->count_cuted_fields= CHECK_FIELD_WARN;  
  null_lex_str.str= 0;				// For sys_var->value_ptr()
  null_lex_str.length= 0;

@@ -2091,6 +2097,7 @@ static bool show_status_array(THD *thd, const char *wild,
  if (*prefix)
    *prefix_end++= '_';
  len=name_buffer + sizeof(name_buffer) - prefix_end;
  partial_cond= make_cond_for_info_schema(cond, table->pos_in_table_list);

  for (; variables->name; variables++)
  {
@@ -2099,6 +2106,9 @@ static bool show_status_array(THD *thd, const char *wild,
    if (ucase_names)
      make_upper(name_buffer);

    restore_record(table, s->default_values);
    table->field[0]->store(name_buffer, strlen(name_buffer),
                           system_charset_info);
    /*
      if var->type is SHOW_FUNC, call the function.
      Repeat as necessary, if new var is again SHOW_FUNC
@@ -2110,12 +2120,13 @@ static bool show_status_array(THD *thd, const char *wild,
    if (show_type == SHOW_ARRAY)
    {
      show_status_array(thd, wild, (SHOW_VAR *) var->value, value_type,
                        status_var, name_buffer, table, ucase_names);
                        status_var, name_buffer, table, ucase_names, partial_cond);
    }
    else
    {
      if (!(wild && wild[0] && wild_case_compare(system_charset_info,
                                                 name_buffer, wild)))
                                                 name_buffer, wild)) &&
          (!partial_cond || partial_cond->val_int()))
      {
        char *value=var->value;
        const char *pos, *end;                  // We assign a lot of const's
@@ -2202,21 +2213,23 @@ static bool show_status_array(THD *thd, const char *wild,
          DBUG_ASSERT(0);
          break;
        }
        restore_record(table, s->default_values);
        table->field[0]->store(name_buffer, strlen(name_buffer),
                               system_charset_info);
        table->field[1]->store(pos, (uint32) (end - pos), system_charset_info);
        thd->count_cuted_fields= CHECK_FIELD_IGNORE;
        table->field[1]->set_notnull();

        pthread_mutex_unlock(&LOCK_global_system_variables);

        if (schema_table_store_record(thd, table))
          DBUG_RETURN(TRUE);
        {
          res= TRUE;
          goto end;
        }
      }
    }

  DBUG_RETURN(FALSE);
  }
end:
  thd->count_cuted_fields= save_count_cuted_fields;
  DBUG_RETURN(res);
}


@@ -5244,7 +5257,7 @@ int fill_variables(THD *thd, TABLE_LIST *tables, COND *cond)

  rw_rdlock(&LOCK_system_variables_hash);
  res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars),
                         option_type, NULL, "", tables->table, upper_case_names);
                         option_type, NULL, "", tables->table, upper_case_names, cond);
  rw_unlock(&LOCK_system_variables_hash);
  DBUG_RETURN(res);
}
@@ -5287,7 +5300,7 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond)
  res= show_status_array(thd, wild,
                         (SHOW_VAR *)all_status_vars.buffer,
                         option_type, tmp1, "", tables->table,
                         upper_case_names);
                         upper_case_names, cond);
  pthread_mutex_unlock(&LOCK_status);
  DBUG_RETURN(res);
}
@@ -6456,7 +6469,7 @@ ST_FIELD_INFO variables_fields_info[]=
{
  {"VARIABLE_NAME", 64, MYSQL_TYPE_STRING, 0, 0, "Variable_name",
   SKIP_OPEN_TABLE},
  {"VARIABLE_VALUE", 20480, MYSQL_TYPE_STRING, 0, 1, "Value", SKIP_OPEN_TABLE},
  {"VARIABLE_VALUE", 1024, MYSQL_TYPE_STRING, 0, 1, "Value", SKIP_OPEN_TABLE},
  {0, 0, MYSQL_TYPE_STRING, 0, 0, 0, SKIP_OPEN_TABLE}
};

@@ -6615,9 +6628,9 @@ ST_SCHEMA_TABLE schema_tables[]=
  {"FILES", files_fields_info, create_schema_table,
   fill_schema_files, 0, 0, -1, -1, 0, 0},
  {"GLOBAL_STATUS", variables_fields_info, create_schema_table,
   fill_status, make_old_format, 0, -1, -1, 0, 0},
   fill_status, make_old_format, 0, 0, -1, 0, 0},
  {"GLOBAL_VARIABLES", variables_fields_info, create_schema_table,
   fill_variables, make_old_format, 0, -1, -1, 0, 0},
   fill_variables, make_old_format, 0, 0, -1, 0, 0},
  {"KEY_COLUMN_USAGE", key_column_usage_fields_info, create_schema_table,
   get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
   OPEN_TABLE_ONLY},
@@ -6642,14 +6655,14 @@ ST_SCHEMA_TABLE schema_tables[]=
  {"SCHEMA_PRIVILEGES", schema_privileges_fields_info, create_schema_table,
   fill_schema_schema_privileges, 0, 0, -1, -1, 0, 0},
  {"SESSION_STATUS", variables_fields_info, create_schema_table,
   fill_status, make_old_format, 0, -1, -1, 0, 0},
   fill_status, make_old_format, 0, 0, -1, 0, 0},
  {"SESSION_VARIABLES", variables_fields_info, create_schema_table,
   fill_variables, make_old_format, 0, -1, -1, 0, 0},
   fill_variables, make_old_format, 0, 0, -1, 0, 0},
  {"STATISTICS", stat_fields_info, create_schema_table, 
   get_all_tables, make_old_format, get_schema_stat_record, 1, 2, 0,
   OPEN_TABLE_ONLY|OPTIMIZE_I_S_TABLE},
  {"STATUS", variables_fields_info, create_schema_table, fill_status, 
   make_old_format, 0, -1, -1, 1, 0},
   make_old_format, 0, 0, -1, 1, 0},
  {"TABLES", tables_fields_info, create_schema_table, 
   get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0,
   OPTIMIZE_I_S_TABLE},
@@ -6665,7 +6678,7 @@ ST_SCHEMA_TABLE schema_tables[]=
  {"USER_PRIVILEGES", user_privileges_fields_info, create_schema_table, 
   fill_schema_user_privileges, 0, 0, -1, -1, 0, 0},
  {"VARIABLES", variables_fields_info, create_schema_table, fill_variables,
   make_old_format, 0, -1, -1, 1, 0},
   make_old_format, 0, 0, -1, 1, 0},
  {"VIEWS", view_fields_info, create_schema_table, 
   get_all_tables, 0, get_schema_views_record, 1, 2, 0,
   OPEN_VIEW_ONLY|OPTIMIZE_I_S_TABLE},