Merge bk-internal.mysql.com:/data0/bk/mysql-5.0

into  bk-internal.mysql.com:/data0/bk/mysql-5.0-community


sql/item_func.cc:
  Auto merged
sql/mysql_priv.h:
  Auto merged
sql/sp_head.cc:
  Auto merged
sql/sql_base.cc:
  Auto merged
sql/sql_class.cc:
  Auto merged
sql/sql_class.h:
  Auto merged
sql/sql_lex.cc:
  Auto merged
sql/sql_lex.h:
  Auto merged
sql/sql_parse.cc:
  Auto merged
sql/sql_select.cc:
  Auto merged
sql/sql_yacc.yy:
  Auto merged
This commit is contained in:
unknown 2007-01-14 04:09:38 +01:00
commit 384b212168
34 changed files with 982 additions and 147 deletions

View file

@ -29,3 +29,6 @@
4554a95d7txO1DuO9G3nAizI3SkFAA
4554b3722d71SbPiI2Gx-RhbZjmuIQ
4558b3d73Cxjlb7Wv1oytdSTthxDfw
459c03b9N_mqF2XJKK6DwSrIt7e6_g
459c1965_BQMBzBO8S_gVqjTHYQrmw
459c2098XoAUsUn8N07IVRDD6CTM-A

View file

@ -7,7 +7,7 @@ AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
# remember to also change ndb version below and update version.c in ndb
AM_INIT_AUTOMAKE(mysql, 5.0.34)
AM_INIT_AUTOMAKE(mysql, 5.0.35)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
@ -19,7 +19,7 @@ SHARED_LIB_VERSION=$SHARED_LIB_MAJOR_VERSION:0:0
# ndb version
NDB_VERSION_MAJOR=5
NDB_VERSION_MINOR=0
NDB_VERSION_BUILD=34
NDB_VERSION_BUILD=35
NDB_VERSION_STATUS=""
# Set all version vars based on $VERSION. How do we do this more elegant ?
@ -1089,7 +1089,6 @@ case $SYSTEM_TYPE in
fi
;;
*darwin*)
AC_DEFINE([DEFAULT_SKIP_THREAD_PRIORITY], [1], [default to skip thread priority])
if test "$ac_cv_prog_gcc" = "yes"
then
FLAGS="-D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DIGNORE_SIGHUP_SIGQUIT"
@ -2511,14 +2510,12 @@ thread_dirs=
dnl This probably should be cleaned up more - for now the threaded
dnl client is just using plain-old libs.
sql_client_dirs=
sql_client_dirs="strings regex mysys libmysql client"
linked_client_targets="linked_libmysql_sources"
if test "$THREAD_SAFE_CLIENT" = "no"
if test "$THREAD_SAFE_CLIENT" != "no"
then
sql_client_dirs="strings regex mysys extra libmysql client"
else
sql_client_dirs="strings regex mysys extra libmysql libmysql_r client"
sql_client_dirs="libmysql_r $sql_client_dirs"
linked_client_targets="$linked_client_targets linked_libmysql_r_sources"
AC_CONFIG_FILES(libmysql_r/Makefile)
AC_DEFINE([THREAD_SAFE_CLIENT], [1], [Should be client be thread safe])
@ -2547,17 +2544,13 @@ AM_CONDITIONAL(HAVE_NETWARE, test "$netware_dir" = "netware")
export CC CXX CFLAGS CXXFLAGS LD LDFLAGS AR
ac_configure_args="$ac_configure_args CFLAGS='$CFLAGS' CXXFLAGS='$CXXFLAGS'"
if test "$with_server" != "no" -o "$THREAD_SAFE_CLIENT" != "no"
if test "$with_server" = "yes" -o "$THREAD_SAFE_CLIENT" != "no"
then
AC_DEFINE([THREAD], [1],
[Define if you want to have threaded code. This may be undef on client code])
# Avoid _PROGRAMS names
THREAD_LOBJECTS="thr_alarm.o thr_lock.o thr_mutex.o thr_rwlock.o my_pthread.o my_thr_init.o mf_keycache.o"
AC_SUBST(THREAD_LOBJECTS)
fi
if test "$with_server" != "no"
then
server_scripts="mysqld_safe mysql_install_db"
sql_server_dirs="strings mysys dbug extra regex"

View file

@ -53,6 +53,7 @@ sqlsources = derror.cc field.cc field_conv.cc strfunc.cc filesort.cc \
protocol.cc net_serv.cc opt_range.cc \
opt_sum.cc procedure.cc records.cc sql_acl.cc \
sql_load.cc discover.cc sql_locale.cc \
sql_profile.cc \
sql_analyse.cc sql_base.cc sql_cache.cc sql_class.cc \
sql_crypt.cc sql_db.cc sql_delete.cc sql_error.cc sql_insert.cc \
sql_lex.cc sql_list.cc sql_manager.cc sql_map.cc sql_parse.cc \

View file

@ -0,0 +1,30 @@
create table t1 (
a int,
b int
);
insert into t1 values (1,1), (2,null), (3, 4);
insert into t1 values (5,1), (6,null), (7, 4);
insert into t1 values (1,1), (2,null), (3, 4);
insert into t1 values (5,1), (6,null), (7, 4);
insert into t1 values (5,1), (6,null), (7, 4);
select sum(a) from t1;
select sum(a) from t1 group by b;
select sum(a) + sum(b) from t1 group by b;
select max(x) from (select sum(a) as x from t1 group by b) as teeone;
show profiles;
show profile for query 8;
show profile cpu, block io for query 8;
show profile cpu for query 8;
show profile cpu for query 9 limit 2 offset 2;
show profile cpu for query 10 limit 0;
show profile cpu for query 65534;
show profile memory;
show profile block io;
show profile context switches;
show profile page faults;
show profile ipc;
show profile swaps limit 1 offset 2;
show profile source;
show profile all for query 0 limit 0;
drop table t1;
End of 5.0 tests

39
mysql-test/t/profile.test Normal file
View file

@ -0,0 +1,39 @@
create table t1 (
a int,
b int
);
--disable_result_log
insert into t1 values (1,1), (2,null), (3, 4);
insert into t1 values (5,1), (6,null), (7, 4);
insert into t1 values (1,1), (2,null), (3, 4);
insert into t1 values (5,1), (6,null), (7, 4);
insert into t1 values (5,1), (6,null), (7, 4);
select sum(a) from t1;
select sum(a) from t1 group by b;
select sum(a) + sum(b) from t1 group by b;
select max(x) from (select sum(a) as x from t1 group by b) as teeone;
# Merely verify that commands work. Checking values is impossible, right?
show profiles;
show profile for query 8;
show profile cpu, block io for query 8;
show profile cpu for query 8;
show profile cpu for query 9 limit 2 offset 2;
show profile cpu for query 10 limit 0;
show profile cpu for query 65534;
show profile memory;
show profile block io;
show profile context switches;
show profile page faults;
show profile ipc;
show profile swaps limit 1 offset 2;
show profile source;
show profile all for query 0 limit 0;
--enable_result_log
drop table t1;
##
--echo End of 5.0 tests

View file

@ -51,6 +51,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \
procedure.h sql_class.h sql_lex.h sql_list.h \
sql_manager.h sql_map.h sql_string.h unireg.h \
sql_error.h field.h handler.h mysqld_suffix.h \
sql_profile.h \
ha_myisammrg.h\
ha_heap.h ha_myisam.h ha_berkeley.h ha_innodb.h \
ha_ndbcluster.h opt_range.h protocol.h \
@ -79,6 +80,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \
set_var.cc sql_parse.cc sql_yacc.yy \
sql_base.cc table.cc sql_select.cc sql_insert.cc \
sql_prepare.cc sql_error.cc sql_locale.cc \
sql_profile.cc \
sql_update.cc sql_delete.cc uniques.cc sql_do.cc \
procedure.cc item_uniq.cc sql_test.cc \
log.cc log_event.cc init.cc derror.cc sql_acl.cc \

View file

