mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
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:
commit
384b212168
34 changed files with 982 additions and 147 deletions
|
@ -29,3 +29,6 @@
|
|||
4554a95d7txO1DuO9G3nAizI3SkFAA
|
||||
4554b3722d71SbPiI2Gx-RhbZjmuIQ
|
||||
4558b3d73Cxjlb7Wv1oytdSTthxDfw
|
||||
459c03b9N_mqF2XJKK6DwSrIt7e6_g
|
||||
459c1965_BQMBzBO8S_gVqjTHYQrmw
|
||||
459c2098XoAUsUn8N07IVRDD6CTM-A
|
||||
|
|
19
configure.in
19
configure.in
|
@ -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"
|
||||
|
||||
|
|
|
@ -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 \
|
||||
|
|
30
mysql-test/r/profile.result
Normal file
30
mysql-test/r/profile.result
Normal 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
39
mysql-test/t/profile.test
Normal 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
|
|
@ -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 \
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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(¶m);
|
||||
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 ¶m, 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(¶m, 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(¶m, 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(¶m, file, fixed_name,
|
||||
param.testflag & T_QUICK);
|
||||
|
@ -708,7 +708,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, 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(¶m,file,fixed_name);
|
||||
}
|
||||
if (!statistics_done && (local_testflag & T_STATISTICS))
|
||||
|
@ -716,14 +716,14 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool optimize)
|
|||
if (share->state.changed & STATE_NOT_ANALYZED)
|
||||
{
|
||||
optimize_done=1;
|
||||
thd->proc_info="Analyzing";
|
||||
THD_PROC_INFO(thd, "Analyzing");
|
||||
error = chk_key(¶m, 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 ¶m, bool optimize)
|
|||
file->update |= HA_STATE_CHANGED | HA_STATE_ROW_CHANGED;
|
||||
update_state_info(¶m, 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(¶m);
|
||||
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
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
13
sql/lex.h
13
sql/lex.h
|
@ -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)},
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
441
sql/sql_profile.cc
Normal 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
187
sql/sql_profile.h
Normal 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 */
|
|
@ -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))
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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> ¬_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_... */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {}
|
||||
|
|
Loading…
Reference in a new issue