1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-24 11:21:21 +03:00

Prevent bugs by making DBUG_* expressions syntactically equivalent

to a single statement.
---
Bug#24795: SHOW PROFILE

Profiling is only partially functional on some architectures.  Where 
there is no getrusage() system call, presently Null values are 
returned where it would be required.  Notably, Windows needs some love 
applied to make it as useful.

  Syntax this adds:
  
  SHOW PROFILES
  
  SHOW PROFILE [types] [FOR QUERY n] [OFFSET n] [LIMIT n]
   where "n" is an integer
   and "types" is zero or many (comma-separated) of
      "CPU"
      "MEMORY" (not presently supported)
      "BLOCK IO"
      "CONTEXT SWITCHES"
      "PAGE FAULTS"
      "IPC"
      "SWAPS"
      "SOURCE"
      "ALL"

It also adds a session variable (boolean) "profiling", set to "no"
by default, and (integer) profiling_history_size, set to 15 by 
default.

This patch abstracts setting THDs' "proc_info" behind a macro that 
can be used as a hook into the profiling code when profiling 
support is compiled in.  All future code in this line should use
that mechanism for setting thd->proc_info.

---

Tests are now set to omit the statistics.

---

Adds an Information_schema table, "profiling" for access to 
"show profile" data.
---
Merge zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community-3--bug24795
into  zippy.cornsilk.net:/home/cmiller/work/mysql/mysql-5.0-community
---
Fix merge problems.
---
Fixed one bug in the query_source being NULL.  

Updated test results.
---
Include more thorough profiling tests.

Improve support for prepared statements.

Use session-specific query IDs, starting at zero.
---
Selecting from I_S.profiling is no longer quashed in profiling, as
requested by Giuseppe.

Limit the size of captured query text.

No longer log queries that are zero length.


BitKeeper/deleted/.del-profile.result:
  Rename: mysql-test/r/profile.result -> BitKeeper/deleted/.del-profile.result
BitKeeper/deleted/.del-profile.test:
  Rename: mysql-test/t/profile.test -> BitKeeper/deleted/.del-profile.test
BitKeeper/deleted/.del-sql_profile.cc:
  Rename: sql/sql_profile.cc -> BitKeeper/deleted/.del-sql_profile.cc
BitKeeper/deleted/.del-sql_profile.h:
  Rename: sql/sql_profile.h -> BitKeeper/deleted/.del-sql_profile.h
configure.in:
  Add a configure-time option to enable/disable query profiling.  The
  default is enabled.
include/my_dbug.h:
  
  
  DBUG_* statements should be syntactically equivalent to a single 
  statement.
myisam/mi_open.c:
  DBUG_* statements should be syntactically equivalent to a single 
  statement.
mysql-test/r/information_schema.result:
  Updated (re-recorded) tests that I missed somehow.  I verified these
  for correctness.
mysql-test/r/information_schema_db.result:
  Updated test results I missed.
mysql-test/r/mysqlshow.result:
  Fix merge problems.
ndb/src/ndbapi/DictCache.cpp:
  DBUG_* statements should be syntactically equivalent to a single 
  statement.
sql/ha_archive.cc:
  Abstract setting thread-info into a function or macro.
  ---
  Manual merge, undoing first patch.
sql/ha_berkeley.cc:
  Include patch backported to 5.0-global.
  
  THD::options is a ulonglong, not ulong.
sql/ha_myisam.cc:
  Abstract setting thread-info into a function or macro.
  ---
  Manual merge, undoing first patch.
sql/ha_myisammrg.cc:
  DBUG_* statements should be syntactically equivalent to a single 
  statement.
sql/ha_ndbcluster.cc:
  DBUG_* statements should be syntactically equivalent to a single 
  statement.
sql/item_cmpfunc.cc:
  DBUG_* statements should be syntactically equivalent to a single 
  statement.
sql/item_func.cc:
  Abstract setting thread-info into a function or macro.
  ---
  Manual merge, undoing first patch.
sql/lock.cc:
  Abstract setting thread-info into a function or macro.
  ---
  Manual merge, undoing first patch.
sql/log_event.cc:
  Abstract setting thread-info into a function or macro.
  ---
  Manual merge, undoing first patch.
sql/mysql_priv.h:
  Use 64-bit constants for the 64-bit bit field.
  
  Add a new option bit for whether profiling is active or not.
sql/mysqld.cc:
  Add semicolon to DBUG statement.
  
  Add a new system variable and set it.
  ---
  Set the minimum, which is zero and not 50.
sql/repl_failsafe.cc:
  Abstract setting thread-info into a function or macro.
  ---
  Manual merge, undoing first patch.