@ -1205,7 +1205,7 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt)
ha_rows count= share->rows_recorded;
DBUG_ENTER("ha_archive::check");
thd->proc_info= "Checking table";
THD_PROC_INFO(thd, "Checking table");
/* Flush any waiting data */
gzflush(share->archive_write, Z_SYNC_FLUSH);
@ -1229,7 +1229,7 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt)
my_free((char*)buf, MYF(0));
thd->proc_info= old_proc_info;
THD_PROC_INFO(thd, old_proc_info);
if ((rc && rc != HA_ERR_END_OF_FILE) || count)
{

View file

@ -339,7 +339,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
MYISAM_SHARE* share = file->s;
const char *old_proc_info=thd->proc_info;
thd->proc_info="Checking table";
THD_PROC_INFO(thd, "Checking table");
myisamchk_init(&param);
param.thd = thd;
param.op_name = "check";
@ -413,7 +413,7 @@ int ha_myisam::check(THD* thd, HA_CHECK_OPT* check_opt)
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
}
thd->proc_info=old_proc_info;
THD_PROC_INFO(thd, old_proc_info);
return error ? HA_ADMIN_CORRUPT : HA_ADMIN_OK;
}
@ -679,22 +679,22 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
char buf[40];
/* TODO: respect myisam_repair_threads variable */
my_snprintf(buf, 40, "Repair with %d threads", my_count_bits(key_map));
thd->proc_info=buf;
THD_PROC_INFO(thd, buf);
error = mi_repair_parallel(&param, file, fixed_name,
param.testflag & T_QUICK);
thd->proc_info="Repair done"; // to reset proc_info, as
THD_PROC_INFO(thd, "Repair done"); // to reset proc_info, as
// it was pointing to local buffer
}
else
{
thd->proc_info="Repair by sorting";
THD_PROC_INFO(thd, "Repair by sorting");
error = mi_repair_by_sort(&param, file, fixed_name,
param.testflag & T_QUICK);
}
}
else
{
thd->proc_info="Repair with keycache";
THD_PROC_INFO(thd, "Repair with keycache");
param.testflag &= ~T_REP_BY_SORT;
error= mi_repair(&param, file, fixed_name,
param.testflag & T_QUICK);
@ -708,7 +708,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
(share->state.changed & STATE_NOT_SORTED_PAGES))
{
optimize_done=1;
thd->proc_info="Sorting index";
THD_PROC_INFO(thd, "Sorting index");
error=mi_sort_index(&param,file,fixed_name);
}
if (!statistics_done && (local_testflag & T_STATISTICS))
@ -716,14 +716,14 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
if (share->state.changed & STATE_NOT_ANALYZED)
{
optimize_done=1;
thd->proc_info="Analyzing";
THD_PROC_INFO(thd, "Analyzing");
error = chk_key(&param, file);
}
else
local_testflag&= ~T_STATISTICS; // Don't update statistics
}
}
thd->proc_info="Saving state";
THD_PROC_INFO(thd, "Saving state");
if (!error)
{
if ((share->state.changed & STATE_CHANGED) || mi_is_crashed(file))
@ -761,7 +761,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK &param, bool optimize)
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
update_state_info(&param, file, 0);
}
thd->proc_info=old_proc_info;
THD_PROC_INFO(thd, old_proc_info);
if (!thd->locked_tables)
mi_lock_database(file,F_UNLCK);
DBUG_RETURN(error ? HA_ADMIN_FAILED :
@ -986,7 +986,7 @@ int ha_myisam::enable_indexes(uint mode)
THD *thd=current_thd;
MI_CHECK param;
const char *save_proc_info=thd->proc_info;
thd->proc_info="Creating index";
THD_PROC_INFO(thd, "Creating index");
myisamchk_init(&param);
param.op_name= "recreating_index";
param.testflag= (T_SILENT | T_REP_BY_SORT | T_QUICK |
@ -1011,7 +1011,7 @@ int ha_myisam::enable_indexes(uint mode)
thd->clear_error();
}
info(HA_STATUS_CONST);
thd->proc_info=save_proc_info;
THD_PROC_INFO(thd, save_proc_info);
}
else
{

View file

@ -3204,7 +3204,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout)
Structure is now initialized. Try to get the lock.
Set up control struct to allow others to abort locks
*/
thd->proc_info="User lock";
THD_PROC_INFO(thd, "User lock");
thd->mysys_var->current_mutex= &LOCK_user_locks;
thd->mysys_var->current_cond= &ull->cond;
@ -3229,7 +3229,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout)
}
pthread_mutex_unlock(&LOCK_user_locks);
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->proc_info=0;
THD_PROC_INFO(thd, 0);
thd->mysys_var->current_mutex= 0;
thd->mysys_var->current_cond= 0;
pthread_mutex_unlock(&thd->mysys_var->mutex);
@ -3310,7 +3310,7 @@ longlong Item_func_get_lock::val_int()
Structure is now initialized. Try to get the lock.
Set up control struct to allow others to abort locks.
*/
thd->proc_info="User lock";
THD_PROC_INFO(thd, "User lock");
thd->mysys_var->current_mutex= &LOCK_user_locks;
thd->mysys_var->current_cond= &ull->cond;
@ -3348,7 +3348,7 @@ longlong Item_func_get_lock::val_int()
pthread_mutex_unlock(&LOCK_user_locks);
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->proc_info=0;
THD_PROC_INFO(thd, 0);
thd->mysys_var->current_mutex= 0;
thd->mysys_var->current_cond= 0;
pthread_mutex_unlock(&thd->mysys_var->mutex);

View file

