summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/information_schema.result7
-rw-r--r--mysql-test/r/profiling.result4
-rw-r--r--mysql-test/t/profiling.test5
-rw-r--r--sql/sql_parse.cc26
-rw-r--r--sql/sql_profile.cc347
-rw-r--r--sql/sql_profile.h7
-rw-r--r--sql/sql_show.cc1
-rw-r--r--sql/sql_yacc.yy12
-rw-r--r--sql/table.h2
9 files changed, 138 insertions, 273 deletions
diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result
index 208509da9a7..bf84f0fe96f 100644
--- a/mysql-test/r/information_schema.result
+++ b/mysql-test/r/information_schema.result
@@ -1402,6 +1402,13 @@ TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1
TRIGGERS information_schema.TRIGGERS 1
USER_PRIVILEGES information_schema.USER_PRIVILEGES 1
VIEWS information_schema.VIEWS 1
+show global status like "Uptime_%";
+Variable_name Value
+Uptime_since_flush_status #
+flush status;
+show global status like "Uptime_%";
+Variable_name Value
+Uptime_since_flush_status #
create table t1(f1 int);
create view v1 as select f1+1 as a from t1;
create table t2 (f1 int, f2 int);
diff --git a/mysql-test/r/profiling.result b/mysql-test/r/profiling.result
index 9f478d68b8d..b99870e3564 100644
--- a/mysql-test/r/profiling.result
+++ b/mysql-test/r/profiling.result
@@ -1,3 +1,7 @@
+show profiles;
+Query_ID Duration Query
+show profile all;
+Status Duration CPU_user CPU_system Context_voluntary Context_involuntary Block_ops_in Block_ops_out Messages_sent Messages_received Page_faults_major Page_faults_minor Swaps Source_function Source_file Source_line
show session variables like 'profil%';
Variable_name Value
profiling OFF
diff --git a/mysql-test/t/profiling.test b/mysql-test/t/profiling.test
index 173d7ec0c96..c86ad60e59b 100644
--- a/mysql-test/t/profiling.test
+++ b/mysql-test/t/profiling.test
@@ -1,5 +1,10 @@
--source include/have_community_features.inc
+# Verify that the protocol isn't violated if we ask for profiling info
+# before profiling has recorded anything.
+show profiles;
+show profile all;
+
# default is OFF
show session variables like 'profil%';
select @@profiling;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index c5b59e4c9a0..f6a58bf1928 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -1509,6 +1509,15 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
break;
}
#endif
+ case SCH_PROFILES:
+ /*
+ Mark this current profiling record to be discarded. We don't
+ wish to have SHOW commands show up in profiling.
+ */
+#ifdef ENABLED_PROFILING
+ thd->profiling.discard();
+#endif
+ break;
case SCH_OPEN_TABLES:
case SCH_VARIABLES:
case SCH_STATUS:
@@ -2011,23 +2020,6 @@ mysql_execute_command(THD *thd)
#endif
break;
}
- case SQLCOM_SHOW_PROFILE:
- {
-#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
- thd->profiling.store();
- thd->profiling.discard(); // will get re-enabled by reset()
- if (lex->profile_query_id != 0)
- res= thd->profiling.show(lex->profile_options, lex->profile_query_id);
- else
- res= thd->profiling.show_last(lex->profile_options);
- if (res)
- goto error;
-#else
- my_error(ER_FEATURE_DISABLED, MYF(0), "SHOW PROFILE", "enable-profiling");
- goto error;
-#endif
- break;
- }
case SQLCOM_SHOW_NEW_MASTER:
{
if (check_global_access(thd, REPL_SLAVE_ACL))
diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc
index 90b4c4768af..6083fcd744b 100644
--- a/sql/sql_profile.cc
+++ b/sql/sql_profile.cc
@@ -62,6 +62,56 @@ ST_FIELD_INFO query_profile_statistics_info[]=
{NULL, 0, MYSQL_TYPE_STRING, 0, true, NULL, NULL}
};
+
+int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table)
+{
+ int profile_options = thd->lex->profile_options;
+ int fields_include_condition_truth_values[]= {
+ FALSE, /* Query_id */
+ FALSE, /* Seq */
+ TRUE, /* Status */
+ TRUE, /* Duration */
+ profile_options & PROFILE_CPU, /* CPU_user */
+ profile_options & PROFILE_CPU, /* CPU_system */
+ profile_options & PROFILE_CONTEXT, /* Context_voluntary */
+ profile_options & PROFILE_CONTEXT, /* Context_involuntary */
+ profile_options & PROFILE_BLOCK_IO, /* Block_ops_in */
+ profile_options & PROFILE_BLOCK_IO, /* Block_ops_out */
+ profile_options & PROFILE_IPC, /* Messages_sent */
+ profile_options & PROFILE_IPC, /* Messages_received */
+ profile_options & PROFILE_PAGE_FAULTS, /* Page_faults_major */
+ profile_options & PROFILE_PAGE_FAULTS, /* Page_faults_minor */
+ profile_options & PROFILE_SWAPS, /* Swaps */
+ profile_options & PROFILE_SOURCE, /* Source_function */
+ profile_options & PROFILE_SOURCE, /* Source_file */
+ profile_options & PROFILE_SOURCE, /* Source_line */
+ };
+
+ ST_FIELD_INFO *field_info;
+ Name_resolution_context *context= &thd->lex->select_lex.context;
+ int i;
+
+ for (i= 0; schema_table->fields_info[i].field_name != NULL; i++)
+ {
+ if (! fields_include_condition_truth_values[i])
+ continue;
+
+ field_info= &schema_table->fields_info[i];
+ Item_field *field= new Item_field(context,
+ NullS, NullS, field_info->field_name);
+ if (field)
+ {
+ field->set_name(field_info->old_name,
+ strlen(field_info->old_name),
+ system_charset_info);
+ if (add_item_to_list(thd, field))
+ return 1;
+ }
+ }
+ return 0;
+}
+
+
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
#define RUSAGE_USEC(tv) ((tv).tv_sec*1000*1000 + (tv).tv_usec)
@@ -242,212 +292,6 @@ void QUERY_PROFILE::reset()
DBUG_VOID_RETURN;
}
-bool QUERY_PROFILE::show(uint options)
-{
- THD *thd= profiling->thd;
- List<Item> field_list;
- DBUG_ENTER("QUERY_PROFILE::show");
-
- field_list.push_back(new Item_empty_string("Status", MYSQL_ERRMSG_SIZE));
- field_list.push_back(new Item_return_int("Duration", TIME_FLOAT_DIGITS,
- MYSQL_TYPE_DOUBLE));
-
- if (options & PROFILE_CPU)
- {
- field_list.push_back(new Item_return_int("CPU_user", TIME_FLOAT_DIGITS,
- MYSQL_TYPE_DOUBLE));
- field_list.push_back(new Item_return_int("CPU_system", TIME_FLOAT_DIGITS,
- MYSQL_TYPE_DOUBLE));
- }
-
- if (options & PROFILE_MEMORY)
- {
- }
-
- if (options & PROFILE_CONTEXT)
- {
- field_list.push_back(new Item_return_int("Context_voluntary", 10,
- MYSQL_TYPE_LONG));
- field_list.push_back(new Item_return_int("Context_involuntary", 10,
- MYSQL_TYPE_LONG));
- }
-
- if (options & PROFILE_BLOCK_IO)
- {
- field_list.push_back(new Item_return_int("Block_ops_in", 10,
- MYSQL_TYPE_LONG));
- field_list.push_back(new Item_return_int("Block_ops_out", 10,
- MYSQL_TYPE_LONG));
- }
-
- if (options & PROFILE_IPC)
- {
- field_list.push_back(new Item_return_int("Messages_sent", 10,
- MYSQL_TYPE_LONG));
- field_list.push_back(new Item_return_int("Messages_received", 10,
- MYSQL_TYPE_LONG));
- }
-
- if (options & PROFILE_PAGE_FAULTS)
- {
- field_list.push_back(new Item_return_int("Page_faults_major", 10,
- MYSQL_TYPE_LONG));
- field_list.push_back(new Item_return_int("Page_faults_minor", 10,
- MYSQL_TYPE_LONG));
- }
-
- if (options & PROFILE_SWAPS)
- {
- field_list.push_back(new Item_return_int("Swaps", 10, MYSQL_TYPE_LONG));
- }
-
- if (options & PROFILE_SOURCE)
- {
- field_list.push_back(new Item_empty_string("Source_function",
- MYSQL_ERRMSG_SIZE));
- field_list.push_back(new Item_empty_string("Source_file",
- MYSQL_ERRMSG_SIZE));
- field_list.push_back(new Item_return_int("Source_line", 10,
- MYSQL_TYPE_LONG));
- }
-
- if (thd->protocol->send_fields(&field_list,
- Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
- DBUG_RETURN(TRUE);
-
- Protocol *protocol= thd->protocol;
- SELECT_LEX *sel= &thd->lex->select_lex;
- SELECT_LEX_UNIT *unit= &thd->lex->unit;
- ha_rows idx= 0;
- unit->set_limit(sel);
- PROFILE_ENTRY *previous= &profile_start;
-
- PROFILE_ENTRY *entry;
- void *iterator;
- for (iterator= entries.new_iterator();
- iterator != NULL;
- iterator= entries.iterator_next(iterator))
- {
- entry= entries.iterator_value(iterator);
-
-#ifdef HAVE_GETRUSAGE
- struct rusage *rusage= &(entry->rusage);
-#endif
- String elapsed;
-
- if (++idx <= unit->offset_limit_cnt)
- continue;
- if (idx > unit->select_limit_cnt)
- break;
-
- protocol->prepare_for_resend();
-
- /*
- This entry, n, has a point in time, T(n), and a status phrase, S(n). The
- status phrase S(n) describes the period of time that begins at T(n). The
- previous status phrase S(n-1) describes the period of time that starts at
- T(n-1) and ends at T(n). Since we want to describe the time that a status
- phrase took T(n)-T(n-1), this line must describe the previous status.
- */
- protocol->store(previous->status, strlen(previous->status),
- system_charset_info);
- protocol->store((double)(entry->time_usecs -
- previous->time_usecs)/(1000.0*1000),
- (uint32) TIME_FLOAT_DIGITS-1, &elapsed);
-
- if (options & PROFILE_CPU)
- {
-#ifdef HAVE_GETRUSAGE
- String cpu_utime, cpu_stime;
- protocol->store((double)(RUSAGE_DIFF_USEC(rusage->ru_utime,
- previous->rusage.ru_utime))/(1000.0*1000),
- (uint32) TIME_FLOAT_DIGITS-1, &cpu_utime);
- protocol->store((double)(RUSAGE_DIFF_USEC(rusage->ru_stime,
- previous->rusage.ru_stime))/(1000.0*1000),
- (uint32) TIME_FLOAT_DIGITS-1, &cpu_stime);
-#else
- protocol->store_null();
- protocol->store_null();
-#endif
- }
-
- if (options & PROFILE_CONTEXT)
- {
-#ifdef HAVE_GETRUSAGE
- protocol->store((uint32)(rusage->ru_nvcsw - previous->rusage.ru_nvcsw));
- protocol->store((uint32)(rusage->ru_nivcsw - previous->rusage.ru_nivcsw));
-#else
- protocol->store_null();
- protocol->store_null();
-#endif
- }
-
- if (options & PROFILE_BLOCK_IO)
- {
-#ifdef HAVE_GETRUSAGE
- protocol->store((uint32)(rusage->ru_inblock - previous->rusage.ru_inblock));
- protocol->store((uint32)(rusage->ru_oublock - previous->rusage.ru_oublock));
-#else
- protocol->store_null();
- protocol->store_null();
-#endif
- }
-
- if (options & PROFILE_IPC)
- {
-#ifdef HAVE_GETRUSAGE
- protocol->store((uint32)(rusage->ru_msgsnd - previous->rusage.ru_msgsnd));
- protocol->store((uint32)(rusage->ru_msgrcv - previous->rusage.ru_msgrcv));
-#else
- protocol->store_null();
- protocol->store_null();
-#endif
- }
-
- if (options & PROFILE_PAGE_FAULTS)
- {
-#ifdef HAVE_GETRUSAGE
- protocol->store((uint32)(rusage->ru_majflt - previous->rusage.ru_majflt));
- protocol->store((uint32)(rusage->ru_minflt - previous->rusage.ru_minflt));
-#else
- protocol->store_null();
- protocol->store_null();
-#endif
- }
-
- if (options & PROFILE_SWAPS)
- {
-#ifdef HAVE_GETRUSAGE
- protocol->store((uint32)(rusage->ru_nswap - previous->rusage.ru_nswap));
-#else
- protocol->store_null();
-#endif
- }
-
- if (options & PROFILE_SOURCE)
- {
- if ((entry->function != NULL) && (entry->file != NULL))
- {
- protocol->store(entry->function, strlen(entry->function),
- system_charset_info);
- protocol->store(entry->file, strlen(entry->file), system_charset_info);
- protocol->store((uint32) entry->line);
- } else {
- protocol->store_null();
- protocol->store_null();
- protocol->store_null();
- }
- }
-
- if (protocol->write())
- DBUG_RETURN(TRUE);
-
- previous= entry;
- }
- send_eof(thd);
- DBUG_RETURN(FALSE);
-}
-
PROFILING::PROFILING()
:profile_id_counter(1), keeping(TRUE), enabled(FALSE), current(NULL), last(NULL)
{
@@ -494,9 +338,6 @@ void PROFILING::store()
DBUG_VOID_RETURN;
}
- while (history.elements > thd->variables.profiling_history_size)
- delete history.pop();
-
if (likely(((thd)->options & OPTION_PROFILING) == 0))
DBUG_VOID_RETURN;
@@ -526,6 +367,9 @@ void PROFILING::store()
if (enabled)
current= new QUERY_PROFILE(this, thd->query, thd->query_length);
+ while (history.elements > thd->variables.profiling_history_size)
+ delete history.pop();
+
DBUG_VOID_RETURN;
}
@@ -630,38 +474,11 @@ void PROFILING::set_query_source(char *query_source_arg, uint query_length_arg)
DBUG_VOID_RETURN;
}
-bool PROFILING::show(uint options, uint profiling_query_id)
-{
- DBUG_ENTER("PROFILING::show");
- QUERY_PROFILE *prof;
-
- void *iterator;
- for (iterator= history.new_iterator();
- iterator != NULL;
- iterator= history.iterator_next(iterator))
- {
- prof= history.iterator_value(iterator);
-
- if(prof->profiling_query_id == profiling_query_id)
- DBUG_RETURN(prof->show(options));
- }
-
- my_error(ER_WRONG_ARGUMENTS, MYF(0), "SHOW PROFILE");
- DBUG_RETURN(TRUE);
-}
-
-bool PROFILING::show_last(uint options)
-{
- DBUG_ENTER("PROFILING::show_last");
- if (!history.is_empty()) {
- DBUG_RETURN(last->show(options));
- }
- DBUG_RETURN(TRUE);
-}
-
/**
Fill the information schema table, "query_profile", as defined in show.cc .
+ There are two ways to get to this function: Selecting from the information
+ schema, and a SHOW command.
*/
int PROFILING::fill_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond)
{
@@ -696,6 +513,31 @@ int PROFILING::fill_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond)
{
entry= query->entries.iterator_value(entry_iterator);
+ if (thd->lex->orig_sql_command == SQLCOM_SHOW_PROFILE)
+ {
+ /*
+ We got here via a SHOW command. That means that we stored
+ information about the query we wish to show and that isn't
+ in a WHERE clause at a higher level to filter out rows we
+ wish to exclude.
+
+ Because that functionality isn't available in the server yet,
+ we must filter here, at the wrong level. Once one can con-
+ struct where and having conditions at the SQL layer, then this
+ condition should be ripped out.
+ */
+ if (thd->lex->profile_query_id == 0) /* 0 == show final query */
+ {
+ if (query != last)
+ continue;
+ }
+ else
+ {
+ if (thd->lex->profile_query_id != query->profiling_query_id)
+ continue;
+ }
+ }
+
/* Set default values for this row. */
restore_record(table, s->default_values);
@@ -715,16 +557,31 @@ int PROFILING::fill_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond)
*/
table->field[2]->store(previous->status, strlen(previous->status),
system_charset_info);
- table->field[3]->store((double)(entry->time_usecs -
- previous->time_usecs)/(1000*1000));
+
+ my_decimal duration;
+ double2my_decimal(E_DEC_FATAL_ERROR,
+ (entry->time_usecs-previous->time_usecs)/(1000.0*1000),
+ &duration);
+ table->field[3]->store_decimal(&duration);
#ifdef HAVE_GETRUSAGE
- table->field[4]->store((double)RUSAGE_DIFF_USEC(entry->rusage.ru_utime,
- previous->rusage.ru_utime)/(1000.0*1000));
- table->field[4]->set_notnull();
- table->field[5]->store((double)RUSAGE_DIFF_USEC(entry->rusage.ru_stime,
- previous->rusage.ru_stime)/(1000.0*1000));
+ my_decimal cpu_utime, cpu_stime;
+ double2my_decimal(E_DEC_FATAL_ERROR,
+ RUSAGE_DIFF_USEC(entry->rusage.ru_utime,
+ previous->rusage.ru_utime) /
+ (1000.0*1000),
+ &cpu_utime);
+
+ double2my_decimal(E_DEC_FATAL_ERROR,
+ RUSAGE_DIFF_USEC(entry->rusage.ru_stime,
+ previous->rusage.ru_stime) /
+ (1000.0*1000),
+ &cpu_stime);
+
+ table->field[4]->store_decimal(&cpu_utime);
+ table->field[5]->store_decimal(&cpu_stime);
+ table->field[4]->set_notnull();
table->field[5]->set_notnull();
#else
/* TODO: Add CPU-usage info for non-BSD systems */
diff --git a/sql/sql_profile.h b/sql/sql_profile.h
index 7d2fbb7827d..1a6ebcd0b0e 100644
--- a/sql/sql_profile.h
+++ b/sql/sql_profile.h
@@ -39,6 +39,7 @@ extern const char * const _unknown_func_;
extern ST_FIELD_INFO query_profile_statistics_info[];
int fill_query_profile_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond);
+int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table);
#define PROFILE_NONE 0
@@ -315,12 +316,6 @@ public:
/* SHOW PROFILES */
bool show_profiles();
- /* SHOW PROFILE FOR QUERY query_id */
- bool show(uint options, uint profiling_query_id);
-
- /* SHOW PROFILE */
- bool show_last(uint options);
-
/* ... from INFORMATION_SCHEMA.PROFILING ... */
int fill_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond);
};
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index 3d7c3d68dd9..dcc65503dec 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -6507,7 +6507,6 @@ ST_SCHEMA_TABLE schema_tables[]=
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0,
OPEN_TABLE_ONLY},
{"OPEN_TABLES", open_tables_fields_info, create_schema_table,
- fill_open_tables, make_old_format, 0, -1, -1, 1, 0},
{"PARTITIONS", partitions_fields_info, create_schema_table,
get_all_tables, 0, get_schema_partitions_record, 1, 2, 0, OPEN_TABLE_ONLY},
{"PLUGINS", plugin_fields_info, create_schema_table,
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 530560228a8..b1b0136b6c3 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -8863,11 +8863,11 @@ opt_table_sym:
opt_profile_defs:
/* empty */
- | profile_defs
+ | profile_defs;
profile_defs:
profile_def
- | profile_defs ',' profile_def
+ | profile_defs ',' profile_def;
profile_def:
CPU_SYM
@@ -9092,7 +9092,13 @@ show_param:
| PROFILES_SYM
{ Lex->sql_command = SQLCOM_SHOW_PROFILES; }
| PROFILE_SYM opt_profile_defs opt_profile_args opt_limit_clause_init
- { Lex->sql_command = SQLCOM_SHOW_PROFILE; }
+ {
+ LEX *lex= Lex;
+ lex->sql_command= SQLCOM_SELECT;
+ lex->orig_sql_command= SQLCOM_SHOW_PROFILE;
+ if (prepare_schema_table(YYTHD, lex, NULL, SCH_PROFILES) != 0)
+ YYABORT;
+ }
| opt_var_type STATUS_SYM wild_and_where
{
LEX *lex= Lex;
diff --git a/sql/table.h b/sql/table.h
index 01f24e02fb6..e873fb1de58 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -697,7 +697,7 @@ enum enum_schema_tables
SCH_PARTITIONS,
SCH_PLUGINS,
SCH_PROCESSLIST,
- SCH_PROFILING,
+ SCH_PROFILES,
SCH_REFERENTIAL_CONSTRAINTS,
SCH_PROCEDURES,
SCH_SCHEMATA,