sql/set_var.cc:
  Make a new system global variable and session variable, to determine
  behavior of profiling.	
  ---
  Include patch backported to 5.0-global.
  
  THD::options is a ulonglong, not ulong.
sql/set_var.h:
  The THD::options bit field is ulonglong, not ulong.
sql/slave.cc:
  Abstract setting thread-info into a function or macro.
  ---
  Manual merge, undoing first patch.
  ---
  Include patch backported to 5.0-global.
  
  THD::options is a ulonglong, not ulong.
sql/sp_head.cc:
  Abstract setting thread-info into a function or macro.
  ---
  Manual merge, undoing first patch.
sql/sql_base.cc:
  Abstract setting thread-info into a function or macro.
  ---
  Manual merge, undoing first patch.
  ---
  Include patch backported to 5.0-global.
  
  THD::options is a ulonglong, not ulong.
sql/sql_cache.cc:
  DBUG_* statements should be syntactically equivalent to a single 
  statement.
  ---
  Fix merge problems.
sql/sql_class.cc:
  Insert a pointer to the current thread in the profiling code.
  ---
  Manual merge, undoing first patch.
  ---
  Fix merge problems.
sql/sql_class.h:
  Create a new system variable, profiling_history_size, and add a 
  member to THD to hold profiling information about this thread's 
  execution.
  ---
  Manual merge, undoing first patch.
sql/sql_delete.cc:
  Abstract setting thread-info into a function or macro.
  ---
  Manual merge, undoing first patch.
  ---
  Include patch backported to 5.0-global.
  
  THD::options is a ulonglong, not ulong.
sql/sql_insert.cc:
  Abstract setting thread-info into a function or macro.
  ---
  Manual merge, undoing first patch.
  ---
  Fix merge problems.
sql/sql_lex.cc:
  Initialize profiling options to empty.
  ---
  Manual merge, undoing first patch.
sql/sql_lex.h:
  Add info to the lexer object so that we can hold data that comes from
  parsing statements.
  
  Reuse memory addresses of uints that can't occur in the same state-
  ment.
  
  This is dangerous because it involves knowledge of what symbols are 
  never used together, which is information stored obliquely in another
  file.
  ---
  Manual merge, undoing first patch.
sql/sql_parse.cc:
  Add hooks to the parser to jump to profiling code.
  
  If profiling is not present, then return an error message upon being
  used.
  ---
  Manual merge, undoing first patch.
  ---
  Fix merge problems.
  ---
  Include patch backported to 5.0-global.
  
  THD::options is a ulonglong, not ulong.
sql/sql_prepare.cc:
  From prepared statement execution, set the query source in the 
  profiler, as we can't get it from  thd .
  ---
  Make it less expensive to limit the size of the queries.
sql/sql_repl.cc:
  Abstract setting thread-info into a function or macro.
  ---
  Manual merge, undoing first patch.
sql/sql_select.cc:
  Abstract setting thread-info into a function or macro.
  ---
  Manual merge, undoing first patch.
  ---
  Fix merge problems.
sql/sql_show.cc:
  Abstract setting thread-info into a function or macro.
  
  Also, remove "static" qualification on schema_table_store_record()
  so that external functions may use it.
  ---
  Manual merge, undoing first patch.
sql/sql_table.cc:
  Abstract setting thread-info into a function or macro.
  ---
  Manual merge, undoing first patch.
sql/sql_update.cc:
  Abstract setting thread-info into a function or macro.
  ---
  Manual merge, undoing first patch.
sql/sql_view.cc:
  Abstract setting thread-info into a function or macro.
  ---
  Manual merge, undoing first patch.
sql/sql_yacc.yy:
  Add new lexer symbols and insert new grammatical rules necessary to 
  retreive profiling information.
  ---
  Manual merge, undoing first patch.
  ---
  Fix merge problems.
sql/table.h:
  Add enum item for query profiling.
BitKeeper/deleted/.del-profiling-master.opt:
  New BitKeeper file ``mysql-test/t/profiling-master.opt''
mysql-test/r/profiling.result:
  New BitKeeper file ``mysql-test/r/profiling.result''
  ---
  Include more verbose that describes the queries so far.
  
  Include Giuseppe's tests.
  ---
  Selecting from I_S.profiling is no longer quashed in profiling, as
  requested by Giuseppe.
mysql-test/t/profiling.test:
  New BitKeeper file ``mysql-test/t/profiling.test''
  ---
  Include more verbose that describes the queries so far.
  
  Include Giuseppe's tests.
  ---
  Selecting from I_S.profiling is no longer quashed in profiling, as
  requested by Giuseppe.