@ -87,6 +87,7 @@ static SYMBOL symbols[] = {
{ "BINLOG", SYM(BINLOG_SYM)},
{ "BIT", SYM(BIT_SYM)},
{ "BLOB", SYM(BLOB_SYM)},
{ "BLOCK", SYM(BLOCK_SYM)},
{ "BOOL", SYM(BOOL_SYM)},
{ "BOOLEAN", SYM(BOOLEAN_SYM)},
{ "BOTH", SYM(BOTH)},
@ -125,8 +126,10 @@ static SYMBOL symbols[] = {
{ "CONSISTENT", SYM(CONSISTENT_SYM)},
{ "CONSTRAINT", SYM(CONSTRAINT)},
{ "CONTAINS", SYM(CONTAINS_SYM)},
{ "CONTEXT", SYM(CONTEXT_SYM)},
{ "CONTINUE", SYM(CONTINUE_SYM)},
{ "CONVERT", SYM(CONVERT_SYM)},
{ "CPU", SYM(CPU_SYM)},
{ "CREATE", SYM(CREATE)},
{ "CROSS", SYM(CROSS)},
{ "CUBE", SYM(CUBE_SYM)},
@ -192,6 +195,7 @@ static SYMBOL symbols[] = {
{ "EXTENDED", SYM(EXTENDED_SYM)},
{ "FALSE", SYM(FALSE_SYM)},
{ "FAST", SYM(FAST_SYM)},
{ "FAULTS", SYM(FAULTS_SYM)},
{ "FETCH", SYM(FETCH_SYM)},
{ "FIELDS", SYM(COLUMNS)},
{ "FILE", SYM(FILE_SYM)},
@ -251,7 +255,9 @@ static SYMBOL symbols[] = {
{ "INTEGER", SYM(INT_SYM)},
{ "INTERVAL", SYM(INTERVAL_SYM)},
{ "INTO", SYM(INTO)},
{ "IO", SYM(IO_SYM)},
{ "IO_THREAD", SYM(RELAY_THREAD)},
{ "IPC", SYM(IPC_SYM)},
{ "IS", SYM(IS)},
{ "ISOLATION", SYM(ISOLATION)},
{ "ISSUER", SYM(ISSUER_SYM)},
@ -309,6 +315,7 @@ static SYMBOL symbols[] = {
{ "MEDIUMBLOB", SYM(MEDIUMBLOB)},
{ "MEDIUMINT", SYM(MEDIUMINT)},
{ "MEDIUMTEXT", SYM(MEDIUMTEXT)},
{ "MEMORY", SYM(MEMORY_SYM)},
{ "MERGE", SYM(MERGE_SYM)},
{ "MICROSECOND", SYM(MICROSECOND_SYM)},
{ "MIDDLEINT", SYM(MEDIUMINT)}, /* For powerbuilder */
@ -356,6 +363,7 @@ static SYMBOL symbols[] = {
{ "OUT", SYM(OUT_SYM)},
{ "OUTER", SYM(OUTER)},
{ "OUTFILE", SYM(OUTFILE)},
{ "PAGE", SYM(PAGE_SYM)},
{ "PACK_KEYS", SYM(PACK_KEYS_SYM)},
{ "PARTIAL", SYM(PARTIAL)},
{ "PASSWORD", SYM(PASSWORD)},
@ -370,6 +378,8 @@ static SYMBOL symbols[] = {
{ "PROCEDURE", SYM(PROCEDURE)},
{ "PROCESS" , SYM(PROCESS)},
{ "PROCESSLIST", SYM(PROCESSLIST_SYM)},
{ "PROFILE", SYM(PROFILE_SYM)},
{ "PROFILES", SYM(PROFILES_SYM)},
{ "PURGE", SYM(PURGE)},
{ "QUARTER", SYM(QUARTER_SYM)},
{ "QUERY", SYM(QUERY_SYM)},
@ -437,6 +447,7 @@ static SYMBOL symbols[] = {
{ "SOME", SYM(ANY_SYM)},
{ "SONAME", SYM(UDF_SONAME_SYM)},
{ "SOUNDS", SYM(SOUNDS_SYM)},
{ "SOURCE", SYM(SOURCE_SYM)},
{ "SPATIAL", SYM(SPATIAL_SYM)},
{ "SPECIFIC", SYM(SPECIFIC_SYM)},
{ "SQL", SYM(SQL_SYM)},
@ -471,6 +482,8 @@ static SYMBOL symbols[] = {
{ "SUBJECT", SYM(SUBJECT_SYM)},
{ "SUPER", SYM(SUPER_SYM)},
{ "SUSPEND", SYM(SUSPEND_SYM)},
{ "SWAPS", SYM(SWAPS_SYM)},
{ "SWITCHES", SYM(SWITCHES_SYM)},
{ "TABLE", SYM(TABLE_SYM)},
{ "TABLES", SYM(TABLES)},
{ "TABLESPACE", SYM(TABLESPACE)},

View file

@ -150,7 +150,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
}
}
thd->proc_info="System lock";
THD_PROC_INFO(thd, "System lock");
if (lock_external(thd, tables, count))
{
/* Clear the lock type of all lock data to avoid reusage. */
@ -159,7 +159,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
sql_lock=0;
break;
}
thd->proc_info="Table lock";
THD_PROC_INFO(thd, "Table lock");
thd->locked=1;
/* Copy the lock data array. thr_multi_lock() reorders its contens. */
memcpy(sql_lock->locks + sql_lock->lock_count, sql_lock->locks,
@ -193,7 +193,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
thd->locked=0;
break;
}
thd->proc_info=0;
THD_PROC_INFO(thd, 0);
/* some table was altered or deleted. reopen tables marked deleted */
mysql_unlock_tables(thd,sql_lock);
@ -208,7 +208,7 @@ retry:
if (wait_for_tables(thd))
break; // Couldn't open tables
}
thd->proc_info=0;
THD_PROC_INFO(thd, 0);
if (thd->killed)
{
thd->send_kill_message();

View file

@ -4265,7 +4265,7 @@ int Create_file_log_event::exec_event(struct st_relay_log_info* rli)
bzero((char*)&file, sizeof(file));
fname_buf= strmov(proc_info, "Making temp file ");
ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
thd->proc_info= proc_info;
THD_PROC_INFO(thd, proc_info);
my_delete(fname_buf, MYF(0)); // old copy may exist already
if ((fd= my_create(fname_buf, CREATE_MODE,
O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
@ -4319,7 +4319,7 @@ err:
end_io_cache(&file);
if (fd >= 0)
my_close(fd, MYF(0));
thd->proc_info= 0;
THD_PROC_INFO(thd, 0);
return error ? 1 : Log_event::exec_event(rli);
}
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
@ -4439,7 +4439,7 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
fname= strmov(proc_info, "Making temp file ");
slave_load_file_stem(fname, file_id, server_id, ".data");
thd->proc_info= proc_info;
THD_PROC_INFO(thd, proc_info);
if (get_create_or_append())
{
my_delete(fname, MYF(0)); // old copy may exist already
@ -4473,7 +4473,7 @@ int Append_block_log_event::exec_event(struct st_relay_log_info* rli)
err:
if (fd >= 0)
my_close(fd, MYF(0));
thd->proc_info= 0;
THD_PROC_INFO(thd, 0);
DBUG_RETURN(error ? error : Log_event::exec_event(rli));
}
#endif

View file

@ -173,6 +173,8 @@ MY_LOCALE *my_locale_by_name(const char *name);
#define BDB_LOG_ALLOC_BLOCK_SIZE 1024
#define WARN_ALLOC_BLOCK_SIZE 2048
#define WARN_ALLOC_PREALLOC_SIZE 1024
#define PROFILE_ALLOC_BLOCK_SIZE 2048
#define PROFILE_ALLOC_PREALLOC_SIZE 1024
/*
The following parameters is to decide when to use an extra cache to
@ -541,6 +543,8 @@ typedef my_bool (*qc_engine_callback)(THD *thd, char *table_key,
#include "field.h" /* Field definitions */
#include "protocol.h"
#include "sql_udf.h"
#include "sql_profile.h"
class user_var_entry;
class Security_context;
enum enum_var_type

View file

@ -91,7 +91,7 @@ static int init_failsafe_rpl_thread(THD* thd)
if (thd->variables.max_join_size == HA_POS_ERROR)
thd->options|= OPTION_BIG_SELECTS;
thd->proc_info="Thread initialized";
THD_PROC_INFO(thd, "Thread initialized");
thd->version=refresh_version;
thd->set_time();
DBUG_RETURN(0);
@ -597,7 +597,7 @@ pthread_handler_t handle_failsafe_rpl(void *arg)
{
bool break_req_chain = 0;
pthread_cond_wait(&COND_rpl_status, &LOCK_rpl_status);
thd->proc_info="Processing request";
THD_PROC_INFO(thd, "Processing request");
while (!break_req_chain)
{
switch (rpl_status) {
@ -941,7 +941,7 @@ bool load_master_data(THD* thd)
goto err;
}
}
thd->proc_info="purging old relay logs";
THD_PROC_INFO(thd, "purging old relay logs");
if (purge_relay_logs(&active_mi->rli,thd,
0 /* not only reset, but also reinit */,
&errmsg))

View file

@ -2924,9 +2924,9 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
#endif
if (thd_type == SLAVE_THD_SQL)
thd->proc_info= "Waiting for the next event in relay log";
THD_PROC_INFO(thd, "Waiting for the next event in relay log");
else
thd->proc_info= "Waiting for master update";
THD_PROC_INFO(thd, "Waiting for master update");
thd->version=refresh_version;
thd->set_time();
DBUG_RETURN(0);
@ -3545,7 +3545,7 @@ dump");
}
mi->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT;
thd->proc_info= "Waiting to reconnect after a failed binlog dump request";
THD_PROC_INFO(thd, "Waiting to reconnect after a failed binlog dump request");
#ifdef SIGNAL_WITH_VIO_CLOSE
thd->clear_active_vio();
#endif

View file

@ -2387,9 +2387,9 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp,
m_lex->unit.cleanup();
thd->proc_info="closing tables";
THD_PROC_INFO(thd, "closing tables");
close_thread_tables(thd);
thd->proc_info= 0;
THD_PROC_INFO(thd, 0);
if (m_lex->query_tables_own_last)
{

View file

@ -306,7 +306,7 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
*/
thd->mysys_var->current_mutex= &LOCK_open;
thd->mysys_var->current_cond= &COND_refresh;
thd->proc_info="Flushing tables";
THD_PROC_INFO(thd, "Flushing tables");
close_old_data_files(thd,thd->open_tables,1,1);
mysql_ha_flush(thd, tables, MYSQL_HA_REOPEN_ON_USAGE | MYSQL_HA_FLUSH_ALL,
@ -348,7 +348,7 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh,
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= 0;
thd->mysys_var->current_cond= 0;
thd->proc_info=0;
THD_PROC_INFO(thd, 0);
pthread_mutex_unlock(&thd->mysys_var->mutex);
}
DBUG_RETURN(result);
@ -1070,7 +1070,7 @@ void wait_for_refresh(THD *thd)
thd->mysys_var->current_mutex= &LOCK_open;
thd->mysys_var->current_cond= &COND_refresh;
proc_info=thd->proc_info;
thd->proc_info="Waiting for table";
THD_PROC_INFO(thd, "Waiting for table");
if (!thd->killed)
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
@ -1078,7 +1078,7 @@ void wait_for_refresh(THD *thd)
pthread_mutex_lock(&thd->mysys_var->mutex);
thd->mysys_var->current_mutex= 0;
thd->mysys_var->current_cond= 0;
thd->proc_info= proc_info;
THD_PROC_INFO(thd, proc_info);
pthread_mutex_unlock(&thd->mysys_var->mutex);
DBUG_VOID_RETURN;
}
@ -1783,7 +1783,7 @@ bool wait_for_tables(THD *thd)
bool result;
DBUG_ENTER("wait_for_tables");
thd->proc_info="Waiting for tables";
THD_PROC_INFO(thd, "Waiting for tables");
pthread_mutex_lock(&LOCK_open);
while (!thd->killed)
{
@ -1799,12 +1799,12 @@ bool wait_for_tables(THD *thd)
else
{
/* Now we can open all tables without any interference */
thd->proc_info="Reopen tables";
THD_PROC_INFO(thd, "Reopen tables");
thd->version= refresh_version;
result=reopen_tables(thd,0,0);
}
pthread_mutex_unlock(&LOCK_open);
thd->proc_info=0;
THD_PROC_INFO(thd, 0);
DBUG_RETURN(result);
}
@ -2103,7 +2103,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags)
restart:
*counter= 0;
query_tables_last_own= 0;
thd->proc_info="Opening tables";
THD_PROC_INFO(thd, "Opening tables");
/*
If we are not already executing prelocked statement and don't have
@ -2283,7 +2283,7 @@ process_view_routines:
}
err:
thd->proc_info=0;
THD_PROC_INFO(thd, 0);
free_root(&new_frm_mem, MYF(0)); // Free pre-alloced block
if (query_tables_last_own)
@ -2357,7 +2357,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
bool refresh;
DBUG_ENTER("open_ltable");
thd->proc_info="Opening table";
THD_PROC_INFO(thd, "Opening table");
thd->current_tablenr= 0;
/* open_ltable can be used only for BASIC TABLEs */
table_list->required_type= FRMTYPE_TABLE;
@ -2391,7 +2391,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
table= 0;
}
}
thd->proc_info=0;
THD_PROC_INFO(thd, 0);
DBUG_RETURN(table);
}
@ -5436,7 +5436,7 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
List_iterator<Item_func_match> li(*(select_lex->ftfunc_list));
Item_func_match *ifm;
DBUG_PRINT("info",("Performing FULLTEXT search"));
thd->proc_info="FULLTEXT initialization";
THD_PROC_INFO(thd, "FULLTEXT initialization");
while ((ifm=li++))
ifm->init_search(no_order);

View file

@ -669,6 +669,7 @@ void query_cache_insert(NET *net, const char *packet, ulong length)
void query_cache_abort(NET *net)
{
DBUG_ENTER("query_cache_abort");
THD *thd= current_thd;
/* See the comment on double-check locking usage above. */
if (net->query_cache_query == 0)
@ -687,6 +688,7 @@ void query_cache_abort(NET *net)
net->query_cache_query);
if (query_block) // Test if changed by other thread
{
THD_PROC_INFO(thd, "storing result in query cache");
DUMP(&query_cache);
BLOCK_LOCK_WR(query_block);
// The following call will remove the lock on query_block
@ -724,6 +726,7 @@ void query_cache_end_of_result(THD *thd)
query_block= ((Query_cache_block*) thd->net.query_cache_query);
if (query_block)
{
THD_PROC_INFO(thd, "storing result in query cache");
DUMP(&query_cache);
BLOCK_LOCK_WR(query_block);
Query_cache_query *header= query_block->query();
@ -1088,6 +1091,8 @@ Query_cache::send_result_to_client(THD *thd, char *sql, uint query_length)
DBUG_PRINT("qcache", ("No active database"));
}
THD_PROC_INFO(thd, "checking query cache for query");
// fill all gaps between fields with 0 to get repeatable key
bzero(&flags, QUERY_CACHE_FLAGS_SIZE);
flags.client_long_flag= test(thd->client_capabilities & CLIENT_LONG_FLAG);
@ -1162,6 +1167,7 @@ sql mode: 0x%lx, sort len: %lu, conncat len: %lu",
}
// Check access;
THD_PROC_INFO(thd, "checking privileges on cached query");
block_table= query_block->table(0);
block_table_end= block_table+query_block->n_tables;
for (; block_table != block_table_end; block_table++)
@ -1254,6 +1260,7 @@ sql mode: 0x%lx, sort len: %lu, conncat len: %lu",
Send cached result to client
*/
#ifndef EMBEDDED_LIBRARY
THD_PROC_INFO(thd, "sending cached result to client");
do
{
DBUG_PRINT("qcache", ("Results (len: %lu used: %lu headers: %lu)",
@ -1331,9 +1338,11 @@ void Query_cache::invalidate(THD *thd, TABLE_LIST *tables_used,
void Query_cache::invalidate(CHANGED_TABLE_LIST *tables_used)
{
THD *thd= current_thd;
DBUG_ENTER("Query_cache::invalidate (changed table list)");
if (tables_used)
{
THD_PROC_INFO(thd, "invalidating query cache entries (table list)");
STRUCT_LOCK(&structure_guard_mutex);
if (query_cache_size > 0 && !flush_in_progress)
{
@ -1364,9 +1373,11 @@ void Query_cache::invalidate(CHANGED_TABLE_LIST *tables_used)
*/
void Query_cache::invalidate_locked_for_write(TABLE_LIST *tables_used)
{
THD *thd= current_thd;
DBUG_ENTER("Query_cache::invalidate_locked_for_write");
if (tables_used)
{
THD_PROC_INFO(thd, "invalidating query cache entries (table)");
STRUCT_LOCK(&structure_guard_mutex);
if (query_cache_size > 0 && !flush_in_progress)
{
@ -1416,6 +1427,7 @@ void Query_cache::invalidate(THD *thd, const char *key, uint32 key_length,
STRUCT_LOCK(&structure_guard_mutex);
if (query_cache_size > 0 && !flush_in_progress)
{
THD_PROC_INFO(thd, "invalidating query cache entries (key)");
using_transactions= using_transactions &&
(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
if (using_transactions) // used for innodb => has_transactions() is TRUE

View file

@ -247,6 +247,7 @@ THD::THD()
init();
/* Initialize sub structures */
init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
profiling.set_thd(this);
user_connect=(USER_CONN *)0;
hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
(hash_get_key) get_var_key,
@ -329,6 +330,7 @@ void THD::init_for_queries()
variables.trans_alloc_block_size,
variables.trans_prealloc_size);
#endif
profiling.reset();
transaction.xid_state.xid.null();
transaction.xid_state.in_thd=1;
}

View file

@ -1308,6 +1308,9 @@ public:
List <MYSQL_ERROR> warn_list;
uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END];
uint total_warn_count;
PROFILING profiling;
/*
Id of current query. Statement can be reused to execute several queries
query_id is global in context of the whole MySQL server.

View file

@ -54,7 +54,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
table->file->print_error(error, MYF(0));
DBUG_RETURN(error);
}
thd->proc_info="init";
THD_PROC_INFO(thd, "init");
table->map=1;
if (mysql_prepare_delete(thd, table_list, &conds))
@ -205,7 +205,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
deleted=0L;
init_ftfuncs(thd, select_lex, 1);
thd->proc_info="updating";
THD_PROC_INFO(thd, "updating");
if (table->triggers)
table->triggers->mark_fields_used(thd, TRG_EVENT_DELETE);
@ -261,7 +261,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
}
if (thd->killed && !error)
error= 1; // Aborted
thd->proc_info="end";
THD_PROC_INFO(thd, "end");
end_read_record(&info);
free_io_cache(table); // Will not do any harm
if (options & OPTION_QUICK)
@ -485,7 +485,7 @@ multi_delete::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
DBUG_ENTER("multi_delete::prepare");
unit= u;
do_delete= 1;
thd->proc_info="deleting from main table";
THD_PROC_INFO(thd, "deleting from main table");
DBUG_RETURN(0);
}
@ -749,7 +749,7 @@ int multi_delete::do_deletes()
bool multi_delete::send_eof()
{
thd->proc_info="deleting from reference tables";
THD_PROC_INFO(thd, "deleting from reference tables");
/* Does deletes for the last n - 1 tables, returns 0 if ok */
int local_error= do_deletes(); // returns 0 if success
@ -758,7 +758,7 @@ bool multi_delete::send_eof()
local_error= local_error || error;
/* reset used flags */
thd->proc_info="end";
THD_PROC_INFO(thd, "end");
/*
We must invalidate the query cache before binlog writing and

View file

@ -397,7 +397,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
if (res || thd->is_fatal_error)
DBUG_RETURN(TRUE);
thd->proc_info="init";
THD_PROC_INFO(thd, "init");
thd->used_tables=0;
values= its++;
@ -470,7 +470,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
error=0;
id=0;
thd->proc_info="update";
THD_PROC_INFO(thd, "update");
if (duplic != DUP_ERROR || ignore)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
if (duplic == DUP_REPLACE)
@ -676,7 +676,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
thd->lock=0;
}
}
thd->proc_info="end";
THD_PROC_INFO(thd, "end");
table->next_number_field=0;
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
thd->next_insert_id=0; // Reset this if wrongly used
@ -1407,7 +1407,7 @@ I_List<delayed_insert> delayed_threads;
delayed_insert *find_handler(THD *thd, TABLE_LIST *table_list)
{
thd->proc_info="waiting for delay_list";
THD_PROC_INFO(thd, "waiting for delay_list");
pthread_mutex_lock(&LOCK_delayed_insert); // Protect master list
I_List_iterator<delayed_insert> it(delayed_threads);
delayed_insert *tmp;
@ -1444,7 +1444,7 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
*/
if (delayed_insert_threads >= thd->variables.max_insert_delayed_threads)
DBUG_RETURN(0);
thd->proc_info="Creating delayed handler";
THD_PROC_INFO(thd, "Creating delayed handler");
pthread_mutex_lock(&LOCK_delayed_create);
/*
The first search above was done without LOCK_delayed_create.
@ -1486,13 +1486,13 @@ static TABLE *delayed_get_table(THD *thd,TABLE_LIST *table_list)
}
/* Wait until table is open */
thd->proc_info="waiting for handler open";
THD_PROC_INFO(thd, "waiting for handler open");
while (!tmp->thd.killed && !tmp->table && !thd->killed)
{
pthread_cond_wait(&tmp->cond_client,&tmp->mutex);
}
pthread_mutex_unlock(&tmp->mutex);
thd->proc_info="got old table";
THD_PROC_INFO(thd, "got old table");
if (tmp->thd.killed)
{
if (tmp->thd.is_fatal_error)
@ -1552,13 +1552,13 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
tables_in_use++;
if (!thd.lock) // Table is not locked
{
client_thd->proc_info="waiting for handler lock";
THD_PROC_INFO(client_thd, "waiting for handler lock");
pthread_cond_signal(&cond); // Tell handler to lock table
while (!dead && !thd.lock && ! client_thd->killed)
{
pthread_cond_wait(&cond_client,&mutex);
}
client_thd->proc_info="got handler lock";
THD_PROC_INFO(client_thd, "got handler lock");
if (client_thd->killed)
goto error;
if (dead)
@ -1576,7 +1576,7 @@ TABLE *delayed_insert::get_local_table(THD* client_thd)
bytes. Since the table copy is used for creating one record only,
the other record buffers and alignment are unnecessary.
*/
client_thd->proc_info="allocating local table";
THD_PROC_INFO(client_thd, "allocating local table");
copy= (TABLE*) client_thd->alloc(sizeof(*copy)+
(table->s->fields+1)*sizeof(Field**)+
table->s->reclength);
@ -1656,11 +1656,11 @@ static int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic, bool igno
delayed_insert *di=thd->di;
DBUG_ENTER("write_delayed");
thd->proc_info="waiting for handler insert";
THD_PROC_INFO(thd, "waiting for handler insert");
pthread_mutex_lock(&di->mutex);
while (di->stacked_inserts >= delayed_queue_size && !thd->killed)
pthread_cond_wait(&di->cond_client,&di->mutex);
thd->proc_info="storing row into queue";
THD_PROC_INFO(thd, "storing row into queue");
if (thd->killed || !(row= new delayed_row(duplic, ignore, log_on)))
goto err;
@ -1869,7 +1869,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
/* Information for pthread_kill */
di->thd.mysys_var->current_mutex= &di->mutex;
di->thd.mysys_var->current_cond= &di->cond;
di->thd.proc_info="Waiting for INSERT";
THD_PROC_INFO(&(di->thd), "Waiting for INSERT");
DBUG_PRINT("info",("Waiting for someone to insert rows"));
while (!thd->killed)
@ -1904,7 +1904,7 @@ pthread_handler_t handle_delayed_insert(void *arg)
pthread_mutex_unlock(&di->thd.mysys_var->mutex);
pthread_mutex_lock(&di->mutex);
}
di->thd.proc_info=0;
THD_PROC_INFO(&(di->thd), 0);
if (di->tables_in_use && ! thd->lock)
{
@ -2023,7 +2023,7 @@ bool delayed_insert::handle_inserts(void)
table->next_number_field=table->found_next_number_field;
thd.proc_info="upgrading lock";
THD_PROC_INFO(&thd, "upgrading lock");
if (thr_upgrade_write_delay_lock(*thd.lock->locks))
{
/* This can only happen if thread is killed by shutdown */
@ -2031,7 +2031,7 @@ bool delayed_insert::handle_inserts(void)
goto err;
}
thd.proc_info="insert";
THD_PROC_INFO(&thd, "insert");
max_rows= delayed_insert_limit;
if (thd.killed || table->s->version != refresh_version)
{
@ -2149,7 +2149,7 @@ bool delayed_insert::handle_inserts(void)
{
if (tables_in_use)
pthread_cond_broadcast(&cond_client); // If waiting clients
thd.proc_info="reschedule";
THD_PROC_INFO(&thd, "reschedule");
pthread_mutex_unlock(&mutex);
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))
{
@ -2168,14 +2168,14 @@ bool delayed_insert::handle_inserts(void)
if (!using_bin_log)
table->file->extra(HA_EXTRA_WRITE_CACHE);
pthread_mutex_lock(&mutex);
thd.proc_info="insert";
THD_PROC_INFO(&thd, "insert");
}
if (tables_in_use)
pthread_cond_broadcast(&cond_client); // If waiting clients
}
}
thd.proc_info=0;
THD_PROC_INFO(&thd, 0);
table->next_number_field=0;
pthread_mutex_unlock(&mutex);
if ((error=table->file->extra(HA_EXTRA_NO_CACHE)))

View file

@ -173,6 +173,7 @@ void lex_start(THD *thd, uchar *buf,uint length)
lex->proc_list.first= 0;
lex->escape_used= FALSE;
lex->reset_query_tables_list(FALSE);
lex->profile_options= PROFILE_NONE;
lex->nest_level=0 ;
lex->allow_sum_func= 0;

View file

@ -94,6 +94,7 @@ enum enum_sql_command {
SQLCOM_XA_START, SQLCOM_XA_END, SQLCOM_XA_PREPARE,
SQLCOM_XA_COMMIT, SQLCOM_XA_ROLLBACK, SQLCOM_XA_RECOVER,
SQLCOM_SHOW_PROC_CODE, SQLCOM_SHOW_FUNC_CODE,
SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES,
/* This should be the last !!! */
SQLCOM_END
@ -938,6 +939,8 @@ typedef struct st_lex : public Query_tables_list
enum enum_var_type option_type;
enum enum_view_create_mode create_view_mode;
enum enum_drop_mode drop_mode;
uint profile_options;
uint profile_query_id;
uint uint_geom_type;
uint grant, grant_tot_col, which_columns;
uint fk_delete_opt, fk_update_opt, fk_match_option;

View file

@ -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= "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= 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=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=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));
@ -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="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="cleaning up";
THD_PROC_INFO(thd, "cleaning up");
VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list
thd->proc_info=0;
THD_PROC_INFO(thd, 0);
thd->command=COM_SLEEP;
thd->query=0;
thd->query_length=0;
@ -2163,8 +2163,6 @@ void log_slow_statement(THD *thd)
*/
if (thd->enable_slow_log && !thd->user_time)
{
thd->proc_info="logging slow query";
if ((ulong) (thd->start_time - thd->time_after_lock) >
thd->variables.long_query_time ||
(thd->server_status &
@ -2173,6 +2171,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->status_var.long_query_count++;
mysql_slow_log.write(thd, thd->query, thd->query_length, start_of_query);
}
@ -2697,6 +2696,20 @@ mysql_execute_command(THD *thd)
(1L << (uint) MYSQL_ERROR::WARN_LEVEL_ERROR));
break;
}
case SQLCOM_SHOW_PROFILES:
{
thd->profiling.store();
thd->profiling.discard();
res= thd->profiling.show_profiles();
break;
}
case SQLCOM_SHOW_PROFILE:
{
thd->profiling.store();
thd->profiling.discard(); // will get re-enabled by reset()
res= thd->profiling.show_last(lex->profile_options);
break;
}
case SQLCOM_SHOW_NEW_MASTER:
{
if (check_global_access(thd, REPL_SLAVE_ACL))
@ -3544,7 +3557,7 @@ end_with_restore_list:
if (add_item_to_list(thd, new Item_null()))
goto error;
thd->proc_info="init";
THD_PROC_INFO(thd, "init");
if ((res= open_and_lock_tables(thd, all_tables)))
break;
@ -4973,7 +4986,7 @@ create_sp_error:
send_ok(thd);
break;
}
thd->proc_info="query end";
THD_PROC_INFO(thd, "query end");
/* Two binlog-related cleanups: */
/*
@ -5144,6 +5157,8 @@ check_access(THD *thd, ulong want_access, const char *db, ulong *save_priv,
else
save_priv= &dummy;
THD_PROC_INFO(thd, "checking permissions");
if ((!db || !db[0]) && !thd->db && !dont_check_global_grants)
{
DBUG_PRINT("error",("No database"));
@ -5631,6 +5646,7 @@ 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;
thd->profiling.reset();
}
DBUG_VOID_RETURN;
}
@ -5854,7 +5870,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
query_cache_abort(&thd->net);
lex->unit.cleanup();
}
thd->proc_info="freeing items";
THD_PROC_INFO(thd, "freeing items");
thd->end_statement();
thd->cleanup_after_query();
DBUG_ASSERT(thd->change_list.is_empty());

441
sql/sql_profile.cc Normal file
View file

@ -0,0 +1,441 @@
/* Copyright (C) 2005 MySQL AB
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; either version 2 of the License, or
(at your option) any later version.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "mysql_priv.h"
#include "sp_rcontext.h"
#define RUSAGE_USEC(tv) ((tv).tv_sec*1000000 + (tv).tv_usec)
#define RUSAGE_DIFF_USEC(tv1, tv2) (RUSAGE_USEC((tv1))-RUSAGE_USEC((tv2)))
PROFILE_ENTRY::PROFILE_ENTRY()
:status(NULL), time(0), function(NULL), file(NULL), line(0)
{
collect();
}
PROFILE_ENTRY::PROFILE_ENTRY(PROFILE *profile_arg, const char *status_arg)
:profile(profile_arg), function(NULL), file(NULL), line(0)
{
collect();
if (status_arg)
set_status(status_arg);
}
PROFILE_ENTRY::PROFILE_ENTRY(PROFILE *profile_arg, const char *status_arg,
const char *function_arg,
const char *file_arg, unsigned int line_arg)
:profile(profile_arg)
{
collect();
if (status_arg)
set_status(status_arg);
if (function_arg)
function= strdup_root(&profile->profiling->root, function_arg);
if (file_arg)
file= strdup_root(&profile->profiling->root, file_arg);
line= line_arg;
}
PROFILE_ENTRY::~PROFILE_ENTRY()
{
if (status)
free(status);
if (function)
free(function);
if (file)
free(file);
}
void PROFILE_ENTRY::set_status(const char *status_arg)
{
status= strdup_root(&profile->profiling->root, status_arg);
}
void PROFILE_ENTRY::collect()
{
time= my_getsystime();
getrusage(RUSAGE_SELF, &rusage);
}
PROFILE::PROFILE(PROFILING *profiling_arg)
:profiling(profiling_arg)
{
profile_end= &profile_start;
}
PROFILE::~PROFILE()
{
entries.empty();
}
void PROFILE::status(const char *status_arg,
const char *function_arg=NULL,
const char *file_arg=NULL, unsigned int line_arg=0)
{
PROFILE_ENTRY *prof= NULL;
MEM_ROOT *old_root= NULL;
THD *thd= profiling->thd;
DBUG_ENTER("PROFILE::status");
/* Blank status. Just return, and thd->proc_info will be set blank later. */
if (unlikely(!status_arg))
DBUG_VOID_RETURN;
/* If thd->proc_info is currently set to status_arg, don't profile twice. */
if (unlikely(thd->proc_info && !(strcmp(thd->proc_info, status_arg))))
DBUG_VOID_RETURN;
/* Is this the same query as our profile currently contains? */
if (unlikely(thd->query_id != query_id && !thd->spcont))
reset();
/*
In order to keep the profile information between queries (i.e. from
SELECT to the following SHOW PROFILE command) the following code is
necessary to keep the profile from getting freed automatically when
mysqld cleans up after the query. This code is shamelessly stolen
from SHOW WARNINGS.
The thd->mem_root structure is freed after each query is completed,
so temporarily override it.
*/
old_root= thd->mem_root;
thd->mem_root= &profiling->root;
if (function_arg && file_arg) {
if ((profile_end= prof= new PROFILE_ENTRY(this, status_arg, function_arg, file_arg, line_arg)))
entries.push_back(prof);
} else {
if ((profile_end= prof= new PROFILE_ENTRY(this, status_arg)))
entries.push_back(prof);
}
thd->mem_root= old_root;
DBUG_VOID_RETURN;
}
void PROFILE::reset()
{
DBUG_ENTER("PROFILE::reset");
if (profiling->thd->query_id != query_id)
{
query_id= profiling->thd->query_id;
profile_start.collect();
entries.empty();
}
DBUG_VOID_RETURN;
}
bool PROFILE::show(uint options)
{
PROFILE_ENTRY *prof;
THD *thd= profiling->thd;
PROFILE_ENTRY *ps= &profile_start;
List<Item> field_list;
DBUG_ENTER("PROFILE::show");
field_list.push_back(new Item_empty_string("Status", MYSQL_ERRMSG_SIZE));
field_list.push_back(new Item_return_int("Time_elapsed", 20,
MYSQL_TYPE_LONGLONG));
if (options & PROFILE_CPU)
{
field_list.push_back(new Item_return_int("CPU_user", 20,
MYSQL_TYPE_LONGLONG));
field_list.push_back(new Item_return_int("CPU_system", 20,
MYSQL_TYPE_LONGLONG));
}
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);
SELECT_LEX *sel= &thd->lex->select_lex;
SELECT_LEX_UNIT *unit= &thd->lex->unit;
ha_rows idx= 0;
Protocol *protocol=thd->protocol;
unit->set_limit(sel);
List_iterator<PROFILE_ENTRY> it(entries);
ulonglong last_time= ps->time;
while ((prof= it++))
{
if (++idx <= unit->offset_limit_cnt)
continue;
if (idx > unit->select_limit_cnt)
break;
protocol->prepare_for_resend();
protocol->store(prof->status, strlen(prof->status), system_charset_info);
protocol->store((ulonglong)(prof->time - ps->time)/10);
if (options & PROFILE_CPU)
{
protocol->store((ulonglong)RUSAGE_DIFF_USEC(prof->rusage.ru_utime,
ps->rusage.ru_utime));
protocol->store((ulonglong)RUSAGE_DIFF_USEC(prof->rusage.ru_stime,
ps->rusage.ru_stime));
}
if (options & PROFILE_CONTEXT)
{
protocol->store((uint32)(prof->rusage.ru_nvcsw - ps->rusage.ru_nvcsw));
protocol->store((uint32)(prof->rusage.ru_nivcsw - ps->rusage.ru_nivcsw));
}
if (options & PROFILE_BLOCK_IO)
{
protocol->store((uint32)(prof->rusage.ru_inblock-ps->rusage.ru_inblock));
protocol->store((uint32)(prof->rusage.ru_oublock-ps->rusage.ru_oublock));
}
if (options & PROFILE_IPC)
{
protocol->store((uint32)(prof->rusage.ru_msgsnd - ps->rusage.ru_msgsnd));
protocol->store((uint32)(prof->rusage.ru_msgrcv - ps->rusage.ru_msgrcv));
}
if (options & PROFILE_PAGE_FAULTS)
{
protocol->store((uint32)(prof->rusage.ru_majflt - ps->rusage.ru_majflt));
protocol->store((uint32)(prof->rusage.ru_minflt - ps->rusage.ru_minflt));
}
if (options & PROFILE_SWAPS)
{
protocol->store((uint32)(prof->rusage.ru_nswap - ps->rusage.ru_nswap));
}
if (options & PROFILE_SOURCE)
{
if(prof->function && prof->file)
{
protocol->store(prof->function, strlen(prof->function), system_charset_info);
protocol->store(prof->file, strlen(prof->file), system_charset_info);
protocol->store(prof->line);
} else {
protocol->store("(unknown)", 10, system_charset_info);
protocol->store("(unknown)", 10, system_charset_info);
protocol->store((uint32) 0);
}
}
if (protocol->write())
DBUG_RETURN(TRUE);
last_time= prof->time;
}
send_eof(thd);
DBUG_RETURN(FALSE);
}
/* XXX: enabled should be set to the current global profiling setting */
PROFILING::PROFILING()
:enabled(1), keeping(1), current(NULL), last(NULL)
{
init_sql_alloc(&root,
PROFILE_ALLOC_BLOCK_SIZE,
PROFILE_ALLOC_PREALLOC_SIZE);
}
PROFILING::~PROFILING()
{
free_root(&root, MYF(0));
}
void PROFILING::status(const char *status_arg,
const char *function_arg,
const char *file_arg, unsigned int line_arg)
{
DBUG_ENTER("PROFILING::status");
if(!current)
reset();
if(unlikely(enabled))
current->status(status_arg, function_arg, file_arg, line_arg);
thd->proc_info= status_arg;
DBUG_VOID_RETURN;
}
void PROFILING::store()
{
MEM_ROOT *old_root;
DBUG_ENTER("PROFILING::store");
if (last && current && (last->query_id == current->query_id))
DBUG_VOID_RETURN;
if (history.elements > 10) /* XXX: global/session var */
{
PROFILE *tmp= history.pop();
delete tmp;
}
old_root= thd->mem_root;
thd->mem_root= &root;
if (current)
{
if (keeping && (!current->entries.is_empty())) {
last= current;
history.push_back(current);
current= NULL;
} else {
delete current;
}
}
current= new PROFILE(this);
thd->mem_root= old_root;
DBUG_VOID_RETURN;
}
void PROFILING::reset()
{
DBUG_ENTER("PROFILING::reset");
store();
current->reset();
/*free_root(&root, MYF(0));*/
keep();
DBUG_VOID_RETURN;
}
bool PROFILING::show_profiles()
{
PROFILE *prof;
List<Item> field_list;
DBUG_ENTER("PROFILING::list_all");
field_list.push_back(new Item_return_int("Query_ID", 10,
MYSQL_TYPE_LONG));
field_list.push_back(new Item_return_int("Time", 20,
MYSQL_TYPE_LONGLONG));
/* TODO: Add another field that lists the query. */
if (thd->protocol->send_fields(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
SELECT_LEX *sel= &thd->lex->select_lex;
SELECT_LEX_UNIT *unit= &thd->lex->unit;
ha_rows idx= 0;
Protocol *protocol=thd->protocol;
unit->set_limit(sel);
List_iterator<PROFILE> it(history);
while ((prof= it++))
{
PROFILE_ENTRY *ps= &prof->profile_start;
PROFILE_ENTRY *pe= prof->profile_end;
if (++idx <= unit->offset_limit_cnt)
continue;
if (idx > unit->select_limit_cnt)
break;
protocol->prepare_for_resend();
protocol->store((uint32)(prof->query_id));
protocol->store((ulonglong)((pe->time - ps->time)/10));
if (protocol->write())
DBUG_RETURN(TRUE);
}
send_eof(thd);
DBUG_RETURN(FALSE);
}
bool PROFILING::show(uint options, uint query_id)
{
DBUG_ENTER("PROFILING::show");
PROFILE *prof;
List_iterator<PROFILE> it(history);
while ((prof= it++))
{
if(prof->query_id == query_id)
prof->show(options);
}
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);
}

187
sql/sql_profile.h Normal file
View file

@ -0,0 +1,187 @@
/* Copyright (C) 2005 MySQL AB
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; either version 2 of the License, or
(at your option) any later version.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#ifndef SQL_PROFILE_H
#define SQL_PROFILE_H
#include <sys/time.h>
#include <sys/resource.h>
#if 1
#define THD_PROC_INFO(thd, msg) do { if(unlikely((thd)->profiling.enabled)) { (thd)->profiling.status((msg), __FUNCTION__, __FILE__, __LINE__); } else { (thd)->proc_info= (msg); } } while (0)
#else
#define THD_PROC_INFO(thd, msg) do { (thd)->proc_info= (msg); } while (0)
#endif
#if 0
struct rusage {
struct timeval ru_utime; /* user time used */
struct timeval ru_stime; /* system time used */
long ru_maxrss; /* integral max resident set size */
long ru_ixrss; /* integral shared text memory size */
long ru_idrss; /* integral unshared data size */
long ru_isrss; /* integral unshared stack size */
long ru_minflt; /* page reclaims */
long ru_majflt; /* page faults */
long ru_nswap; /* swaps */
long ru_inblock; /* block input operations */
long ru_oublock; /* block output operations */
long ru_msgsnd; /* messages sent */
long ru_msgrcv; /* messages received */
long ru_nsignals; /* signals received */
long ru_nvcsw; /* voluntary context switches */
long ru_nivcsw; /* involuntary context switches */
};
#endif
#define PROFILE_NONE 0
#define PROFILE_CPU 1
#define PROFILE_MEMORY 2
#define PROFILE_BLOCK_IO 4
#define PROFILE_CONTEXT 8
#define PROFILE_PAGE_FAULTS 16
#define PROFILE_IPC 32
#define PROFILE_SWAPS 64
#define PROFILE_SOURCE 16384
#define PROFILE_ALL 32767
class PROFILE_ENTRY;
class PROFILE;
class PROFILING;
/*
A single entry in a single profile.
*/
class PROFILE_ENTRY: public Sql_alloc
{
public:
PROFILE *profile;
char *status;
ulonglong time;
struct rusage rusage;
char *function;
char *file;
unsigned int line;
PROFILE_ENTRY();
PROFILE_ENTRY(PROFILE *profile_arg, const char *status_arg);
PROFILE_ENTRY(PROFILE *profile_arg, const char *status_arg,
const char *function_arg,
const char *file_arg, unsigned int line_arg);
~PROFILE_ENTRY();
void set_status(const char *status_arg);
void collect();
};
/*
The full profile for a single query. Includes multiple PROFILE_ENTRY
objects.
*/
class PROFILE: public Sql_alloc
{
public:
PROFILING *profiling;
query_id_t query_id;
PROFILE_ENTRY profile_start;
PROFILE_ENTRY *profile_end;
List<PROFILE_ENTRY> entries;
PROFILE(PROFILING *profiling_arg);
~PROFILE();
/* Add a profile status change to the current profile. */
void status(const char *status_arg,
const char *function_arg,
const char *file_arg, unsigned int line_arg);
/* Reset the contents of this profile entry. */
void reset();
/* Show this profile. This is called by PROFILING. */
bool show(uint options);
};
/*
Profiling state for a single THD. Contains multiple PROFILE objects.
*/
class PROFILING: public Sql_alloc
{
public:
MEM_ROOT root;
THD *thd;
bool enabled;
bool keeping;
PROFILE *current;
PROFILE *last;
List<PROFILE> history;
PROFILING();
~PROFILING();
inline void set_thd(THD *thd_arg) { thd= thd_arg; };
/*
Should we try to collect profiling information at all?
If we disable profiling, we cannot later decide to turn it back
on for the same query.
*/
inline void enable() { enabled= 1; };
inline void disable() { enabled= 0; };
/*
Do we intend to keep the currently collected profile?
We don't keep profiles for some commands, such as SHOW PROFILE,
SHOW PROFILES, and some SQLCOM commands which aren't useful to
profile. The keep() and discard() functions can be called many
times, only the final setting when the query finishes is used
to decide whether to discard the profile.
The default is to keep the profile for all queries.
*/
inline void keep() { keeping= 1; };
inline void discard() { keeping= 0; };
void status(const char *status_arg,
const char *function_arg,
const char *file_arg, unsigned int line_arg);
/* Stash this profile in the profile history. */
void store();
/* Reset the current profile and state of profiling for the next query. */
void reset();
/* SHOW PROFILES */
bool show_profiles();
/* SHOW PROFILE FOR QUERY query_id */
bool show(uint options, uint query_id);
/* SHOW PROFILE */
bool show_last(uint options);
};
#endif /* SQL_PROFILE_H */

View file

@ -1196,7 +1196,7 @@ bool change_master(THD* thd, MASTER_INFO* mi)
if (need_relay_log_purge)
{
relay_log_purge= 1;
thd->proc_info="Purging old relay logs";
THD_PROC_INFO(thd, "Purging old relay logs");
if (purge_relay_logs(&mi->rli, thd,
0 /* not only reset, but also reinit */,
&errmsg))

View file

@ -598,6 +598,7 @@ JOIN::optimize()
if (thd->lex->orig_sql_command != SQLCOM_SHOW_STATUS)
thd->status_var.last_query_cost= 0.0;
THD_PROC_INFO(thd, "optimizing");
row_limit= ((select_distinct || order || group_list) ? HA_POS_ERROR :
unit->select_limit_cnt);
/* select_limit is used to decide if we are likely to scan the whole table */
@ -701,14 +702,14 @@ JOIN::optimize()
thd->fatal_error();
error= res;
DBUG_PRINT("error",("Error from opt_sum_query"));
DBUG_RETURN(1);
DBUG_RETURN(1);
}
if (res < 0)
{
DBUG_PRINT("info",("No matching min/max row"));
zero_result_cause= "No matching min/max row";
error=0;
DBUG_RETURN(0);
zero_result_cause= "No matching min/max row";
error=0;
DBUG_RETURN(0);
}
DBUG_PRINT("info",("Select tables optimized away"));
zero_result_cause= "Select tables optimized away";
@ -744,7 +745,7 @@ JOIN::optimize()
sort_by_table= get_sort_by_table(order, group_list, select_lex->leaf_tables);
/* Calculate how to do the join */
thd->proc_info= "statistics";
THD_PROC_INFO(thd, "statistics");
if (make_join_statistics(this, select_lex->leaf_tables, conds, &keyuse) ||
thd->is_fatal_error)
{
@ -754,7 +755,7 @@ JOIN::optimize()
/* Remove distinct if only const tables */
select_distinct= select_distinct && (const_tables != tables);
thd->proc_info= "preparing";
THD_PROC_INFO(thd, "preparing");
if (result->initialize_tables(this))
{
DBUG_PRINT("error",("Error: initialize_tables() failed"));
@ -1101,8 +1102,9 @@ JOIN::optimize()
join_tab[const_tables].type != JT_REF_OR_NULL &&
(order && simple_order || group_list && simple_group))
{
if (add_ref_to_table_cond(thd,&join_tab[const_tables]))
if (add_ref_to_table_cond(thd,&join_tab[const_tables])) {
DBUG_RETURN(1);
}
}
if (!(select_options & SELECT_BIG_RESULT) &&
@ -1160,7 +1162,7 @@ JOIN::optimize()
if (need_tmp)
{
DBUG_PRINT("info",("Creating tmp table"));
thd->proc_info="Creating tmp table";
THD_PROC_INFO(thd, "creating temporary table");
init_items_ref_array();
@ -1189,7 +1191,9 @@ JOIN::optimize()
select_options,
tmp_rows_limit,
(char *) "")))
{
DBUG_RETURN(1);
}
/*
We don't have to store rows in temp table that doesn't match HAVING if:
@ -1209,28 +1213,35 @@ JOIN::optimize()
if (group_list && simple_group)
{
DBUG_PRINT("info",("Sorting for group"));
thd->proc_info="Sorting for group";
THD_PROC_INFO(thd, "sorting for group");
if (create_sort_index(thd, this, group_list,
HA_POS_ERROR, HA_POS_ERROR) ||
alloc_group_fields(this, group_list) ||
make_sum_func_list(all_fields, fields_list, 1) ||
setup_sum_funcs(thd, sum_funcs))
DBUG_RETURN(1);
{
DBUG_RETURN(1);
}
group_list=0;
}
else
{
if (make_sum_func_list(all_fields, fields_list, 0) ||
setup_sum_funcs(thd, sum_funcs))
DBUG_RETURN(1);
{
DBUG_RETURN(1);
}
if (!group_list && ! exec_tmp_table1->distinct && order && simple_order)
{
DBUG_PRINT("info",("Sorting for order"));
thd->proc_info="Sorting for order";
if (create_sort_index(thd, this, order,
DBUG_PRINT("info",("Sorting for order"));
THD_PROC_INFO(thd, "Sorting for order");
if (create_sort_index(thd, this, order,
HA_POS_ERROR, HA_POS_ERROR))
DBUG_RETURN(1);
order=0;
{
DBUG_RETURN(1);
}
order=0;
}
}
@ -1353,6 +1364,7 @@ JOIN::exec()
int tmp_error;
DBUG_ENTER("JOIN::exec");
THD_PROC_INFO(thd, "executing");
error= 0;
if (procedure)
{
@ -1492,7 +1504,7 @@ JOIN::exec()
curr_tmp_table= exec_tmp_table1;
/* Copy data to the temporary table */
thd->proc_info= "Copying to tmp table";
THD_PROC_INFO(thd, "Copying to tmp table");
DBUG_PRINT("info", ("%s", thd->proc_info));
if ((tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table, 0)))
{
@ -1615,7 +1627,7 @@ JOIN::exec()
}
if (curr_join->group_list)
{
thd->proc_info= "Creating sort index";
THD_PROC_INFO(thd, "Creating sort index");
if (curr_join->join_tab == join_tab && save_join_tab())
{
DBUG_VOID_RETURN;
@ -1629,7 +1641,7 @@ JOIN::exec()
sortorder= curr_join->sortorder;
}
thd->proc_info="Copying to group table";
THD_PROC_INFO(thd, "Copying to group table");
DBUG_PRINT("info", ("%s", thd->proc_info));
tmp_error= -1;
if (curr_join != this)
@ -1685,7 +1697,7 @@ JOIN::exec()
curr_join->join_free(); /* Free quick selects */
if (curr_join->select_distinct && ! curr_join->group_list)
{
thd->proc_info="Removing duplicates";
THD_PROC_INFO(thd, "Removing duplicates");
if (curr_join->tmp_having)
curr_join->tmp_having->update_used_tables();
if (remove_duplicates(curr_join, curr_tmp_table,
@ -1746,7 +1758,7 @@ JOIN::exec()
if (curr_join->group_list || curr_join->order)
{
DBUG_PRINT("info",("Sorting for send_fields"));
thd->proc_info="Sorting result";
THD_PROC_INFO(thd, "Sorting result");
/* If we have already done the group, add HAVING to sorted table */
if (curr_join->tmp_having && ! curr_join->group_list &&
! curr_join->sort_and_group)
@ -1870,7 +1882,7 @@ JOIN::exec()
}
else
{
thd->proc_info="Sending data";
THD_PROC_INFO(thd, "Sending data");
DBUG_PRINT("info", ("%s", thd->proc_info));
result->send_fields((procedure ? curr_join->procedure_fields_list :
*curr_fields_list),
@ -2018,7 +2030,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
{
if (!(join= new JOIN(thd, fields, select_options, result)))
DBUG_RETURN(TRUE);
thd->proc_info="init";
THD_PROC_INFO(thd, "init");
thd->used_tables=0; // Updated by setup_fields
if (err= join->prepare(rref_pointer_array, tables, wild_num,
conds, og_num, order, group, having, proc_param,
@ -2063,8 +2075,9 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
err:
if (free_join)
{
thd->proc_info="end";
THD_PROC_INFO(thd, "cleaning up");
err|= select_lex->cleanup();
THD_PROC_INFO(thd, "end");
DBUG_RETURN(err || thd->net.report_error);
}
DBUG_RETURN(join->error);
@ -9794,7 +9807,7 @@ free_tmp_table(THD *thd, TABLE *entry)
DBUG_PRINT("enter",("table: %s",entry->alias));
save_proc_info=thd->proc_info;
thd->proc_info="removing tmp table";
THD_PROC_INFO(thd, "removing tmp table");
if (entry->file)
{
@ -9822,7 +9835,7 @@ free_tmp_table(THD *thd, TABLE *entry)
bitmap_clear_bit(&temp_pool, entry->temp_pool_slot);
free_root(&own_root, MYF(0)); /* the table is allocated in its own root */
thd->proc_info=save_proc_info;
THD_PROC_INFO(thd, save_proc_info);
DBUG_VOID_RETURN;
}
@ -9852,7 +9865,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
DBUG_RETURN(1); // End of memory
save_proc_info=thd->proc_info;
thd->proc_info="converting HEAP to MyISAM";
THD_PROC_INFO(thd, "converting HEAP to MyISAM");
if (create_myisam_tmp_table(&new_table,param,
thd->lex->select_lex.options | thd->options))
@ -9905,8 +9918,8 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
table->s= &table->share_not_to_be_used;
table->file->change_table_ptr(table);
if (save_proc_info)
thd->proc_info= (!strcmp(save_proc_info,"Copying to tmp table") ?
"Copying to tmp table on disk" : save_proc_info);
THD_PROC_INFO(thd, (!strcmp(save_proc_info,"Copying to tmp table") ?
"Copying to tmp table on disk" : save_proc_info));
DBUG_RETURN(0);
err:
@ -9918,7 +9931,7 @@ bool create_myisam_from_heap(THD *thd, TABLE *table, TMP_TABLE_PARAM *param,
new_table.file->delete_table(new_table.s->table_name);
delete new_table.file;
err2:
thd->proc_info=save_proc_info;
THD_PROC_INFO(thd, save_proc_info);
DBUG_RETURN(1);
}

View file

@ -1349,7 +1349,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
#if !defined(DONT_USE_THR_ALARM) && ! defined(SCO)
if (pthread_kill(tmp->real_id,0))
tmp->proc_info="*** DEAD ***"; // This shouldn't happen
THD_PROC_INFO(tmp, "*** DEAD ***"); // This shouldn't happen
#endif
#ifdef EXTRA_DEBUG
thd_info->start_time= tmp->time_after_lock;

View file

@ -1729,7 +1729,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
}
}
thd->proc_info="creating table";
THD_PROC_INFO(thd, "creating table");
create_info->table_existed= 0; // Mark that table is created
if (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE)
@ -1760,7 +1760,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name,
end:
VOID(pthread_mutex_unlock(&LOCK_open));
thd->proc_info="After create";
THD_PROC_INFO(thd, "After create");
DBUG_RETURN(error);
warn:
@ -2879,7 +2879,7 @@ mysql_discard_or_import_tablespace(THD *thd,
ALTER TABLE
*/
thd->proc_info="discard_or_import_tablespace";
THD_PROC_INFO(thd, "discard_or_import_tablespace");
discard= test(tablespace_op == DISCARD_TABLESPACE);
@ -2896,7 +2896,7 @@ mysql_discard_or_import_tablespace(THD *thd,
error=table->file->discard_or_import_tablespace(discard);
thd->proc_info="end";
THD_PROC_INFO(thd, "end");
if (error)
goto err;
@ -3007,7 +3007,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
frm_type_enum frm_type;
DBUG_ENTER("mysql_alter_table");
thd->proc_info="init";
THD_PROC_INFO(thd, "init");
table_name=table_list->table_name;
alias= (lower_case_table_names == 2) ? table_list->alias : table_name;
@ -3142,7 +3142,7 @@ view_err:
DBUG_RETURN(TRUE);
}
thd->proc_info="setup";
THD_PROC_INFO(thd, "setup");
if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
!table->s->tmp_table) // no need to touch frm
{
@ -3173,7 +3173,7 @@ view_err:
if (!error && (new_name != table_name || new_db != db))
{
thd->proc_info="rename";
THD_PROC_INFO(thd, "rename");
/* Then do a 'simple' rename of the table */
if (!access(new_name_buff,F_OK))
{
@ -3627,7 +3627,7 @@ view_err:
/* We don't want update TIMESTAMP fields during ALTER TABLE. */
thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
thd->cuted_fields=0L;
thd->proc_info="copy to tmp table";
THD_PROC_INFO(thd, "copy to tmp table");
next_insert_id=thd->next_insert_id; // Remember for logging
copied=deleted=0;
if (new_table && !new_table->s->is_view)
@ -3711,7 +3711,7 @@ view_err:
from the cache, free all locks, close the old table and remove it.
*/
thd->proc_info="rename result table";
THD_PROC_INFO(thd, "rename result table");
my_snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
current_pid, thd->thread_id);
if (lower_case_table_names)
@ -3822,7 +3822,7 @@ view_err:
broadcast_refresh();
goto err;
}
thd->proc_info="end";
THD_PROC_INFO(thd, "end");
if (mysql_bin_log.is_open())
{
thd->clear_error();

View file

@ -166,7 +166,7 @@ int mysql_update(THD *thd,
mysql_handle_derived(thd->lex, &mysql_derived_filling)))
DBUG_RETURN(1);
thd->proc_info="init";
THD_PROC_INFO(thd, "init");
table= table_list->table;
table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
@ -358,7 +358,7 @@ int mysql_update(THD *thd,
else
init_read_record_idx(&info, thd, table, 1, used_index);
thd->proc_info="Searching rows for update";
THD_PROC_INFO(thd, "Searching rows for update");
uint tmp_limit= limit;
while (!(error=info.read_record(&info)) && !thd->killed)
@ -423,7 +423,7 @@ int mysql_update(THD *thd,
updated= found= 0;
thd->count_cuted_fields= CHECK_FIELD_WARN; /* calc cuted fields */
thd->cuted_fields=0L;
thd->proc_info="Updating";
THD_PROC_INFO(thd, "Updating");
query_id=thd->query_id;
transactional_table= table->file->has_transactions();
@ -511,7 +511,7 @@ int mysql_update(THD *thd,
end_read_record(&info);
free_io_cache(table); // If ORDER BY
delete select;
thd->proc_info="end";
THD_PROC_INFO(thd, "end");
VOID(table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY));
/*
@ -959,7 +959,7 @@ int multi_update::prepare(List<Item> &not_used_values,
thd->count_cuted_fields= CHECK_FIELD_WARN;
thd->cuted_fields=0L;
thd->proc_info="updating main table";
THD_PROC_INFO(thd, "updating main table");
tables_to_update= get_table_map(fields);
@ -1511,11 +1511,11 @@ err2:
bool multi_update::send_eof()
{
char buff[STRING_BUFFER_USUAL_SIZE];
thd->proc_info="updating reference tables";
THD_PROC_INFO(thd, "updating reference tables");
/* Does updates for the last n - 1 tables, returns 0 if ok */
int local_error = (table_count) ? do_updates(0) : 0;
thd->proc_info= "end";
THD_PROC_INFO(thd, "end");
/* We must invalidate the query cache before binlog writing and
ha_autocommit_... */

View file

@ -588,7 +588,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views,
DBUG_RETURN(0);
err:
thd->proc_info= "end";
THD_PROC_INFO(thd, "end");
lex->link_first_table_back(view, link_to_local);
unit->cleanup();
DBUG_RETURN(res || thd->net.report_error);

View file

@ -361,6 +361,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token BIT_SYM
%token BIT_XOR
%token BLOB_SYM
%token BLOCK_SYM
%token BOOLEAN_SYM
%token BOOL_SYM
%token BOTH
@ -401,10 +402,12 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token CONSISTENT_SYM
%token CONSTRAINT
%token CONTAINS_SYM
%token CONTEXT_SYM
%token CONTINUE_SYM
%token CONVERT_SYM
%token CONVERT_TZ_SYM
%token COUNT_SYM
%token CPU_SYM
%token CREATE
%token CROSS
%token CUBE_SYM
@ -478,6 +481,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token EXTRACT_SYM
%token FALSE_SYM
%token FAST_SYM
%token FAULTS_SYM
%token FETCH_SYM
%token FIELD_FUNC
%token FILE_SYM
@ -547,6 +551,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token INT_SYM
%token INVOKER_SYM
%token IN_SYM
%token IO_SYM
%token IPC_SYM
%token IS
%token ISOLATION
%token ISSUER_SYM
@ -615,6 +621,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token MEDIUMINT
%token MEDIUMTEXT
%token MEDIUM_SYM
%token MEMORY_SYM
%token MERGE_SYM
%token MICROSECOND_SYM
%token MIGRATE_SYM
@ -673,6 +680,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token OUTFILE
%token OUT_SYM
%token PACK_KEYS_SYM
%token PAGE_SYM
%token PARTIAL
%token PASSWORD
%token PARAM_MARKER
@ -690,6 +698,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token PROCEDURE
%token PROCESS
%token PROCESSLIST_SYM
%token PROFILE_SYM
%token PROFILES_SYM
%token PURGE
%token QUARTER_SYM
%token QUERY_SYM
@ -760,6 +770,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token SMALLINT
%token SNAPSHOT_SYM
%token SOUNDS_SYM
%token SOURCE_SYM
%token SPATIAL_SYM
%token SPECIFIC_SYM
%token SQLEXCEPTION_SYM
@ -790,6 +801,8 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token SUM_SYM
%token SUPER_SYM
%token SUSPEND_SYM
%token SWAPS_SYM
%token SWITCHES_SYM
%token SYSDATE
%token TABLES
%token TABLESPACE
@ -915,7 +928,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
union_opt select_derived_init option_type2
%type <ulong_num>
ulong_num raid_types merge_insert_types
ulong_num raid_types merge_insert_types opt_profile_query_arg
%type <ulonglong_number>
ulonglong_num
@ -6655,6 +6668,48 @@ opt_table_sym:
/* empty */
| TABLE_SYM;
opt_profile_defs:
/* empty */
| profile_defs
profile_defs:
profile_def
| profile_defs ',' profile_def
profile_def:
CPU_SYM
{ Lex->profile_options|= PROFILE_CPU; }
| MEMORY_SYM
{ Lex->profile_options|= PROFILE_MEMORY; }
| BLOCK_SYM IO_SYM
{ Lex->profile_options|= PROFILE_BLOCK_IO; }
| CONTEXT_SYM SWITCHES_SYM
{ Lex->profile_options|= PROFILE_CONTEXT; }
| PAGE_SYM FAULTS_SYM
{ Lex->profile_options|= PROFILE_PAGE_FAULTS; }
| IPC_SYM
{ Lex->profile_options|= PROFILE_IPC; }
| SWAPS_SYM
{ Lex->profile_options|= PROFILE_SWAPS; }
| SOURCE_SYM
{ Lex->profile_options|= PROFILE_SOURCE; }
| ALL
{ Lex->profile_options|= PROFILE_ALL; }
;
opt_profile_query_arg:
/* empty */
{ $$= 0; }
| QUERY_SYM NUM
{ $$= atoi($2.str); }
;
opt_profile_args:
/* empty */
| FOR_SYM opt_profile_query_arg
{ Lex->profile_query_id = $2; }
;
/* Show things */
show: SHOW
@ -6790,6 +6845,10 @@ show_param:
{ Lex->sql_command = SQLCOM_SHOW_WARNS;}
| ERRORS opt_limit_clause_init
{ Lex->sql_command = SQLCOM_SHOW_ERRORS;}
| 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; }
| opt_var_type STATUS_SYM wild_and_where
{
LEX *lex= Lex;
@ -7881,6 +7940,7 @@ keyword_sp:
| BERKELEY_DB_SYM {}
| BINLOG_SYM {}
| BIT_SYM {}
| BLOCK_SYM {}
| BOOL_SYM {}
| BOOLEAN_SYM {}
| BTREE_SYM {}
@ -7897,6 +7957,8 @@ keyword_sp:
| COMPRESSED_SYM {}
| CONCURRENT {}
| CONSISTENT_SYM {}
| CONTEXT_SYM {}
| CPU_SYM {}
| CUBE_SYM {}
| DATA_SYM {}
| DATETIME {}
@ -7919,6 +7981,7 @@ keyword_sp:
| EXPANSION_SYM {}
| EXTENDED_SYM {}
| FAST_SYM {}
| FAULTS_SYM {}
| FOUND_SYM {}
| DISABLE_SYM {}
| ENABLE_SYM {}
@ -7943,6 +8006,8 @@ keyword_sp:
| ISSUER_SYM {}
| INNOBASE_SYM {}
| INSERT_METHOD {}
| IO_SYM {}
| IPC_SYM {}
| RELAY_THREAD {}
| LAST_SYM {}
| LEAVES {}
@ -7972,6 +8037,7 @@ keyword_sp:
| MAX_UPDATES_PER_HOUR {}
| MAX_USER_CONNECTIONS_SYM {}
| MEDIUM_SYM {}
| MEMORY_SYM {}
| MERGE_SYM {}
| MICROSECOND_SYM {}
| MIGRATE_SYM {}
@ -7998,6 +8064,7 @@ keyword_sp:
| ONE_SHOT_SYM {}
| ONE_SYM {}
| PACK_KEYS_SYM {}
| PAGE_SYM {}
| PARTIAL {}
| PASSWORD {}
| PHASE_SYM {}
@ -8007,6 +8074,8 @@ keyword_sp:
| PRIVILEGES {}
| PROCESS {}
| PROCESSLIST_SYM {}
| PROFILE_SYM {}
| PROFILES_SYM {}
| QUARTER_SYM {}
| QUERY_SYM {}
| QUICK {}
@ -8040,6 +8109,7 @@ keyword_sp:
| SHUTDOWN {}
| SNAPSHOT_SYM {}
| SOUNDS_SYM {}
| SOURCE_SYM {}
| SQL_CACHE_SYM {}
| SQL_BUFFER_RESULT {}
| SQL_NO_CACHE_SYM {}
@ -8051,6 +8121,8 @@ keyword_sp:
| SUBJECT_SYM {}
| SUPER_SYM {}
| SUSPEND_SYM {}
| SWAPS_SYM {}
| SWITCHES_SYM {}
| TABLES {}
| TABLESPACE {}
| TEMPORARY {}