sql/sql_profile.cc:
  New BitKeeper file ``sql/sql_profile.cc''
  ---
  If query_source is NULL, as can sometimes happen, then don't try
  to copy that memory.
  ---
  Make each new session use its own numbering of query_ids, and not
  show the global-pool numbers to the user.
  
  Provide a way for prepared statements to set the query_source.
  ---
  Selecting from I_S.profiling is no longer quashed in profiling, as
  requested by Giuseppe.
  
  Limit the size of captured query text.
  
  No longer log queries that are zero length.
sql/sql_profile.h:
  New BitKeeper file ``sql/sql_profile.h''
  ---
  Make each new session use its own numbering of query_ids, and not
  show the global-pool numbers to the user.
  
  Provide a way for prepared statements to set the query_source.
  ---
  Make it less expensive to limit the size of the queries.
This commit is contained in:
unknown
2007-02-22 10:03:08 -05:00
parent 98d31c694d
commit 607c224969
48 changed files with 1602 additions and 574 deletions

View File

@@ -140,14 +140,14 @@ static bool end_active_trans(THD *thd)
if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
OPTION_TABLE_LOCK))
{
DBUG_PRINT("info",("options: 0x%lx", (ulong) thd->options));
DBUG_PRINT("info",("options: 0x%llx", thd->options));
/* Safety if one did "drop table" on locked tables */
if (!thd->locked_tables)
thd->options&= ~OPTION_TABLE_LOCK;
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (ha_commit(thd))
error=1;
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->options&= ~(OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
}
DBUG_RETURN(error);
}
@@ -171,7 +171,7 @@ static bool begin_trans(THD *thd)
else
{
LEX *lex= thd->lex;
thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
thd->options= ((thd->options & ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
OPTION_BEGIN);
thd->server_status|= SERVER_STATUS_IN_TRANS;
if (lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
@@ -1058,7 +1058,7 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var,
Vio* save_vio;
ulong save_client_capabilities;
THD_PROC_INFO(thd, "Execution of init_command");
thd_proc_info(thd, "Execution of init_command");
/*
We need to lock init_command_var because
during execution of init_command_var query
@@ -1158,7 +1158,7 @@ pthread_handler_t handle_one_connection(void *arg)
net->compress=1; // Use compression
thd->version= refresh_version;
THD_PROC_INFO(thd, 0);
thd_proc_info(thd, 0);
thd->command= COM_SLEEP;
thd->set_time();
thd->init_for_queries();
@@ -1175,7 +1175,7 @@ pthread_handler_t handle_one_connection(void *arg)
sctx->host_or_ip, "init_connect command failed");
sql_print_warning("%s", net->last_error);
}
THD_PROC_INFO(thd, 0);
thd_proc_info(thd, 0);
thd->set_time();
thd->init_for_queries();
}
@@ -1258,7 +1258,7 @@ pthread_handler_t handle_bootstrap(void *arg)
if (thd->variables.max_join_size == HA_POS_ERROR)
thd->options |= OPTION_BIG_SELECTS;
THD_PROC_INFO(thd, 0);
thd_proc_info(thd, 0);
thd->version=refresh_version;
thd->security_ctx->priv_user=
thd->security_ctx->user= (char*) my_strdup("boot", MYF(MY_WME));
@@ -1447,7 +1447,7 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
*/
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
res= ha_commit(thd);
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->options&= ~(OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
break;
case COMMIT_RELEASE:
do_release= 1; /* fall through */
@@ -1464,7 +1464,7 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
if (ha_rollback(thd))
res= -1;
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->options&= ~(OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
if (!res && (completion == ROLLBACK_AND_CHAIN))
res= begin_trans(thd);
break;
@@ -2105,7 +2105,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
if (thd->lock || thd->open_tables || thd->derived_tables ||
thd->prelocked_mode)
{
THD_PROC_INFO(thd, "closing tables");
thd_proc_info(thd, "closing tables");
close_thread_tables(thd); /* Free tables */
}
/*
@@ -2128,9 +2128,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
log_slow_statement(thd);
THD_PROC_INFO(thd, "cleaning up");
thd_proc_info(thd, "cleaning up");
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list
THD_PROC_INFO(thd, 0);
thd_proc_info(thd, 0);
thd->command=COM_SLEEP;
thd->query=0;
thd->query_length=0;
@@ -2163,6 +2163,8 @@ void log_slow_statement(THD *thd)
*/
if (thd->enable_slow_log && !thd->user_time)
{
thd_proc_info(thd, "logging slow query");
if ((ulong) (thd->start_time - thd->time_after_lock) >
thd->variables.long_query_time ||
(thd->server_status &
@@ -2171,7 +2173,7 @@ void log_slow_statement(THD *thd)
/* == SQLCOM_END unless this is a SHOW command */
thd->lex->orig_sql_command == SQLCOM_END)
{
THD_PROC_INFO(thd, "logging slow query");
thd_proc_info(thd, "logging slow query");
thd->status_var.long_query_count++;
mysql_slow_log.write(thd, thd->query, thd->query_length, start_of_query);
}
@@ -2698,16 +2700,33 @@ mysql_execute_command(THD *thd)
}
case SQLCOM_SHOW_PROFILES:
{
#ifdef ENABLED_PROFILING
thd->profiling.store();
thd->profiling.discard();
res= thd->profiling.show_profiles();
if (res)
goto error;
#else
my_error(ER_FEATURE_DISABLED, MYF(0), "query profiling", "enable-profiling");
goto error;
#endif
break;
}
case SQLCOM_SHOW_PROFILE:
{
#ifdef ENABLED_PROFILING
thd->profiling.store();
thd->profiling.discard(); // will get re-enabled by reset()
res= thd->profiling.show_last(lex->profile_options);
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), "query profiling", "enable-profiling");
goto error;
#endif
break;
}
case SQLCOM_SHOW_NEW_MASTER:
@@ -3557,7 +3576,7 @@ end_with_restore_list:
if (add_item_to_list(thd, new Item_null()))
goto error;
THD_PROC_INFO(thd, "init");
thd_proc_info(thd, "init");
if ((res= open_and_lock_tables(thd, all_tables)))
break;
@@ -3721,7 +3740,7 @@ end_with_restore_list:
if (thd->options & OPTION_TABLE_LOCK)
{
end_active_trans(thd);
thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
thd->options&= ~(OPTION_TABLE_LOCK);
}
if (thd->global_read_lock)
unlock_global_read_lock(thd);
@@ -3747,7 +3766,7 @@ end_with_restore_list:
send_ok(thd);
}
else
thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
thd->options&= ~(OPTION_TABLE_LOCK);
thd->in_lock_tables=0;
break;
case SQLCOM_CREATE_DB:
@@ -4847,7 +4866,7 @@ create_sp_error:
thd->transaction.xid_state.xa_state=XA_ACTIVE;
thd->transaction.xid_state.xid.set(thd->lex->xid);
xid_cache_insert(&thd->transaction.xid_state);
thd->options= ((thd->options & (ulong) ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
thd->options= ((thd->options & ~(OPTION_STATUS_NO_TRANS_UPDATE)) |
OPTION_BEGIN);
thd->server_status|= SERVER_STATUS_IN_TRANS;
send_ok(thd);
@@ -4941,7 +4960,7 @@ create_sp_error:
xa_state_names[thd->transaction.xid_state.xa_state]);
break;
}
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->options&= ~(OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
xid_cache_delete(&thd->transaction.xid_state);
thd->transaction.xid_state.xa_state=XA_NOTR;
@@ -4971,7 +4990,7 @@ create_sp_error:
my_error(ER_XAER_RMERR, MYF(0));
else
send_ok(thd);
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->options&= ~(OPTION_BEGIN | OPTION_STATUS_NO_TRANS_UPDATE);
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
xid_cache_delete(&thd->transaction.xid_state);
thd->transaction.xid_state.xa_state=XA_NOTR;
@@ -4986,7 +5005,7 @@ create_sp_error:
send_ok(thd);
break;
}
THD_PROC_INFO(thd, "query end");
thd_proc_info(thd, "query end");
/* Two binlog-related cleanups: */
/*
@@ -5157,8 +5176,7 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
else
save_priv= &dummy;
THD_PROC_INFO(thd, "checking permissions");
thd_proc_info(thd, "checking permissions");
if ((!db || !db[0]) && !thd->db && !dont_check_global_grants)
{
DBUG_PRINT("error",("No database"));
@@ -5605,6 +5623,9 @@ mysql_init_query(THD *thd, uchar *buf, uint length)
DBUG_ENTER("mysql_init_query");
lex_start(thd, buf, length);
mysql_reset_thd_for_next_command(thd);
#ifdef ENABLED_PROFILING
thd->profiling.reset();
#endif
DBUG_VOID_RETURN;
}
@@ -5646,7 +5667,9 @@ void mysql_reset_thd_for_next_command(THD *thd)
thd->total_warn_count=0; // Warnings for this query
thd->rand_used= 0;
thd->sent_row_count= thd->examined_row_count= 0;
#ifdef ENABLED_PROFILING
thd->profiling.reset();
#endif
}
DBUG_VOID_RETURN;
}
@@ -5870,7 +5893,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
query_cache_abort(&thd->net);
lex->unit.cleanup();
}
THD_PROC_INFO(thd, "freeing items");
thd_proc_info(thd, "freeing items");
thd->end_statement();
thd->cleanup_after_query();
DBUG_ASSERT(thd->change_list.is_empty());