merged 5.0-main -> 5.0-bugteam
This commit is contained in:
commit
812d2559b5
@ -35,9 +35,25 @@
|
||||
459a70691aYIfU2ohV0a3P5iTLpO2A
|
||||
459a7422KF_P7PuU3YQ5qG6ZLEVpiA
|
||||
459a74e4nRcXppMSBYeQQ5efDkTADg
|
||||
459c03b9N_mqF2XJKK6DwSrIt7e6_g
|
||||
459c1965_BQMBzBO8S_gVqjTHYQrmw
|
||||
459c2098XoAUsUn8N07IVRDD6CTM-A
|
||||
459ea845XenN-uWqEM5LFvUT60tW_A
|
||||
45ae6628gqKTsUFfnoNExadETVIkbA
|
||||
45af88c9RIIJWPfBxs3o7zekI-ELPQ
|
||||
45ba4faf2oqu6eR8fqecR3LfSNcYUg
|
||||
45ba5238-NKl80QVXzdGo8hO9M75Xg
|
||||
45c0fdfb2mz6NdOIsLenJtf6_ZelTA
|
||||
45c38d90tNwOTSaYKHXd3ccLtnytlQ
|
||||
45c390d6BbWrwyEi5T5VsWKYxl06Rg
|
||||
45c39d31g0iik6UE_oTK5N55ry-ycA
|
||||
45d1ffcd-r3v8A7uh92hQaMfQM9UPQ
|
||||
45d21437Vg_-i4uOWyvzYWHESXDP6A
|
||||
45da6370nnZlAAIieMCrXkxF9toOyQ
|
||||
45da6551zUuplwxuqcT2fhRgceC0CQ
|
||||
45db0d4bkGtxBk21sZFJgbCV1FcNRg
|
||||
45db468b-DKE8kUTV42eYMYmk8_g9g
|
||||
45dd21d1rVPnDfvZTNVHLalcjnbsZw
|
||||
45ddaf15_Ld7IAEpUUP3FJjJ-oSEFg
|
||||
45ddc763DodLG1BqH_wRBJXMbCSB5A
|
||||
45ddc8282KnaNGuijqCTphlXV_eeog
|
||||
|
@ -1016,6 +1016,9 @@
|
||||
<File
|
||||
RelativePath="sql_prepare.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="sql_profile.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="sql_rename.cpp">
|
||||
</File>
|
||||
|
45
configure.in
45
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.82)
|
||||
AM_INIT_AUTOMAKE(mysql, 5.0.83)
|
||||
AM_CONFIG_HEADER([include/config.h:config.h.in])
|
||||
|
||||
PROTOCOL_VERSION=10
|
||||
@ -23,7 +23,7 @@ NDB_SHARED_LIB_VERSION=$NDB_SHARED_LIB_MAJOR_VERSION:0:0
|
||||
# ndb version
|
||||
NDB_VERSION_MAJOR=5
|
||||
NDB_VERSION_MINOR=0
|
||||
NDB_VERSION_BUILD=82
|
||||
NDB_VERSION_BUILD=83
|
||||
NDB_VERSION_STATUS=""
|
||||
|
||||
# Set all version vars based on $VERSION. How do we do this more elegant ?
|
||||
@ -661,7 +661,6 @@ then
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
AC_ARG_WITH(server-suffix,
|
||||
[ --with-server-suffix Append value to the version string.],
|
||||
[ MYSQL_SERVER_SUFFIX=`echo "$withval" | sed -e 's/^\(...................................\)..*$/\1/'` ],
|
||||
@ -724,6 +723,45 @@ else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
AC_MSG_CHECKING(whether features provided by the user community should be included.)
|
||||
AC_ARG_ENABLE(community-features,
|
||||
AC_HELP_STRING(
|
||||
[--enable-community-features],
|
||||
[Enable additional features provided by the user community.]),
|
||||
[ ENABLE_COMMUNITY_FEATURES=$enableval ],
|
||||
[ ENABLE_COMMUNITY_FEATURES=no ]
|
||||
)
|
||||
|
||||
if test "$ENABLE_COMMUNITY_FEATURES" = "yes"
|
||||
then
|
||||
AC_DEFINE([COMMUNITY_SERVER], [1],
|
||||
[Whether features provided by the user community should be included])
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
# Add query profiler
|
||||
AC_MSG_CHECKING(whether query profiling should be included)
|
||||
AC_ARG_ENABLE(profiling,
|
||||
AS_HELP_STRING([--enable-profiling], [Add query-profiling code.]),
|
||||
[ ENABLED_PROFILING=$enableval ],
|
||||
[ ENABLED_PROFILING=no ])
|
||||
|
||||
if test "$ENABLED_PROFILING" = "yes"
|
||||
then
|
||||
if test "$ENABLE_COMMUNITY_FEATURES" = "yes";
|
||||
then
|
||||
AC_DEFINE([ENABLED_PROFILING], [1], [If SHOW PROFILE should be enabled])
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
ENABLED_PROFILING="no"
|
||||
AC_MSG_RESULT([no, overridden because community-features disabled])
|
||||
AC_MSG_ERROR([This is almost certainly wrong. Add --enable-community-features or remove --enable-profiling .])
|
||||
fi
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
fi
|
||||
|
||||
# Use this to set the place used for unix socket used to local communication.
|
||||
AC_ARG_WITH(unix-socket-path,
|
||||
@ -1177,7 +1215,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"
|
||||
|
@ -45,7 +45,7 @@ extern "C" {
|
||||
#undef HAVE_SYS_MMAN_H
|
||||
#undef HAVE_SYNCH_H
|
||||
#undef HAVE_MMAP
|
||||
#undef HAVE_RINT
|
||||
#undef HAVE_FESETROUND
|
||||
|
||||
#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
|
||||
#define HAVE_PTHREAD_SIGMASK 1
|
||||
|
@ -206,6 +206,10 @@ typedef uint rf_SetTimer;
|
||||
/* If LOAD DATA LOCAL INFILE should be enabled by default */
|
||||
#define ENABLED_LOCAL_INFILE 1
|
||||
|
||||
/* If query profiling should be enabled by default */
|
||||
#define ENABLED_PROFILING 1
|
||||
#define COMMUNITY_SERVER 1
|
||||
|
||||
/* Convert some simple functions to Posix */
|
||||
|
||||
#define my_sigset(A,B) signal((A),(B))
|
||||
|
@ -162,6 +162,7 @@ extern char *my_strdup_with_length(const char *from, size_t length,
|
||||
#define ORIG_CALLER_INFO /* nothing */
|
||||
#define TRASH(A,B) /* nothing */
|
||||
#endif
|
||||
#define my_strndup(A,B,C) my_strdup_with_length((A), (B), (C))
|
||||
|
||||
#ifdef HAVE_LARGE_PAGES
|
||||
extern uint my_get_large_page_size(void);
|
||||
|
@ -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 \
|
||||
|
4
mysql-test/include/have_community_features.inc
Normal file
4
mysql-test/include/have_community_features.inc
Normal file
@ -0,0 +1,4 @@
|
||||
--require r/have_community_features.require
|
||||
--disable_query_log
|
||||
show variables like 'have_community_features';
|
||||
--enable_query_log
|
4
mysql-test/include/have_profiling.inc
Normal file
4
mysql-test/include/have_profiling.inc
Normal file
@ -0,0 +1,4 @@
|
||||
--require r/have_profiling.require
|
||||
--disable_query_log
|
||||
show variables like 'have_profiling';
|
||||
--enable_query_log
|
2
mysql-test/r/have_community_features.require
Normal file
2
mysql-test/r/have_community_features.require
Normal file
@ -0,0 +1,2 @@
|
||||
Variable_name Value
|
||||
have_community_features YES
|
2
mysql-test/r/have_profiling.require
Normal file
2
mysql-test/r/have_profiling.require
Normal file
@ -0,0 +1,2 @@
|
||||
Variable_name Value
|
||||
have_profiling YES
|
@ -42,6 +42,7 @@ COLLATION_CHARACTER_SET_APPLICABILITY
|
||||
COLUMNS
|
||||
COLUMN_PRIVILEGES
|
||||
KEY_COLUMN_USAGE
|
||||
PROFILING
|
||||
ROUTINES
|
||||
SCHEMATA
|
||||
SCHEMA_PRIVILEGES
|
||||
@ -729,7 +730,7 @@ CREATE TABLE t_crashme ( f1 BIGINT);
|
||||
CREATE VIEW a1 (t_CRASHME) AS SELECT f1 FROM t_crashme GROUP BY f1;
|
||||
CREATE VIEW a2 AS SELECT t_CRASHME FROM a1;
|
||||
count(*)
|
||||
101
|
||||
102
|
||||
drop view a2, a1;
|
||||
drop table t_crashme;
|
||||
select table_schema,table_name, column_name from
|
||||
@ -800,7 +801,7 @@ delete from mysql.db where user='mysqltest_4';
|
||||
flush privileges;
|
||||
SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA;
|
||||
table_schema count(*)
|
||||
information_schema 16
|
||||
information_schema 17
|
||||
mysql 17
|
||||
create table t1 (i int, j int);
|
||||
create trigger trg1 before insert on t1 for each row
|
||||
@ -1093,7 +1094,7 @@ table_schema='information_schema' and
|
||||
(column_type = 'varchar(7)' or column_type = 'varchar(20)')
|
||||
group by column_type order by num;
|
||||
column_type group_concat(table_schema, '.', table_name) num
|
||||
varchar(20) information_schema.COLUMNS 1
|
||||
varchar(20) information_schema.COLUMNS,information_schema.PROFILING 2
|
||||
varchar(7) information_schema.ROUTINES,information_schema.VIEWS 2
|
||||
create table t1(f1 char(1) not null, f2 char(9) not null)
|
||||
default character set utf8;
|
||||
@ -1191,6 +1192,7 @@ COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
|
||||
COLUMNS TABLE_SCHEMA
|
||||
COLUMN_PRIVILEGES TABLE_SCHEMA
|
||||
KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
|
||||
PROFILING QUERY_ID
|
||||
ROUTINES ROUTINE_SCHEMA
|
||||
SCHEMATA SCHEMA_NAME
|
||||
SCHEMA_PRIVILEGES TABLE_SCHEMA
|
||||
@ -1222,6 +1224,7 @@ COLLATION_CHARACTER_SET_APPLICABILITY COLLATION_NAME
|
||||
COLUMNS TABLE_SCHEMA
|
||||
COLUMN_PRIVILEGES TABLE_SCHEMA
|
||||
KEY_COLUMN_USAGE CONSTRAINT_SCHEMA
|
||||
PROFILING QUERY_ID
|
||||
ROUTINES ROUTINE_SCHEMA
|
||||
SCHEMATA SCHEMA_NAME
|
||||
SCHEMA_PRIVILEGES TABLE_SCHEMA
|
||||
@ -1304,6 +1307,7 @@ COLLATION_CHARACTER_SET_APPLICABILITY information_schema.COLLATION_CHARACTER_SET
|
||||
COLUMNS information_schema.COLUMNS 1
|
||||
COLUMN_PRIVILEGES information_schema.COLUMN_PRIVILEGES 1
|
||||
KEY_COLUMN_USAGE information_schema.KEY_COLUMN_USAGE 1
|
||||
PROFILING information_schema.PROFILING 1
|
||||
ROUTINES information_schema.ROUTINES 1
|
||||
SCHEMATA information_schema.SCHEMATA 1
|
||||
SCHEMA_PRIVILEGES information_schema.SCHEMA_PRIVILEGES 1
|
||||
|
8
mysql-test/r/information_schema_community.result
Normal file
8
mysql-test/r/information_schema_community.result
Normal file
@ -0,0 +1,8 @@
|
||||
show global status like "Uptime_%";
|
||||
Variable_name Value
|
||||
Uptime_since_flush_status #
|
||||
flush status;
|
||||
show global status like "Uptime_%";
|
||||
Variable_name Value
|
||||
Uptime_since_flush_status #
|
||||
End of 5.0 tests.
|
@ -11,6 +11,7 @@ COLLATION_CHARACTER_SET_APPLICABILITY
|
||||
COLUMNS
|
||||
COLUMN_PRIVILEGES
|
||||
KEY_COLUMN_USAGE
|
||||
PROFILING
|
||||
ROUTINES
|
||||
SCHEMATA
|
||||
SCHEMA_PRIVILEGES
|
||||
|
@ -85,6 +85,7 @@ Database: information_schema
|
||||
| COLUMNS |
|
||||
| COLUMN_PRIVILEGES |
|
||||
| KEY_COLUMN_USAGE |
|
||||
| PROFILING |
|
||||
| ROUTINES |
|
||||
| SCHEMATA |
|
||||
| SCHEMA_PRIVILEGES |
|
||||
@ -106,6 +107,7 @@ Database: INFORMATION_SCHEMA
|
||||
| COLUMNS |
|
||||
| COLUMN_PRIVILEGES |
|
||||
| KEY_COLUMN_USAGE |
|
||||
| PROFILING |
|
||||
| ROUTINES |
|
||||
| SCHEMATA |
|
||||
| SCHEMA_PRIVILEGES |
|
||||
|
415
mysql-test/r/profiling.result
Normal file
415
mysql-test/r/profiling.result
Normal file
@ -0,0 +1,415 @@
|
||||
show profiles;
|
||||
Query_ID Duration Query
|
||||
show profile all;
|
||||
Status Duration CPU_user CPU_system Context_voluntary Context_involuntary Block_ops_in Block_ops_out Messages_sent Messages_received Page_faults_major Page_faults_minor Swaps Source_function Source_file Source_line
|
||||
show session variables like 'profil%';
|
||||
Variable_name Value
|
||||
profiling OFF
|
||||
profiling_history_size 15
|
||||
select @@profiling;
|
||||
@@profiling
|
||||
0
|
||||
set global profiling = ON;
|
||||
ERROR HY000: Variable 'profiling' is a SESSION variable and can't be used with SET GLOBAL
|
||||
set global profiling_history_size=100;
|
||||
show global variables like 'profil%';
|
||||
Variable_name Value
|
||||
profiling OFF
|
||||
profiling_history_size 100
|
||||
set session profiling = ON;
|
||||
set session profiling_history_size=30;
|
||||
show session variables like 'profil%';
|
||||
Variable_name Value
|
||||
profiling ON
|
||||
profiling_history_size 30
|
||||
select @@profiling;
|
||||
@@profiling
|
||||
1
|
||||
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);
|
||||
select max(x) from (select sum(a) as x from t1 group by b) as teeone;
|
||||
max(x)
|
||||
20
|
||||
insert into t1 select * from t1;
|
||||
select count(*) from t1;
|
||||
count(*)
|
||||
24
|
||||
insert into t1 select * from t1;
|
||||
insert into t1 select * from t1;
|
||||
insert into t1 select * from t1;
|
||||
select count(*) from t1;
|
||||
count(*)
|
||||
192
|
||||
insert into t1 select * from t1;
|
||||
insert into t1 select * from t1;
|
||||
insert into t1 select * from t1;
|
||||
select count(*) from t1;
|
||||
count(*)
|
||||
1536
|
||||
select sum(a) from t1;
|
||||
sum(a)
|
||||
6144
|
||||
select sum(a) from t1 group by b;
|
||||
sum(a)
|
||||
2048
|
||||
1536
|
||||
2560
|
||||
select sum(a) + sum(b) from t1 group by b;
|
||||
sum(a) + sum(b)
|
||||
NULL
|
||||
2048
|
||||
4608
|
||||
select max(x) from (select sum(a) as x from t1 group by b) as teeone;
|
||||
max(x)
|
||||
2560
|
||||
select '012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890' as big_string;
|
||||
big_string
|
||||
012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890
|
||||
show profiles;
|
||||
Query_ID Duration Query
|
||||
1 # set session profiling_history_size=30
|
||||
2 # show session variables like 'profil%'
|
||||
3 # select @@profiling
|
||||
4 # create table t1 (
|
||||
a int,
|
||||
b int
|
||||
)
|
||||
5 # insert into t1 values (1,1), (2,null), (3, 4)
|
||||
6 # insert into t1 values (5,1), (6,null), (7, 4)
|
||||
7 # insert into t1 values (1,1), (2,null), (3, 4)
|
||||
8 # insert into t1 values (5,1), (6,null), (7, 4)
|
||||
9 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
|
||||
10 # insert into t1 select * from t1
|
||||
11 # select count(*) from t1
|
||||
12 # insert into t1 select * from t1
|
||||
13 # insert into t1 select * from t1
|
||||
14 # insert into t1 select * from t1
|
||||
15 # select count(*) from t1
|
||||
16 # insert into t1 select * from t1
|
||||
17 # insert into t1 select * from t1
|
||||
18 # insert into t1 select * from t1
|
||||
19 # select count(*) from t1
|
||||
20 # select sum(a) from t1
|
||||
21 # select sum(a) from t1 group by b
|
||||
22 # select sum(a) + sum(b) from t1 group by b
|
||||
23 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
|
||||
24 # select '0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345
|
||||
show profile for query 15;
|
||||
show profile cpu for query 15;
|
||||
show profile cpu, block io for query 15;
|
||||
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;
|
||||
show profile all for query 15;
|
||||
select * from information_schema.profiling;
|
||||
select query_id, state, duration from information_schema.profiling;
|
||||
select query_id, sum(duration) from information_schema.profiling group by query_id;
|
||||
select query_id, count(*) from information_schema.profiling group by query_id;
|
||||
select sum(duration) from information_schema.profiling;
|
||||
select query_id, count(*), sum(duration) from information_schema.profiling group by query_id;
|
||||
select CPU_user, CPU_system, Context_voluntary, Context_involuntary, Block_ops_in, Block_ops_out, Messages_sent, Messages_received, Page_faults_major, Page_faults_minor, Swaps, Source_function, Source_file, Source_line from information_schema.profiling;
|
||||
drop table if exists t1, t2, t3;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't2'
|
||||
Note 1051 Unknown table 't3'
|
||||
create table t1 (id int );
|
||||
create table t2 (id int not null);
|
||||
create table t3 (id int not null primary key);
|
||||
insert into t1 values (1), (2), (3);
|
||||
insert into t2 values (1), (2), (3);
|
||||
insert into t3 values (1), (2), (3);
|
||||
show profiles;
|
||||
Query_ID Duration Query
|
||||
10 # insert into t1 select * from t1
|
||||
11 # select count(*) from t1
|
||||
12 # insert into t1 select * from t1
|
||||
13 # insert into t1 select * from t1
|
||||
14 # insert into t1 select * from t1
|
||||
15 # select count(*) from t1
|
||||
16 # insert into t1 select * from t1
|
||||
17 # insert into t1 select * from t1
|
||||
18 # insert into t1 select * from t1
|
||||
19 # select count(*) from t1
|
||||
20 # select sum(a) from t1
|
||||
21 # select sum(a) from t1 group by b
|
||||
22 # select sum(a) + sum(b) from t1 group by b
|
||||
23 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
|
||||
24 # select '0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345
|
||||
25 # select * from information_schema.profiling
|
||||
26 # select query_id, state, duration from information_schema.profiling
|
||||
27 # select query_id, sum(duration) from information_schema.profiling group by query_id
|
||||
28 # select query_id, count(*) from information_schema.profiling group by query_id
|
||||
29 # select sum(duration) from information_schema.profiling
|
||||
30 # select query_id, count(*), sum(duration) from information_schema.profiling group by query_id
|
||||
31 # select CPU_user, CPU_system, Context_voluntary, Context_involuntary, Block_ops_in, Block_ops_out, Messages_sent, Messages_received, Page_faults_major, Page_faults_minor, Swaps, Source_function, Source_file, Source_line from information_schema.profiling
|
||||
32 # drop table if exists t1, t2, t3
|
||||
33 # SHOW WARNINGS
|
||||
34 # create table t1 (id int )
|
||||
35 # create table t2 (id int not null)
|
||||
36 # create table t3 (id int not null primary key)
|
||||
37 # insert into t1 values (1), (2), (3)
|
||||
38 # insert into t2 values (1), (2), (3)
|
||||
39 # insert into t3 values (1), (2), (3)
|
||||
select * from t1;
|
||||
id
|
||||
1
|
||||
2
|
||||
3
|
||||
show profiles;
|
||||
Query_ID Duration Query
|
||||
11 # select count(*) from t1
|
||||
12 # insert into t1 select * from t1
|
||||
13 # insert into t1 select * from t1
|
||||
14 # insert into t1 select * from t1
|
||||
15 # select count(*) from t1
|
||||
16 # insert into t1 select * from t1
|
||||
17 # insert into t1 select * from t1
|
||||
18 # insert into t1 select * from t1
|
||||
19 # select count(*) from t1
|
||||
20 # select sum(a) from t1
|
||||
21 # select sum(a) from t1 group by b
|
||||
22 # select sum(a) + sum(b) from t1 group by b
|
||||
23 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
|
||||
24 # select '0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345
|
||||
25 # select * from information_schema.profiling
|
||||
26 # select query_id, state, duration from information_schema.profiling
|
||||
27 # select query_id, sum(duration) from information_schema.profiling group by query_id
|
||||
28 # select query_id, count(*) from information_schema.profiling group by query_id
|
||||
29 # select sum(duration) from information_schema.profiling
|
||||
30 # select query_id, count(*), sum(duration) from information_schema.profiling group by query_id
|
||||
31 # select CPU_user, CPU_system, Context_voluntary, Context_involuntary, Block_ops_in, Block_ops_out, Messages_sent, Messages_received, Page_faults_major, Page_faults_minor, Swaps, Source_function, Source_file, Source_line from information_schema.profiling
|
||||
32 # drop table if exists t1, t2, t3
|
||||
33 # SHOW WARNINGS
|
||||
34 # create table t1 (id int )
|
||||
35 # create table t2 (id int not null)
|
||||
36 # create table t3 (id int not null primary key)
|
||||
37 # insert into t1 values (1), (2), (3)
|
||||
38 # insert into t2 values (1), (2), (3)
|
||||
39 # insert into t3 values (1), (2), (3)
|
||||
40 # select * from t1
|
||||
This ^^ should end in "select * from t1;"
|
||||
delete from t1;
|
||||
insert into t1 values (1), (2), (3);
|
||||
insert into t1 values (1), (2), (3);
|
||||
select * from t1;
|
||||
id
|
||||
1
|
||||
2
|
||||
3
|
||||
1
|
||||
2
|
||||
3
|
||||
show profiles;
|
||||
Query_ID Duration Query
|
||||
15 # select count(*) from t1
|
||||
16 # insert into t1 select * from t1
|
||||
17 # insert into t1 select * from t1
|
||||
18 # insert into t1 select * from t1
|
||||
19 # select count(*) from t1
|
||||
20 # select sum(a) from t1
|
||||
21 # select sum(a) from t1 group by b
|
||||
22 # select sum(a) + sum(b) from t1 group by b
|
||||
23 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
|
||||
24 # select '0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345
|
||||
25 # select * from information_schema.profiling
|
||||
26 # select query_id, state, duration from information_schema.profiling
|
||||
27 # select query_id, sum(duration) from information_schema.profiling group by query_id
|
||||
28 # select query_id, count(*) from information_schema.profiling group by query_id
|
||||
29 # select sum(duration) from information_schema.profiling
|
||||
30 # select query_id, count(*), sum(duration) from information_schema.profiling group by query_id
|
||||
31 # select CPU_user, CPU_system, Context_voluntary, Context_involuntary, Block_ops_in, Block_ops_out, Messages_sent, Messages_received, Page_faults_major, Page_faults_minor, Swaps, Source_function, Source_file, Source_line from information_schema.profiling
|
||||
32 # drop table if exists t1, t2, t3
|
||||
33 # SHOW WARNINGS
|
||||
34 # create table t1 (id int )
|
||||
35 # create table t2 (id int not null)
|
||||
36 # create table t3 (id int not null primary key)
|
||||
37 # insert into t1 values (1), (2), (3)
|
||||
38 # insert into t2 values (1), (2), (3)
|
||||
39 # insert into t3 values (1), (2), (3)
|
||||
40 # select * from t1
|
||||
41 # delete from t1
|
||||
42 # insert into t1 values (1), (2), (3)
|
||||
43 # insert into t1 values (1), (2), (3)
|
||||
44 # select * from t1
|
||||
set session profiling = OFF;
|
||||
select sum(id) from t1;
|
||||
sum(id)
|
||||
12
|
||||
show profiles;
|
||||
Query_ID Duration Query
|
||||
15 # select count(*) from t1
|
||||
16 # insert into t1 select * from t1
|
||||
17 # insert into t1 select * from t1
|
||||
18 # insert into t1 select * from t1
|
||||
19 # select count(*) from t1
|
||||
20 # select sum(a) from t1
|
||||
21 # select sum(a) from t1 group by b
|
||||
22 # select sum(a) + sum(b) from t1 group by b
|
||||
23 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
|
||||
24 # select '0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345
|
||||
25 # select * from information_schema.profiling
|
||||
26 # select query_id, state, duration from information_schema.profiling
|
||||
27 # select query_id, sum(duration) from information_schema.profiling group by query_id
|
||||
28 # select query_id, count(*) from information_schema.profiling group by query_id
|
||||
29 # select sum(duration) from information_schema.profiling
|
||||
30 # select query_id, count(*), sum(duration) from information_schema.profiling group by query_id
|
||||
31 # select CPU_user, CPU_system, Context_voluntary, Context_involuntary, Block_ops_in, Block_ops_out, Messages_sent, Messages_received, Page_faults_major, Page_faults_minor, Swaps, Source_function, Source_file, Source_line from information_schema.profiling
|
||||
32 # drop table if exists t1, t2, t3
|
||||
33 # SHOW WARNINGS
|
||||
34 # create table t1 (id int )
|
||||
35 # create table t2 (id int not null)
|
||||
36 # create table t3 (id int not null primary key)
|
||||
37 # insert into t1 values (1), (2), (3)
|
||||
38 # insert into t2 values (1), (2), (3)
|
||||
39 # insert into t3 values (1), (2), (3)
|
||||
40 # select * from t1
|
||||
41 # delete from t1
|
||||
42 # insert into t1 values (1), (2), (3)
|
||||
43 # insert into t1 values (1), (2), (3)
|
||||
44 # select * from t1
|
||||
set session profiling = ON;
|
||||
select @@profiling;
|
||||
@@profiling
|
||||
1
|
||||
create function f1() returns varchar(50) return 'hello';
|
||||
select @@profiling;
|
||||
@@profiling
|
||||
1
|
||||
select * from t1 where id <> f1();
|
||||
id
|
||||
1
|
||||
2
|
||||
3
|
||||
1
|
||||
2
|
||||
3
|
||||
select @@profiling;
|
||||
@@profiling
|
||||
1
|
||||
set session profiling = OFF;
|
||||
drop table if exists profile_log;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 'profile_log'
|
||||
create table profile_log (how_many int);
|
||||
drop procedure if exists p1;
|
||||
drop procedure if exists p2;
|
||||
drop procedure if exists p3;
|
||||
create procedure p1 ()
|
||||
modifies sql data
|
||||
begin
|
||||
set profiling = ON;
|
||||
select 'This p1 should show up in profiling';
|
||||
insert into profile_log select count(*) from information_schema.profiling;
|
||||
end//
|
||||
create procedure p2()
|
||||
deterministic
|
||||
begin
|
||||
set profiling = ON;
|
||||
call p1();
|
||||
select 'This p2 should show up in profiling';
|
||||
end//
|
||||
create procedure p3 ()
|
||||
reads sql data
|
||||
begin
|
||||
set profiling = ON;
|
||||
select 'This p3 should show up in profiling';
|
||||
show profile;
|
||||
end//
|
||||
first call to p1
|
||||
call p1;
|
||||
select * from profile_log;
|
||||
second call to p1
|
||||
call p1;
|
||||
select * from profile_log;
|
||||
third call to p1
|
||||
call p1;
|
||||
select * from profile_log;
|
||||
set session profiling = OFF;
|
||||
call p2;
|
||||
set session profiling = OFF;
|
||||
call p3;
|
||||
show profiles;
|
||||
drop procedure if exists p1;
|
||||
drop procedure if exists p2;
|
||||
drop procedure if exists p3;
|
||||
drop table if exists profile_log;
|
||||
set session profiling = ON;
|
||||
drop table if exists t2;
|
||||
create table t2 (id int not null);
|
||||
create trigger t2_bi before insert on t2 for each row set @x=0;
|
||||
select @@profiling;
|
||||
@@profiling
|
||||
1
|
||||
insert into t2 values (1), (2), (3);
|
||||
select @@profiling;
|
||||
@@profiling
|
||||
1
|
||||
set session profiling = ON;
|
||||
drop table if exists t1, t2;
|
||||
create table t1 (id int not null primary key);
|
||||
create table t2 (id int not null primary key, id1 int not null);
|
||||
select @@profiling;
|
||||
@@profiling
|
||||
1
|
||||
alter table t2 add foreign key (id1) references t1 (id) on delete cascade;
|
||||
select @@profiling;
|
||||
@@profiling
|
||||
1
|
||||
lock table t1 write;
|
||||
select @@profiling;
|
||||
@@profiling
|
||||
1
|
||||
unlock table;
|
||||
select @@profiling;
|
||||
@@profiling
|
||||
1
|
||||
set autocommit=0;
|
||||
select @@profiling, @@autocommit;
|
||||
@@profiling @@autocommit
|
||||
1 0
|
||||
begin;
|
||||
select @@profiling;
|
||||
@@profiling
|
||||
1
|
||||
insert into t1 values (1);
|
||||
insert into t2 values (1,1);
|
||||
testing referential integrity cascade
|
||||
delete from t1 where id = 1;
|
||||
select @@profiling;
|
||||
@@profiling
|
||||
1
|
||||
testing rollback
|
||||
rollback;
|
||||
select @@profiling;
|
||||
@@profiling
|
||||
1
|
||||
testing commit
|
||||
begin;
|
||||
select @@profiling;
|
||||
@@profiling
|
||||
1
|
||||
commit;
|
||||
select @@profiling;
|
||||
@@profiling
|
||||
1
|
||||
drop table if exists t1, t2, t3;
|
||||
drop view if exists v1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 'test.v1'
|
||||
drop function if exists f1;
|
||||
set session profiling = OFF;
|
||||
End of 5.0 tests
|
@ -4407,7 +4407,7 @@ pk a
|
||||
3 30
|
||||
2 20
|
||||
DROP TABLE t1,t2;
|
||||
CREATE TABLE t1 (s1 CHAR(1));
|
||||
CREATE TABLE t1 (s1 char(1));
|
||||
INSERT INTO t1 VALUES ('a');
|
||||
SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1);
|
||||
s1
|
||||
|
@ -1029,6 +1029,7 @@ where t.table_schema = 'information_schema' and
|
||||
group by c2.column_type order by num limit 1)
|
||||
group by t.table_name order by num1, t.table_name;
|
||||
|
||||
|
||||
#
|
||||
# Bug#28266 IS_UPDATABLE field on VIEWS table in I_S database is wrong
|
||||
#
|
||||
|
13
mysql-test/t/information_schema_community.test
Normal file
13
mysql-test/t/information_schema_community.test
Normal file
@ -0,0 +1,13 @@
|
||||
-- source include/have_community_features.inc
|
||||
|
||||
#
|
||||
# Bug#24822: Patch: uptime_since_flush_status
|
||||
#
|
||||
--replace_column 2 #
|
||||
show global status like "Uptime_%";
|
||||
flush status;
|
||||
--replace_column 2 #
|
||||
show global status like "Uptime_%"; # Almost certainly zero
|
||||
|
||||
--echo End of 5.0 tests.
|
||||
|
@ -50,7 +50,7 @@ create view v_bug25347 as select * from t_bug25347;
|
||||
flush tables;
|
||||
--echo removing and creating
|
||||
--remove_file $MYSQLTEST_VARDIR/master-data/d_bug25347/t_bug25347.MYI
|
||||
--write_file $MYSQLTEST_VARDIR/master-data/d_bug25347/t_bug25347.MYI
|
||||
--write_file $MYSQLTEST_VARDIR/master-data/d_bug25347/t_bug25347.MYI
|
||||
EOF
|
||||
--exec $MYSQL_CHECK --repair --databases --use-frm d_bug25347
|
||||
drop view v_bug25347;
|
||||
|
266
mysql-test/t/profiling.test
Normal file
266
mysql-test/t/profiling.test
Normal file
@ -0,0 +1,266 @@
|
||||
--source include/have_profiling.inc
|
||||
|
||||
# Verify that the protocol isn't violated if we ask for profiling info
|
||||
# before profiling has recorded anything.
|
||||
show profiles;
|
||||
show profile all;
|
||||
|
||||
# default is OFF
|
||||
show session variables like 'profil%';
|
||||
select @@profiling;
|
||||
|
||||
# setting global variable is an error
|
||||
--error ER_LOCAL_VARIABLE
|
||||
set global profiling = ON;
|
||||
|
||||
# But size is okay
|
||||
set global profiling_history_size=100;
|
||||
show global variables like 'profil%';
|
||||
|
||||
# turn on for testing
|
||||
set session profiling = ON;
|
||||
set session profiling_history_size=30; # small enough to overflow
|
||||
|
||||
# verify it is active
|
||||
show session variables like 'profil%';
|
||||
select @@profiling;
|
||||
|
||||
# Profiling is a descriptive look into the way the server operated
|
||||
# in retrospect. Chad doesn't think it's wise to include the result
|
||||
# log, as this creates a proscriptive specification about how the
|
||||
# server should work in the future -- or it forces everyone who
|
||||
# changes the server significantly to record the test results again,
|
||||
# and that violates the spirit of our tests. Please don't include
|
||||
# execution-specific data here, as in all of the "show profile" and
|
||||
# information_schema.profiling results.
|
||||
|
||||
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);
|
||||
select max(x) from (select sum(a) as x from t1 group by b) as teeone;
|
||||
insert into t1 select * from t1;
|
||||
select count(*) from t1;
|
||||
insert into t1 select * from t1;
|
||||
insert into t1 select * from t1;
|
||||
insert into t1 select * from t1;
|
||||
select count(*) from t1;
|
||||
insert into t1 select * from t1;
|
||||
insert into t1 select * from t1;
|
||||
insert into t1 select * from t1;
|
||||
select count(*) from t1;
|
||||
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;
|
||||
select '012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890' as big_string;
|
||||
|
||||
--enable_result_log
|
||||
--replace_column 2 #
|
||||
show profiles;
|
||||
|
||||
--disable_result_log
|
||||
###--replace_column 2 # 3 # 4 #
|
||||
show profile for query 15;
|
||||
###--replace_column 2 # 3 # 4 #
|
||||
show profile cpu for query 15;
|
||||
###--replace_column 2 # 3 # 4 # 5 # 6 #
|
||||
show profile cpu, block io for query 15;
|
||||
###--replace_column 2 # 3 # 4 #
|
||||
show profile cpu for query 9 limit 2 offset 2;
|
||||
show profile cpu for query 10 limit 0;
|
||||
--error 0,ER_WRONG_ARGUMENTS
|
||||
show profile cpu for query 65534;
|
||||
###--replace_column 2 #
|
||||
show profile memory;
|
||||
###--replace_column 2 # 3 # 4 #
|
||||
show profile block io;
|
||||
###--replace_column 2 # 3 # 4 #
|
||||
show profile context switches;
|
||||
###--replace_column 2 # 3 # 4 #
|
||||
show profile page faults;
|
||||
###--replace_column 2 # 3 # 4 #
|
||||
show profile ipc;
|
||||
###--replace_column 2 #
|
||||
show profile swaps limit 1 offset 2;
|
||||
###--replace_column 2 # 5 #
|
||||
show profile source;
|
||||
show profile all for query 0 limit 0;
|
||||
###--replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 11 # 12 # 13 # 16 #
|
||||
show profile all for query 15;
|
||||
###--replace_column 2 # 3 # 4 # 5 # 6 # 7 # 8 # 9 # 10 # 11 # 12 # 13 # 16 #
|
||||
|
||||
select * from information_schema.profiling;
|
||||
select query_id, state, duration from information_schema.profiling;
|
||||
select query_id, sum(duration) from information_schema.profiling group by query_id;
|
||||
select query_id, count(*) from information_schema.profiling group by query_id;
|
||||
select sum(duration) from information_schema.profiling;
|
||||
|
||||
# Broken down into number of stages and duration of each query.
|
||||
select query_id, count(*), sum(duration) from information_schema.profiling group by query_id;
|
||||
select CPU_user, CPU_system, Context_voluntary, Context_involuntary, Block_ops_in, Block_ops_out, Messages_sent, Messages_received, Page_faults_major, Page_faults_minor, Swaps, Source_function, Source_file, Source_line from information_schema.profiling;
|
||||
|
||||
|
||||
--enable_result_log
|
||||
drop table if exists t1, t2, t3;
|
||||
create table t1 (id int );
|
||||
create table t2 (id int not null);
|
||||
create table t3 (id int not null primary key);
|
||||
insert into t1 values (1), (2), (3);
|
||||
insert into t2 values (1), (2), (3);
|
||||
insert into t3 values (1), (2), (3);
|
||||
|
||||
--replace_column 2 #
|
||||
show profiles;
|
||||
|
||||
select * from t1;
|
||||
--replace_column 2 #
|
||||
show profiles;
|
||||
--echo This ^^ should end in "select * from t1;"
|
||||
|
||||
delete from t1;
|
||||
insert into t1 values (1), (2), (3);
|
||||
insert into t1 values (1), (2), (3);
|
||||
|
||||
select * from t1;
|
||||
--replace_column 2 #
|
||||
show profiles;
|
||||
|
||||
# Turning profiling off does freeze it
|
||||
set session profiling = OFF;
|
||||
select sum(id) from t1;
|
||||
--replace_column 2 #
|
||||
show profiles;
|
||||
|
||||
## Verify that the various juggling of THD contexts doesn't affect profiling.
|
||||
|
||||
## Functions and procedures
|
||||
set session profiling = ON;
|
||||
select @@profiling;
|
||||
create function f1() returns varchar(50) return 'hello';
|
||||
select @@profiling;
|
||||
select * from t1 where id <> f1();
|
||||
select @@profiling;
|
||||
|
||||
set session profiling = OFF;
|
||||
drop table if exists profile_log;
|
||||
create table profile_log (how_many int);
|
||||
|
||||
--disable_warnings
|
||||
drop procedure if exists p1;
|
||||
drop procedure if exists p2;
|
||||
drop procedure if exists p3;
|
||||
--enable_warnings
|
||||
|
||||
delimiter //;
|
||||
create procedure p1 ()
|
||||
modifies sql data
|
||||
begin
|
||||
set profiling = ON;
|
||||
select 'This p1 should show up in profiling';
|
||||
insert into profile_log select count(*) from information_schema.profiling;
|
||||
end//
|
||||
create procedure p2()
|
||||
deterministic
|
||||
begin
|
||||
set profiling = ON;
|
||||
call p1();
|
||||
select 'This p2 should show up in profiling';
|
||||
end//
|
||||
create procedure p3 ()
|
||||
reads sql data
|
||||
begin
|
||||
set profiling = ON;
|
||||
select 'This p3 should show up in profiling';
|
||||
show profile;
|
||||
end//
|
||||
delimiter ;//
|
||||
|
||||
--disable_result_log
|
||||
--echo first call to p1
|
||||
call p1;
|
||||
select * from profile_log;
|
||||
--echo second call to p1
|
||||
call p1;
|
||||
select * from profile_log;
|
||||
--echo third call to p1
|
||||
call p1;
|
||||
select * from profile_log;
|
||||
set session profiling = OFF;
|
||||
call p2;
|
||||
set session profiling = OFF;
|
||||
call p3;
|
||||
|
||||
--replace_column 1 # 2 #
|
||||
show profiles;
|
||||
--enable_result_log
|
||||
|
||||
drop procedure if exists p1;
|
||||
drop procedure if exists p2;
|
||||
drop procedure if exists p3;
|
||||
drop table if exists profile_log;
|
||||
|
||||
## Triggers
|
||||
set session profiling = ON;
|
||||
drop table if exists t2;
|
||||
create table t2 (id int not null);
|
||||
create trigger t2_bi before insert on t2 for each row set @x=0;
|
||||
select @@profiling;
|
||||
insert into t2 values (1), (2), (3);
|
||||
select @@profiling;
|
||||
|
||||
## ALTER TABLE
|
||||
set session profiling = ON;
|
||||
drop table if exists t1, t2;
|
||||
create table t1 (id int not null primary key);
|
||||
create table t2 (id int not null primary key, id1 int not null);
|
||||
select @@profiling;
|
||||
alter table t2 add foreign key (id1) references t1 (id) on delete cascade;
|
||||
select @@profiling;
|
||||
|
||||
## Table LOCKing
|
||||
lock table t1 write;
|
||||
select @@profiling;
|
||||
unlock table;
|
||||
select @@profiling;
|
||||
|
||||
## Transactions
|
||||
set autocommit=0;
|
||||
select @@profiling, @@autocommit;
|
||||
begin;
|
||||
select @@profiling;
|
||||
insert into t1 values (1);
|
||||
insert into t2 values (1,1);
|
||||
--echo testing referential integrity cascade
|
||||
delete from t1 where id = 1;
|
||||
select @@profiling;
|
||||
--echo testing rollback
|
||||
--disable_warnings
|
||||
rollback;
|
||||
--enable_warnings
|
||||
select @@profiling;
|
||||
--echo testing commit
|
||||
begin;
|
||||
select @@profiling;
|
||||
commit;
|
||||
select @@profiling;
|
||||
|
||||
drop table if exists t1, t2, t3;
|
||||
drop view if exists v1;
|
||||
drop function if exists f1;
|
||||
|
||||
## Multiple queries in one packet. Combo statements don't work with ps-proto.
|
||||
#--eval select 1; select 2; select 3;
|
||||
## two continuations, one starting
|
||||
#select state from information_schema.profiling where seq=1 order by query_id desc limit 3;
|
||||
|
||||
|
||||
## last thing in the file
|
||||
set session profiling = OFF;
|
||||
|
||||
##
|
||||
--echo End of 5.0 tests
|
@ -3375,16 +3375,14 @@ SELECT * FROM t1
|
||||
WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b);
|
||||
DROP TABLE t1,t2;
|
||||
|
||||
|
||||
#
|
||||
# Bug#20835 (literal string with =any values)
|
||||
#
|
||||
CREATE TABLE t1 (s1 CHAR(1));
|
||||
CREATE TABLE t1 (s1 char(1));
|
||||
INSERT INTO t1 VALUES ('a');
|
||||
SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1);
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
#
|
||||
# Bug#40519 Subselect query using bigint fails
|
||||
#
|
||||
@ -3395,7 +3393,6 @@ INSERT INTO t2 VALUES (2,1),(3,1);
|
||||
SELECT * FROM t1 i WHERE 1 IN (SELECT l.id2 FROM t2 l WHERE i.id=l.id1);
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
|
||||
#
|
||||
# Bug#37460 Assertion failed:
|
||||
# !table->file || table->file->inited == handler::NONE
|
||||
@ -3409,13 +3406,13 @@ INSERT INTO t1 (id) VALUES (1);
|
||||
INSERT INTO t2 (id) VALUES (1);
|
||||
|
||||
CREATE VIEW v1 AS
|
||||
SELECT t2.c AS c FROM t1, t2
|
||||
WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
|
||||
SELECT t2.c AS c FROM t1, t2
|
||||
WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
|
||||
UPDATE v1 SET c=1;
|
||||
|
||||
CREATE VIEW v2 (a,b) AS
|
||||
SELECT t2.id, t2.c AS c FROM t1, t2
|
||||
WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
|
||||
SELECT t2.id, t2.c AS c FROM t1, t2
|
||||
WHERE t1.id=t2.id AND 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
|
||||
|
||||
--error ER_VIEW_CHECK_FAILED
|
||||
INSERT INTO v2(a,b) VALUES (2,2);
|
||||
@ -3423,8 +3420,8 @@ INSERT INTO v2(a,b) VALUES (1,2);
|
||||
SELECT * FROM v1;
|
||||
|
||||
CREATE VIEW v3 AS
|
||||
SELECT t2.c AS c FROM t2
|
||||
WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
|
||||
SELECT t2.c AS c FROM t2
|
||||
WHERE 1 IN (SELECT id FROM t1) WITH CHECK OPTION;
|
||||
|
||||
DELETE FROM v3;
|
||||
|
||||
|
@ -126,7 +126,7 @@ if [ -e $DESTDIR ] ; then
|
||||
usage
|
||||
fi
|
||||
|
||||
trap 'echo "Clearning up and exiting..." ; rm -fr $DESTDIR; exit 1' ERR
|
||||
trap 'echo "Cleaning up and exiting..." ; rm -fr $DESTDIR; exit 1' ERR
|
||||
|
||||
# ----------------------------------------------------------------------
|
||||
# Adjust target name if needed, release with debug info has another name
|
||||
|
@ -73,6 +73,7 @@ ADD_EXECUTABLE(mysqld${MYSQLD_EXE_SUFFIX}
|
||||
time.cc tztime.cc uniques.cc unireg.cc
|
||||
../sql-common/my_user.c
|
||||
sql_locale.cc
|
||||
sql_profile.cc
|
||||
${PROJECT_SOURCE_DIR}/sql/sql_yacc.cc
|
||||
${PROJECT_SOURCE_DIR}/sql/sql_yacc.h
|
||||
${PROJECT_SOURCE_DIR}/include/mysqld_error.h
|
||||
|
@ -52,6 +52,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 ha_ndbcluster_cond.h \
|
||||
@ -81,6 +82,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 \
|
||||
|
@ -1209,7 +1209,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);
|
||||
|
||||
@ -1221,7 +1221,7 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt)
|
||||
while (!(rc= get_row(archive, table->record[0])))
|
||||
count--;
|
||||
|
||||
thd->proc_info= old_proc_info;
|
||||
thd_proc_info(thd, old_proc_info);
|
||||
|
||||
if ((rc && rc != HA_ERR_END_OF_FILE) || count)
|
||||
{
|
||||
|
@ -1865,8 +1865,8 @@ int ha_berkeley::external_lock(THD *thd, int lock_type)
|
||||
OPTION_TABLE_LOCK)) && !trx->all)
|
||||
{
|
||||
/* We have to start a master transaction */
|
||||
DBUG_PRINT("trans",("starting transaction all: options: 0x%lx",
|
||||
(ulong) thd->options));
|
||||
DBUG_PRINT("trans",("starting transaction all: options: 0x%llx",
|
||||
thd->options));
|
||||
if ((error=txn_begin(db_env, 0, &trx->all, 0)))
|
||||
{
|
||||
trx->bdb_lock_count--; // We didn't get the lock
|
||||
|
@ -681,7 +681,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";
|
||||
@ -755,7 +755,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;
|
||||
}
|
||||
|
||||
@ -1037,22 +1037,22 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_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);
|
||||
@ -1066,7 +1066,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_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))
|
||||
@ -1074,14 +1074,14 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_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))
|
||||
@ -1119,7 +1119,7 @@ int ha_myisam::repair(THD *thd, MI_CHECK ¶m, bool do_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 :
|
||||
@ -1335,7 +1335,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 |
|
||||
@ -1360,7 +1360,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
|
||||
{
|
||||
|
@ -3414,7 +3414,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;
|
||||
|
||||
@ -3439,7 +3439,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);
|
||||
@ -3526,7 +3526,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;
|
||||
|
||||
@ -3569,7 +3569,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 (sql_lock->table_count && lock_external(thd, sql_lock->table,
|
||||
sql_lock->table_count))
|
||||
{
|
||||
@ -160,7 +160,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,
|
||||
@ -203,7 +203,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);
|
||||
@ -218,7 +218,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();
|
||||
|
@ -4604,7 +4604,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,
|
||||
@ -4658,7 +4658,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) */
|
||||
@ -4778,7 +4778,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
|
||||
@ -4812,7 +4812,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
|
||||
|
@ -199,6 +199,8 @@ MY_LOCALE *my_locale_by_number(uint number);
|
||||
#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
|
||||
@ -376,6 +378,8 @@ MY_LOCALE *my_locale_by_number(uint number);
|
||||
fulltext functions when reading from it.
|
||||
*/
|
||||
#define TMP_TABLE_FORCE_MYISAM (ULL(1) << 32)
|
||||
#define OPTION_PROFILING (ULL(1) << 33)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
@ -515,6 +519,8 @@ enum enum_parsing_place
|
||||
struct st_table;
|
||||
class THD;
|
||||
|
||||
#define thd_proc_info(thd, msg) set_thd_proc_info(thd, msg, __func__, __FILE__, __LINE__)
|
||||
|
||||
/* Struct to handle simple linked lists */
|
||||
|
||||
typedef struct st_sql_list {
|
||||
@ -586,6 +592,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
|
||||
@ -598,6 +606,16 @@ typedef Comp_creator* (*chooser_compare_func_creator)(bool invert);
|
||||
#include "item.h"
|
||||
extern my_decimal decimal_zero;
|
||||
|
||||
/**
|
||||
The meat of thd_proc_info(THD*, char*), a macro that packs the last
|
||||
three calling-info parameters.
|
||||
*/
|
||||
extern "C"
|
||||
const char *set_thd_proc_info(THD *thd, const char *info,
|
||||
const char *calling_func,
|
||||
const char *calling_file,
|
||||
const unsigned int calling_line);
|
||||
|
||||
/* sql_parse.cc */
|
||||
void free_items(Item *item);
|
||||
void cleanup_items(Item *item);
|
||||
@ -999,6 +1017,8 @@ bool get_schema_tables_result(JOIN *join,
|
||||
enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table);
|
||||
bool schema_table_store_record(THD *thd, TABLE *table);
|
||||
|
||||
bool schema_table_store_record(THD *thd, TABLE *table);
|
||||
|
||||
#define is_schema_db(X) \
|
||||
!my_strcasecmp(system_charset_info, INFORMATION_SCHEMA_NAME.str, (X))
|
||||
|
||||
@ -1281,7 +1301,7 @@ void my_dbopt_free(void);
|
||||
External variables
|
||||
*/
|
||||
|
||||
extern time_t server_start_time;
|
||||
extern time_t server_start_time, flush_status_time;
|
||||
extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH],
|
||||
mysql_real_data_home[], *opt_mysql_tmpdir, mysql_charsets_dir[],
|
||||
mysql_unpacked_real_data_home[],
|
||||
@ -1471,6 +1491,8 @@ extern SHOW_COMP_OPTION have_query_cache;
|
||||
extern SHOW_COMP_OPTION have_geometry, have_rtree_keys;
|
||||
extern SHOW_COMP_OPTION have_crypt;
|
||||
extern SHOW_COMP_OPTION have_compress;
|
||||
extern SHOW_COMP_OPTION have_community_features;
|
||||
extern SHOW_COMP_OPTION have_profiling;
|
||||
|
||||
#ifndef __WIN__
|
||||
extern pthread_t signal_thread;
|
||||
|
@ -472,7 +472,7 @@ ulong slow_launch_threads = 0, sync_binlog_period;
|
||||
ulong expire_logs_days = 0;
|
||||
ulong rpl_recovery_rank=0;
|
||||
|
||||
time_t server_start_time;
|
||||
time_t server_start_time, flush_status_time;
|
||||
|
||||
char mysql_home[FN_REFLEN], pidfile_name[FN_REFLEN], system_time_zone[30];
|
||||
char *default_tz_name;
|
||||
@ -538,6 +538,8 @@ SHOW_COMP_OPTION have_isam;
|
||||
SHOW_COMP_OPTION have_raid, have_ssl, have_symlink, have_query_cache;
|
||||
SHOW_COMP_OPTION have_geometry, have_rtree_keys, have_dlopen;
|
||||
SHOW_COMP_OPTION have_crypt, have_compress;
|
||||
SHOW_COMP_OPTION have_community_features;
|
||||
SHOW_COMP_OPTION have_profiling;
|
||||
|
||||
/* Thread specific variables */
|
||||
|
||||
@ -2832,7 +2834,7 @@ static int init_common_variables(const char *conf_file_name, int argc,
|
||||
tzset(); // Set tzname
|
||||
|
||||
max_system_variables.pseudo_thread_id= (ulong)~0;
|
||||
server_start_time= time((time_t*) 0);
|
||||
server_start_time= flush_status_time= time((time_t*) 0);
|
||||
if (init_thread_environment())
|
||||
return 1;
|
||||
mysql_init_variables();
|
||||
@ -5040,6 +5042,7 @@ enum options_mysqld
|
||||
OPT_PLUGIN_DIR,
|
||||
OPT_PORT_OPEN_TIMEOUT,
|
||||
OPT_MERGE,
|
||||
OPT_PROFILING,
|
||||
OPT_INNODB_ROLLBACK_ON_TIMEOUT,
|
||||
OPT_SECURE_FILE_PRIV,
|
||||
OPT_KEEP_FILES_ON_CREATE,
|
||||
@ -5646,6 +5649,12 @@ Disable with --skip-ndbcluster (will save memory).",
|
||||
"Maximum time in seconds to wait for the port to become free. "
|
||||
"(Default: no wait)", (gptr*) &mysqld_port_timeout,
|
||||
(gptr*) &mysqld_port_timeout, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
{"profiling_history_size", OPT_PROFILING, "Limit of query profiling memory",
|
||||
(gptr*) &global_system_variables.profiling_history_size,
|
||||
(gptr*) &max_system_variables.profiling_history_size,
|
||||
0, GET_ULONG, REQUIRED_ARG, 15, 0, 100, 0, 0, 0},
|
||||
#endif
|
||||
{"relay-log", OPT_RELAY_LOG,
|
||||
"The location and name to use for relay logs.",
|
||||
(gptr*) &opt_relay_logname, (gptr*) &opt_relay_logname, 0,
|
||||
@ -6687,6 +6696,9 @@ struct show_var_st status_vars[]= {
|
||||
{"Threads_created", (char*) &thread_created, SHOW_LONG_CONST},
|
||||
{"Threads_running", (char*) &thread_running, SHOW_INT_CONST},
|
||||
{"Uptime", (char*) 0, SHOW_STARTTIME},
|
||||
#ifdef COMMUNITY_SERVER
|
||||
{"Uptime_since_flush_status",(char*) 0, SHOW_FLUSHTIME},
|
||||
#endif
|
||||
{NullS, NullS, SHOW_LONG}
|
||||
};
|
||||
|
||||
@ -6993,6 +7005,16 @@ static void mysql_init_variables(void)
|
||||
#if !defined(my_pthread_setprio) && !defined(HAVE_PTHREAD_SETSCHEDPARAM)
|
||||
opt_specialflag |= SPECIAL_NO_PRIOR;
|
||||
#endif
|
||||
#ifdef ENABLED_PROFILING
|
||||
have_profiling = SHOW_OPTION_YES;
|
||||
#else
|
||||
have_profiling = SHOW_OPTION_NO;
|
||||
#endif
|
||||
#ifdef COMMUNITY_SERVER
|
||||
have_community_features = SHOW_OPTION_YES;
|
||||
#else
|
||||
have_community_features = SHOW_OPTION_NO;
|
||||
#endif
|
||||
|
||||
#if defined(__WIN__) || defined(__NETWARE__)
|
||||
/* Allow Win32 and NetWare users to move MySQL anywhere */
|
||||
@ -8017,6 +8039,9 @@ void refresh_status(THD *thd)
|
||||
|
||||
/* Reset the counters of all key caches (default and named). */
|
||||
process_key_caches(reset_key_cache_counters);
|
||||
#ifdef COMMUNITY_SERVER
|
||||
flush_status_time= time((time_t*) 0);
|
||||
#endif
|
||||
pthread_mutex_unlock(&LOCK_status);
|
||||
|
||||
/*
|
||||
|
@ -92,7 +92,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);
|
||||
@ -603,7 +603,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) {
|
||||
@ -947,7 +947,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))
|
||||
@ -974,7 +974,7 @@ bool load_master_data(THD* thd)
|
||||
flush_relay_log_info(&active_mi->rli);
|
||||
pthread_cond_broadcast(&active_mi->rli.data_cond);
|
||||
pthread_mutex_unlock(&active_mi->rli.data_lock);
|
||||
thd->proc_info = "starting slave";
|
||||
thd_proc_info(thd, "starting slave");
|
||||
if (restart_thread_mask)
|
||||
{
|
||||
error=start_slave_threads(0 /* mutex not needed */,
|
||||
@ -986,7 +986,7 @@ bool load_master_data(THD* thd)
|
||||
err:
|
||||
unlock_slave_threads(active_mi);
|
||||
pthread_mutex_unlock(&LOCK_active_mi);
|
||||
thd->proc_info = 0;
|
||||
thd_proc_info(thd, 0);
|
||||
|
||||
mysql_close(&mysql); // safe to call since we always do mysql_init()
|
||||
if (!error)
|
||||
|
@ -567,6 +567,12 @@ static sys_var_thd_bit sys_unique_checks("unique_checks", 0,
|
||||
set_option_bit,
|
||||
OPTION_RELAXED_UNIQUE_CHECKS,
|
||||
1);
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
static sys_var_thd_bit sys_profiling("profiling", NULL, set_option_bit,
|
||||
ulonglong(OPTION_PROFILING));
|
||||
static sys_var_thd_ulong sys_profiling_history_size("profiling_history_size",
|
||||
&SV::profiling_history_size);
|
||||
#endif
|
||||
|
||||
/* Local state variables */
|
||||
|
||||
@ -730,6 +736,10 @@ sys_var *sys_variables[]=
|
||||
&sys_optimizer_prune_level,
|
||||
&sys_optimizer_search_depth,
|
||||
&sys_preload_buff_size,
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
&sys_profiling,
|
||||
&sys_profiling_history_size,
|
||||
#endif
|
||||
&sys_pseudo_thread_id,
|
||||
&sys_query_alloc_block_size,
|
||||
&sys_query_cache_size,
|
||||
@ -893,6 +903,8 @@ struct show_var_st init_vars[]= {
|
||||
{"have_bdb", (char*) &have_berkeley_db, SHOW_HAVE},
|
||||
{"have_blackhole_engine", (char*) &have_blackhole_db, SHOW_HAVE},
|
||||
{"have_compress", (char*) &have_compress, SHOW_HAVE},
|
||||
{"have_community_features", (char*) &have_community_features, SHOW_HAVE},
|
||||
{"have_profiling", (char*) &have_profiling, SHOW_HAVE},
|
||||
{"have_crypt", (char*) &have_crypt, SHOW_HAVE},
|
||||
{"have_csv", (char*) &have_csv_db, SHOW_HAVE},
|
||||
{"have_dynamic_loading", (char*) &have_dlopen, SHOW_HAVE},
|
||||
@ -1048,6 +1060,10 @@ struct show_var_st init_vars[]= {
|
||||
{sys_plugin_dir.name, (char*) &sys_plugin_dir, SHOW_SYS},
|
||||
{"port", (char*) &mysqld_port, SHOW_INT},
|
||||
{sys_preload_buff_size.name, (char*) &sys_preload_buff_size, SHOW_SYS},
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
{sys_profiling.name, (char*) &sys_profiling, SHOW_SYS},
|
||||
{sys_profiling_history_size.name, (char*) &sys_profiling_history_size, SHOW_SYS},
|
||||
#endif
|
||||
{"protocol_version", (char*) &protocol_version, SHOW_INT},
|
||||
{sys_query_alloc_block_size.name, (char*) &sys_query_alloc_block_size,
|
||||
SHOW_SYS},
|
||||
@ -3027,7 +3043,7 @@ static bool set_option_autocommit(THD *thd, set_var *var)
|
||||
if ((org_options & OPTION_NOT_AUTOCOMMIT))
|
||||
{
|
||||
/* We changed to auto_commit mode */
|
||||
thd->options&= ~(ulong) OPTION_BEGIN;
|
||||
thd->options&= ~OPTION_BEGIN;
|
||||
thd->transaction.all.modified_non_trans_table= FALSE;
|
||||
thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
|
||||
if (ha_commit(thd))
|
||||
|
40
sql/slave.cc
40
sql/slave.cc
@ -1625,8 +1625,8 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
|
||||
|
||||
/* Create the table. We do not want to log the "create table" statement */
|
||||
save_options = thd->options;
|
||||
thd->options &= ~(ulong) (OPTION_BIN_LOG);
|
||||
thd->proc_info = "Creating table from master dump";
|
||||
thd->options &= ~ (OPTION_BIN_LOG);
|
||||
thd_proc_info(thd, "Creating table from master dump");
|
||||
// save old db in case we are creating in a different database
|
||||
save_db = thd->db;
|
||||
save_db_length= thd->db_length;
|
||||
@ -1640,7 +1640,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
|
||||
if (thd->query_error)
|
||||
goto err; // mysql_parse took care of the error send
|
||||
|
||||
thd->proc_info = "Opening master dump table";
|
||||
thd_proc_info(thd, "Opening master dump table");
|
||||
tables.lock_type = TL_WRITE;
|
||||
if (!open_ltable(thd, &tables, TL_WRITE))
|
||||
{
|
||||
@ -1649,7 +1649,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
|
||||
}
|
||||
|
||||
file = tables.table->file;
|
||||
thd->proc_info = "Reading master dump table data";
|
||||
thd_proc_info(thd, "Reading master dump table data");
|
||||
/* Copy the data file */
|
||||
if (file->net_read_dump(net))
|
||||
{
|
||||
@ -1661,7 +1661,7 @@ static int create_table_from_dump(THD* thd, MYSQL *mysql, const char* db,
|
||||
|
||||
check_opt.init();
|
||||
check_opt.flags|= T_VERY_SILENT | T_CALC_CHECKSUM | T_QUICK;
|
||||
thd->proc_info = "Rebuilding the index on master dump table";
|
||||
thd_proc_info(thd, "Rebuilding the index on master dump table");
|
||||
/*
|
||||
We do not want repair() to spam us with messages
|
||||
just send them to the error log, and report the failure in case of
|
||||
@ -3002,9 +3002,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);
|
||||
@ -3622,7 +3622,7 @@ slave_begin:
|
||||
goto err;
|
||||
}
|
||||
|
||||
thd->proc_info = "Connecting to master";
|
||||
thd_proc_info(thd, "Connecting to master");
|
||||
// we can get killed during safe_connect
|
||||
if (!safe_connect(thd, mysql, mi))
|
||||
{
|
||||
@ -3649,7 +3649,7 @@ connected:
|
||||
// TODO: the assignment below should be under mutex (5.0)
|
||||
mi->slave_running= MYSQL_SLAVE_RUN_CONNECT;
|
||||
thd->slave_net = &mysql->net;
|
||||
thd->proc_info = "Checking master version";
|
||||
thd_proc_info(thd, "Checking master version");
|
||||
if (get_master_version_and_clock(mysql, mi))
|
||||
goto err;
|
||||
|
||||
@ -3660,7 +3660,7 @@ connected:
|
||||
If fails, this is not fatal - we just print the error message and go
|
||||
on with life.
|
||||
*/
|
||||
thd->proc_info = "Registering slave on master";
|
||||
thd_proc_info(thd, "Registering slave on master");
|
||||
if (register_slave_on_master(mysql))
|
||||
goto err;
|
||||
}
|
||||
@ -3669,7 +3669,7 @@ connected:
|
||||
while (!io_slave_killed(thd,mi))
|
||||
{
|
||||
bool suppress_warnings= 0;
|
||||
thd->proc_info = "Requesting binlog dump";
|
||||
thd_proc_info(thd, "Requesting binlog dump");
|
||||
if (request_dump(mysql, mi, &suppress_warnings))
|
||||
{
|
||||
sql_print_error("Failed on request_dump()");
|
||||
@ -3681,7 +3681,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
|
||||
@ -3705,7 +3705,7 @@ dump");
|
||||
goto err;
|
||||
}
|
||||
|
||||
thd->proc_info = "Reconnecting after a failed binlog dump request";
|
||||
thd_proc_info(thd, "Reconnecting after a failed binlog dump request");
|
||||
if (!suppress_warnings)
|
||||
sql_print_error("Slave I/O thread: failed dump request, \
|
||||
reconnecting to try again, log '%s' at postion %s", IO_RPL_LOG_NAME,
|
||||
@ -3732,7 +3732,7 @@ after reconnect");
|
||||
important thing is to not confuse users by saying "reading" whereas
|
||||
we're in fact receiving nothing.
|
||||
*/
|
||||
thd->proc_info= "Waiting for master to send event";
|
||||
thd_proc_info(thd, "Waiting for master to send event");
|
||||
event_len= read_event(mysql, mi, &suppress_warnings);
|
||||
if (io_slave_killed(thd,mi))
|
||||
{
|
||||
@ -3763,7 +3763,7 @@ Stopping slave I/O thread due to out-of-memory error from master");
|
||||
goto err;
|
||||
}
|
||||
mi->slave_running= MYSQL_SLAVE_RUN_NOT_CONNECT;
|
||||
thd->proc_info = "Waiting to reconnect after a failed master event read";
|
||||
thd_proc_info(thd, "Waiting to reconnect after a failed master event read");
|
||||
#ifdef SIGNAL_WITH_VIO_CLOSE
|
||||
thd->clear_active_vio();
|
||||
#endif
|
||||
@ -3782,7 +3782,7 @@ Stopping slave I/O thread due to out-of-memory error from master");
|
||||
reconnect after a failed read");
|
||||
goto err;
|
||||
}
|
||||
thd->proc_info = "Reconnecting after a failed master event read";
|
||||
thd_proc_info(thd, "Reconnecting after a failed master event read");
|
||||
if (!suppress_warnings)
|
||||
sql_print_information("Slave I/O thread: Failed reading log event, \
|
||||
reconnecting to retry, log '%s' position %s", IO_RPL_LOG_NAME,
|
||||
@ -3799,7 +3799,7 @@ reconnect done to recover from failed read");
|
||||
} // if (event_len == packet_error)
|
||||
|
||||
retry_count=0; // ok event, reset retry counter
|
||||
thd->proc_info = "Queueing master event to the relay log";
|
||||
thd_proc_info(thd, "Queueing master event to the relay log");
|
||||
if (queue_event(mi,(const char*)mysql->net.read_pos + 1,
|
||||
event_len))
|
||||
{
|
||||
@ -3881,7 +3881,7 @@ err:
|
||||
mi->mysql=0;
|
||||
}
|
||||
write_ignored_events_info_to_relay_log(thd, mi);
|
||||
thd->proc_info = "Waiting for slave mutex on exit";
|
||||
thd_proc_info(thd, "Waiting for slave mutex on exit");
|
||||
pthread_mutex_lock(&mi->run_lock);
|
||||
|
||||
/* Forget the relay log's format */
|
||||
@ -4075,7 +4075,7 @@ Slave SQL thread aborted. Can't execute init_slave query");
|
||||
|
||||
while (!sql_slave_killed(thd,rli))
|
||||
{
|
||||
thd->proc_info = "Reading event from the relay log";
|
||||
thd_proc_info(thd, "Reading event from the relay log");
|
||||
DBUG_ASSERT(rli->sql_thd == thd);
|
||||
THD_CHECK_SENTRY(thd);
|
||||
if (exec_relay_log_event(thd,rli))
|
||||
@ -4107,7 +4107,7 @@ the slave SQL thread with \"SLAVE START\". We stopped at log \
|
||||
thd->query= 0;
|
||||
thd->query_length= 0;
|
||||
VOID(pthread_mutex_unlock(&LOCK_thread_count));
|
||||
thd->proc_info = "Waiting for slave mutex on exit";
|
||||
thd_proc_info(thd, "Waiting for slave mutex on exit");
|
||||
pthread_mutex_lock(&rli->run_lock);
|
||||
/* We need data_lock, at least to wake up any waiting master_pos_wait() */
|
||||
pthread_mutex_lock(&rli->data_lock);
|
||||
|
@ -1103,15 +1103,36 @@ sp_head::execute(THD *thd)
|
||||
*/
|
||||
thd->spcont->callers_arena= &backup_arena;
|
||||
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
/* Discard the initial part of executing routines. */
|
||||
thd->profiling.discard_current_query();
|
||||
#endif
|
||||
do
|
||||
{
|
||||
sp_instr *i;
|
||||
uint hip; // Handler ip
|
||||
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
/*
|
||||
Treat each "instr" of a routine as discrete unit that could be profiled.
|
||||
Profiling only records information for segments of code that set the
|
||||
source of the query, and almost all kinds of instructions in s-p do not.
|
||||
*/
|
||||
thd->profiling.finish_current_query();
|
||||
thd->profiling.start_new_query("continuing inside routine");
|
||||
#endif
|
||||
|
||||
i = get_instr(ip); // Returns NULL when we're done.
|
||||
if (i == NULL)
|
||||
{
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
thd->profiling.discard_current_query();
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
DBUG_PRINT("execute", ("Instruction %u", ip));
|
||||
|
||||
/* Don't change NOW() in FUNCTION or TRIGGER */
|
||||
if (!thd->in_sub_stmt)
|
||||
thd->set_time(); // Make current_time() et al work
|
||||
@ -1188,6 +1209,10 @@ sp_head::execute(THD *thd)
|
||||
}
|
||||
} while (!err_status && !thd->killed);
|
||||
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
thd->profiling.finish_current_query();
|
||||
thd->profiling.start_new_query("tail end of routine");
|
||||
#endif
|
||||
thd->restore_active_arena(&execute_arena, &backup_arena);
|
||||
|
||||
thd->spcont->pop_all_cursors(); // To avoid memory leaks after an error
|
||||
@ -2520,9 +2545,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)
|
||||
{
|
||||
@ -2610,6 +2635,10 @@ sp_instr_stmt::execute(THD *thd, uint *nextp)
|
||||
|
||||
query= thd->query;
|
||||
query_length= thd->query_length;
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
/* This s-p instr is profilable and will be captured. */
|
||||
thd->profiling.set_query_source(m_query.str, m_query.length);
|
||||
#endif
|
||||
if (!(res= alloc_query(thd, m_query.str, m_query.length+1)) &&
|
||||
!(res=subst_spvars(thd, this, &m_query)))
|
||||
{
|
||||
|
@ -360,7 +360,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,
|
||||
@ -416,7 +416,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);
|
||||
@ -609,7 +609,7 @@ void close_thread_tables(THD *thd, bool lock_in_use, bool skip_derived)
|
||||
good idea to turn off OPTION_TABLE_LOCK flag.
|
||||
*/
|
||||
DBUG_ASSERT(thd->lex->requires_prelocking());
|
||||
thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
|
||||
thd->options&= ~(OPTION_TABLE_LOCK);
|
||||
}
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
@ -1202,7 +1202,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);
|
||||
|
||||
@ -1210,7 +1210,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;
|
||||
}
|
||||
@ -2314,7 +2314,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)
|
||||
{
|
||||
@ -2330,12 +2330,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);
|
||||
}
|
||||
|
||||
@ -2637,7 +2637,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
|
||||
@ -2865,7 +2865,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)
|
||||
@ -2939,7 +2939,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;
|
||||
@ -2966,7 +2966,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);
|
||||
}
|
||||
|
||||
@ -3186,7 +3186,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
|
||||
{
|
||||
if (thd->lex->requires_prelocking())
|
||||
{
|
||||
thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
|
||||
thd->options&= ~(OPTION_TABLE_LOCK);
|
||||
thd->in_lock_tables=0;
|
||||
}
|
||||
DBUG_RETURN(-1);
|
||||
@ -3219,7 +3219,7 @@ int lock_tables(THD *thd, TABLE_LIST *tables, uint count, bool *need_reopen)
|
||||
ha_rollback_stmt(thd);
|
||||
mysql_unlock_tables(thd, thd->locked_tables);
|
||||
thd->locked_tables= 0;
|
||||
thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
|
||||
thd->options&= ~(OPTION_TABLE_LOCK);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
}
|
||||
@ -6228,7 +6228,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);
|
||||
|
@ -706,6 +706,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)
|
||||
@ -724,6 +725,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
|
||||
@ -772,6 +774,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();
|
||||
@ -1194,6 +1197,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);
|
||||
@ -1277,6 +1282,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
|
||||
}
|
||||
|
||||
// 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++)
|
||||
@ -1369,6 +1375,7 @@ def_week_frmt: %lu, in_trans: %d, autocommit: %d",
|
||||
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)",
|
||||
@ -1446,9 +1453,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)
|
||||
{
|
||||
@ -1479,9 +1488,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)
|
||||
{
|
||||
@ -1531,6 +1542,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
|
||||
|
@ -165,6 +165,20 @@ Open_tables_state::Open_tables_state(ulong version_arg)
|
||||
reset_open_tables_state();
|
||||
}
|
||||
|
||||
extern "C"
|
||||
const char *set_thd_proc_info(THD *thd, const char *info,
|
||||
const char *calling_function,
|
||||
const char *calling_file,
|
||||
const unsigned int calling_line)
|
||||
{
|
||||
const char *old_info= thd->proc_info;
|
||||
DBUG_PRINT("proc_info", ("%s:%d %s", calling_file, calling_line, info));
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
thd->profiling.status_change(info, calling_function, calling_file, calling_line);
|
||||
#endif
|
||||
thd->proc_info= info;
|
||||
return old_info;
|
||||
}
|
||||
|
||||
|
||||
THD::THD()
|
||||
@ -258,6 +272,9 @@ THD::THD()
|
||||
init();
|
||||
/* Initialize sub structures */
|
||||
init_sql_alloc(&warn_root, WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE);
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
profiling.set_thd(this);
|
||||
#endif
|
||||
user_connect=(USER_CONN *)0;
|
||||
hash_init(&user_vars, system_charset_info, USER_VARS_HASH_SIZE, 0, 0,
|
||||
(hash_get_key) get_var_key,
|
||||
|
@ -547,6 +547,7 @@ struct system_variables
|
||||
ulong optimizer_prune_level;
|
||||
ulong optimizer_search_depth;
|
||||
ulong preload_buff_size;
|
||||
ulong profiling_history_size;
|
||||
ulong query_cache_type;
|
||||
ulong read_buff_size;
|
||||
ulong read_rnd_buff_size;
|
||||
@ -1258,6 +1259,9 @@ public:
|
||||
Points to info-string that we show in SHOW PROCESSLIST
|
||||
You are supposed to update thd->proc_info only if you have coded
|
||||
a time-consuming piece that MySQL can get stuck in for a long time.
|
||||
|
||||
Set it using the thd_proc_info(THD *thread, const char *message)
|
||||
macro/function.
|
||||
*/
|
||||
const char *proc_info;
|
||||
|
||||
@ -1430,6 +1434,10 @@ public:
|
||||
List <MYSQL_ERROR> warn_list;
|
||||
uint warn_count[(uint) MYSQL_ERROR::WARN_LEVEL_END];
|
||||
uint total_warn_count;
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
PROFILING profiling;
|
||||
#endif
|
||||
|
||||
/*
|
||||
Id of current query. Statement can be reused to execute several queries
|
||||
query_id is global in context of the whole MySQL server.
|
||||
|
@ -56,7 +56,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))
|
||||
@ -220,7 +220,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 (triggers_applicable)
|
||||
{
|
||||
@ -288,7 +288,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
|
||||
}
|
||||
killed_status= thd->killed;
|
||||
error= (killed_status == THD::NOT_KILLED)? error : 1;
|
||||
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)
|
||||
@ -527,7 +527,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);
|
||||
}
|
||||
|
||||
@ -841,7 +841,7 @@ int multi_delete::do_deletes()
|
||||
bool multi_delete::send_eof()
|
||||
{
|
||||
THD::killed_state killed_status= THD::NOT_KILLED;
|
||||
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
|
||||
@ -850,7 +850,7 @@ bool multi_delete::send_eof()
|
||||
local_error= local_error || error;
|
||||
killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
|
||||
/* reset used flags */
|
||||
thd->proc_info="end";
|
||||
thd_proc_info(thd, "end");
|
||||
|
||||
/*
|
||||
We must invalidate the query cache before binlog writing and
|
||||
@ -997,7 +997,7 @@ end:
|
||||
/* Probably InnoDB table */
|
||||
ulonglong save_options= thd->options;
|
||||
table_list->lock_type= TL_WRITE;
|
||||
thd->options&= ~(ulong) (OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
|
||||
thd->options&= ~(OPTION_BEGIN | OPTION_NOT_AUTOCOMMIT);
|
||||
ha_enable_transaction(thd, FALSE);
|
||||
mysql_init_select(thd->lex);
|
||||
error= mysql_delete(thd, table_list, (COND*) 0, (SQL_LIST*) 0,
|
||||
|
@ -622,7 +622,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
}
|
||||
lock_type= table_list->lock_type;
|
||||
|
||||
thd->proc_info="init";
|
||||
thd_proc_info(thd, "init");
|
||||
thd->used_tables=0;
|
||||
values= its++;
|
||||
value_count= values->elements;
|
||||
@ -708,7 +708,11 @@ 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)
|
||||
{
|
||||
if (!table->triggers || !table->triggers->has_delete_triggers())
|
||||
@ -945,7 +949,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
|
||||
@ -1723,7 +1727,7 @@ I_List<Delayed_insert> delayed_threads;
|
||||
static
|
||||
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 *di;
|
||||
@ -1805,7 +1809,7 @@ bool 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.
|
||||
@ -1852,13 +1856,13 @@ bool 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 (!di->thd.killed && !di->table && !thd->killed)
|
||||
{
|
||||
pthread_cond_wait(&di->cond_client, &di->mutex);
|
||||
}
|
||||
pthread_mutex_unlock(&di->mutex);
|
||||
thd->proc_info="got old table";
|
||||
thd_proc_info(thd, "got old table");
|
||||
if (di->thd.killed)
|
||||
{
|
||||
if (di->thd.net.report_error)
|
||||
@ -1933,13 +1937,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)
|
||||
@ -1956,7 +1960,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);
|
||||
@ -2037,11 +2041,11 @@ int write_delayed(THD *thd,TABLE *table,enum_duplicates duplic, bool ignore,
|
||||
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;
|
||||
@ -2271,7 +2275,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)
|
||||
@ -2306,7 +2310,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)
|
||||
{
|
||||
@ -2425,7 +2429,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 */
|
||||
@ -2433,7 +2437,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->needs_reopen_or_name_lock())
|
||||
{
|
||||
@ -2568,7 +2572,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)))
|
||||
{
|
||||
@ -2587,14 +2591,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)))
|
||||
|
@ -200,7 +200,7 @@ void lex_start(THD *thd)
|
||||
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;
|
||||
lex->in_sum_func= NULL;
|
||||
|
@ -94,8 +94,13 @@ 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,
|
||||
/* This should be the last !!! */
|
||||
SQLCOM_SHOW_PROFILE, SQLCOM_SHOW_PROFILES,
|
||||
|
||||
/*
|
||||
When a command is added here, be sure it's also added in mysqld.cc
|
||||
in "struct show_var_st status_vars[]= {" ...
|
||||
*/
|
||||
/* This should be the last !!! */
|
||||
SQLCOM_END
|
||||
};
|
||||
|
||||
@ -1076,6 +1081,9 @@ 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_query_id;
|
||||
uint profile_options;
|
||||
uint uint_geom_type;
|
||||
uint grant, grant_tot_col, which_columns;
|
||||
uint fk_delete_opt, fk_update_opt, fk_match_option;
|
||||
|
103
sql/sql_parse.cc
103
sql/sql_parse.cc
@ -178,14 +178,14 @@ static bool end_active_trans(THD *thd)
|
||||
if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN |
|
||||
OPTION_TABLE_LOCK))
|
||||
{
|
||||
DBUG_PRINT("info",("options: 0x%lx", (ulong) thd->options));
|
||||
DBUG_PRINT("info",("options: 0x%llx", thd->options));
|
||||
/* Safety if one did "drop table" on locked tables */
|
||||
if (!thd->locked_tables)
|
||||
thd->options&= ~OPTION_TABLE_LOCK;
|
||||
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
|
||||
if (ha_commit(thd))
|
||||
error=1;
|
||||
thd->options&= ~(ulong) OPTION_BEGIN;
|
||||
thd->options&= ~OPTION_BEGIN;
|
||||
thd->transaction.all.modified_non_trans_table= FALSE;
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
@ -211,7 +211,7 @@ static bool begin_trans(THD *thd)
|
||||
{
|
||||
LEX *lex= thd->lex;
|
||||
thd->transaction.all.modified_non_trans_table= FALSE;
|
||||
thd->options|= (ulong) OPTION_BEGIN;
|
||||
thd->options|= OPTION_BEGIN;
|
||||
thd->server_status|= SERVER_STATUS_IN_TRANS;
|
||||
if (lex->start_transaction_opt & MYSQL_START_TRANS_OPT_WITH_CONS_SNAPSHOT)
|
||||
error= ha_start_consistent_snapshot(thd);
|
||||
@ -1099,7 +1099,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
|
||||
@ -1203,7 +1203,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->init_for_queries();
|
||||
|
||||
@ -1219,7 +1219,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->init_for_queries();
|
||||
}
|
||||
|
||||
@ -1311,7 +1311,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));
|
||||
@ -1355,6 +1355,10 @@ pthread_handler_t handle_bootstrap(void *arg)
|
||||
thd->db_length+1+QUERY_CACHE_FLAGS_SIZE);
|
||||
thd->query[length] = '\0';
|
||||
DBUG_PRINT("query",("%-.4096s",thd->query));
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
thd->profiling.set_query_source(thd->query, length);
|
||||
#endif
|
||||
|
||||
/*
|
||||
We don't need to obtain LOCK_thread_count here because in bootstrap
|
||||
mode we have only one thread.
|
||||
@ -1512,7 +1516,7 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
|
||||
*/
|
||||
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
|
||||
res= ha_commit(thd);
|
||||
thd->options&= ~(ulong) OPTION_BEGIN;
|
||||
thd->options&= ~OPTION_BEGIN;
|
||||
thd->transaction.all.modified_non_trans_table= FALSE;
|
||||
break;
|
||||
case COMMIT_RELEASE:
|
||||
@ -1530,7 +1534,7 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
|
||||
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
|
||||
if (ha_rollback(thd))
|
||||
res= -1;
|
||||
thd->options&= ~(ulong) OPTION_BEGIN;
|
||||
thd->options&= ~OPTION_BEGIN;
|
||||
thd->transaction.all.modified_non_trans_table= FALSE;
|
||||
if (!res && (completion == ROLLBACK_AND_CHAIN))
|
||||
res= begin_trans(thd);
|
||||
@ -1564,6 +1568,7 @@ int end_trans(THD *thd, enum enum_mysql_completiontype completion)
|
||||
|
||||
static bool do_command(THD *thd)
|
||||
{
|
||||
bool return_value;
|
||||
char *packet= 0;
|
||||
ulong packet_length;
|
||||
NET *net= &thd->net;
|
||||
@ -1587,7 +1592,12 @@ static bool do_command(THD *thd)
|
||||
thd->clear_error(); // Clear error message
|
||||
|
||||
net_new_transaction(net);
|
||||
if ((packet_length=my_net_read(net)) == packet_error)
|
||||
|
||||
packet_length= my_net_read(net);
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
thd->profiling.start_new_query();
|
||||
#endif
|
||||
if (packet_length == packet_error)
|
||||
{
|
||||
DBUG_PRINT("info",("Got error %d reading command from socket %s",
|
||||
net->error,
|
||||
@ -1596,11 +1606,15 @@ static bool do_command(THD *thd)
|
||||
/* Check if we can continue without closing the connection */
|
||||
|
||||
if (net->error != 3)
|
||||
DBUG_RETURN(TRUE); // We have to close it.
|
||||
{
|
||||
return_value= TRUE; // We have to close it.
|
||||
goto out;
|
||||
}
|
||||
|
||||
net_send_error(thd, net->last_errno, NullS);
|
||||
net->error= 0;
|
||||
DBUG_RETURN(FALSE);
|
||||
return_value= FALSE;
|
||||
goto out;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1625,7 +1639,13 @@ static bool do_command(THD *thd)
|
||||
command == packet[0] == COM_SLEEP).
|
||||
In dispatch_command packet[packet_length] points beyond the end of packet.
|
||||
*/
|
||||
DBUG_RETURN(dispatch_command(command,thd, packet+1, (uint) packet_length));
|
||||
return_value= dispatch_command(command, thd, packet+1, (uint) (packet_length));
|
||||
|
||||
out:
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
thd->profiling.finish_current_query();
|
||||
#endif
|
||||
DBUG_RETURN(return_value);
|
||||
}
|
||||
#endif /* EMBEDDED_LIBRARY */
|
||||
|
||||
@ -1931,6 +1951,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
|
||||
mysql_log.write(thd,command, format, thd->query_length, thd->query);
|
||||
DBUG_PRINT("query",("%-.4096s",thd->query));
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
thd->profiling.set_query_source(thd->query, thd->query_length);
|
||||
#endif
|
||||
|
||||
if (!(specialflag & SPECIAL_NO_PRIOR))
|
||||
my_pthread_setprio(pthread_self(),QUERY_PRIOR);
|
||||
@ -1957,6 +1980,13 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
||||
next_packet++;
|
||||
length--;
|
||||
}
|
||||
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
thd->profiling.finish_current_query();
|
||||
thd->profiling.start_new_query("continuing");
|
||||
thd->profiling.set_query_source(next_packet, length);
|
||||
#endif
|
||||
|
||||
VOID(pthread_mutex_lock(&LOCK_thread_count));
|
||||
thd->query_length= length;
|
||||
thd->query= next_packet;
|
||||
@ -2273,7 +2303,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 */
|
||||
}
|
||||
/*
|
||||
@ -2296,9 +2326,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;
|
||||
@ -2331,7 +2361,7 @@ void log_slow_statement(THD *thd)
|
||||
*/
|
||||
if (thd->enable_slow_log && !thd->user_time)
|
||||
{
|
||||
thd->proc_info="logging slow query";
|
||||
thd_proc_info(thd, "logging slow query");
|
||||
|
||||
if ((thd->start_time > thd->time_after_lock &&
|
||||
(ulong) (thd->start_time - thd->time_after_lock) >
|
||||
@ -2342,6 +2372,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);
|
||||
}
|
||||
@ -2449,6 +2480,15 @@ int prepare_schema_table(THD *thd, LEX *lex, Table_ident *table_ident,
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case SCH_PROFILES:
|
||||
/*
|
||||
Mark this current profiling record to be discarded. We don't
|
||||
wish to have SHOW commands show up in profiling.
|
||||
*/
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
thd->profiling.discard_current_query();
|
||||
#endif
|
||||
break;
|
||||
case SCH_OPEN_TABLES:
|
||||
case SCH_VARIABLES:
|
||||
case SCH_STATUS:
|
||||
@ -2923,6 +2963,19 @@ mysql_execute_command(THD *thd)
|
||||
(1L << (uint) MYSQL_ERROR::WARN_LEVEL_ERROR));
|
||||
break;
|
||||
}
|
||||
case SQLCOM_SHOW_PROFILES:
|
||||
{
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
thd->profiling.discard_current_query();
|
||||
res= thd->profiling.show_profiles();
|
||||
if (res)
|
||||
goto error;
|
||||
#else
|
||||
my_error(ER_FEATURE_DISABLED, MYF(0), "SHOW PROFILES", "enable-profiling");
|
||||
goto error;
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
case SQLCOM_SHOW_NEW_MASTER:
|
||||
{
|
||||
if (check_global_access(thd, REPL_SLAVE_ACL))
|
||||
@ -3920,7 +3973,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;
|
||||
|
||||
@ -4091,7 +4144,7 @@ end_with_restore_list:
|
||||
if (thd->options & OPTION_TABLE_LOCK)
|
||||
{
|
||||
end_active_trans(thd);
|
||||
thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
|
||||
thd->options&= ~(OPTION_TABLE_LOCK);
|
||||
}
|
||||
if (thd->global_read_lock)
|
||||
unlock_global_read_lock(thd);
|
||||
@ -4130,7 +4183,7 @@ end_with_restore_list:
|
||||
that it can't lock a table in its list
|
||||
*/
|
||||
end_active_trans(thd);
|
||||
thd->options&= ~(ulong) (OPTION_TABLE_LOCK);
|
||||
thd->options&= ~(OPTION_TABLE_LOCK);
|
||||
}
|
||||
thd->in_lock_tables=0;
|
||||
break;
|
||||
@ -5241,7 +5294,7 @@ create_sp_error:
|
||||
thd->transaction.xid_state.xid.set(thd->lex->xid);
|
||||
xid_cache_insert(&thd->transaction.xid_state);
|
||||
thd->transaction.all.modified_non_trans_table= FALSE;
|
||||
thd->options|= (ulong) OPTION_BEGIN;
|
||||
thd->options|= OPTION_BEGIN;
|
||||
thd->server_status|= SERVER_STATUS_IN_TRANS;
|
||||
send_ok(thd);
|
||||
break;
|
||||
@ -5347,7 +5400,7 @@ create_sp_error:
|
||||
xa_state_names[thd->transaction.xid_state.xa_state]);
|
||||
break;
|
||||
}
|
||||
thd->options&= ~(ulong) OPTION_BEGIN;
|
||||
thd->options&= ~OPTION_BEGIN;
|
||||
thd->transaction.all.modified_non_trans_table= FALSE;
|
||||
thd->server_status&= ~SERVER_STATUS_IN_TRANS;
|
||||
xid_cache_delete(&thd->transaction.xid_state);
|
||||
@ -5392,7 +5445,7 @@ create_sp_error:
|
||||
send_ok(thd);
|
||||
break;
|
||||
}
|
||||
thd->proc_info="query end";
|
||||
thd_proc_info(thd, "query end");
|
||||
/* Two binlog-related cleanups: */
|
||||
|
||||
/*
|
||||
@ -5576,6 +5629,7 @@ 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"));
|
||||
@ -5774,6 +5828,7 @@ static bool check_show_access(THD *thd, TABLE_LIST *table)
|
||||
case SCH_COLUMN_PRIVILEGES:
|
||||
case SCH_TABLE_CONSTRAINTS:
|
||||
case SCH_KEY_COLUMN_USAGE:
|
||||
case SCH_PROFILES:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -6401,7 +6456,7 @@ void mysql_parse(THD *thd, const char *inBuf, uint length,
|
||||
thd->lex->sphead= 0;
|
||||
}
|
||||
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());
|
||||
|
@ -2283,6 +2283,9 @@ void mysql_stmt_execute(THD *thd, char *packet_arg, uint packet_length)
|
||||
if (!(stmt= find_prepared_statement(thd, stmt_id, "mysql_stmt_execute")))
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
thd->profiling.set_query_source(stmt->query, stmt->query_length);
|
||||
#endif
|
||||
DBUG_PRINT("exec_query", ("%s", stmt->query));
|
||||
DBUG_PRINT("info",("stmt: %p", stmt));
|
||||
|
||||
|
672
sql/sql_profile.cc
Normal file
672
sql/sql_profile.cc
Normal file
@ -0,0 +1,672 @@
|
||||
/* Copyright (C) 2007 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; version 2 of the License.
|
||||
|
||||
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 */
|
||||
|
||||
|
||||
/**
|
||||
@file
|
||||
|
||||
Implement query profiling as as list of metaphorical fences, with one fence
|
||||
per query, and each fencepost a change of thd->proc_info state (with a
|
||||
snapshot of system statistics). When asked, we can then iterate over the
|
||||
fenceposts and calculate the distance between them, to inform the user what
|
||||
happened during a particular query or thd->proc_info state.
|
||||
|
||||
User variables that inform profiling behavior:
|
||||
- "profiling", boolean, session only, "Are queries profiled?"
|
||||
- "profiling_history_size", integer, session + global, "Num queries stored?"
|
||||
*/
|
||||
|
||||
|
||||
#include "mysql_priv.h"
|
||||
#include "my_sys.h"
|
||||
|
||||
#define TIME_FLOAT_DIGITS 9
|
||||
/** two vals encoded: (dec*100)+len */
|
||||
#define TIME_I_S_DECIMAL_SIZE (TIME_FLOAT_DIGITS*100)+(TIME_FLOAT_DIGITS-3)
|
||||
|
||||
#define MAX_QUERY_LENGTH 300
|
||||
|
||||
/* Reserved for systems that can't record the function name in source. */
|
||||
const char * const _unknown_func_ = "<unknown>";
|
||||
|
||||
/**
|
||||
Connects Information_Schema and Profiling.
|
||||
*/
|
||||
int fill_query_profile_statistics_info(THD *thd, TABLE_LIST *tables,
|
||||
Item *cond)
|
||||
{
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
return(thd->profiling.fill_statistics_info(thd, tables, cond));
|
||||
#else
|
||||
my_error(ER_FEATURE_DISABLED, MYF(0), "SHOW PROFILE", "enable-profiling");
|
||||
return(1);
|
||||
#endif
|
||||
}
|
||||
|
||||
ST_FIELD_INFO query_profile_statistics_info[]=
|
||||
{
|
||||
/* name, length, type, value, maybe_null, old_name, open_method */
|
||||
{"QUERY_ID", 20, MYSQL_TYPE_LONG, 0, false, "Query_id"},
|
||||
{"SEQ", 20, MYSQL_TYPE_LONG, 0, false, "Seq"},
|
||||
{"STATE", 30, MYSQL_TYPE_STRING, 0, false, "Status"},
|
||||
{"DURATION", TIME_I_S_DECIMAL_SIZE, MYSQL_TYPE_DECIMAL, 0, false, "Duration"},
|
||||
{"CPU_USER", TIME_I_S_DECIMAL_SIZE, MYSQL_TYPE_DECIMAL, 0, true, "CPU_user"},
|
||||
{"CPU_SYSTEM", TIME_I_S_DECIMAL_SIZE, MYSQL_TYPE_DECIMAL, 0, true, "CPU_system"},
|
||||
{"CONTEXT_VOLUNTARY", 20, MYSQL_TYPE_LONG, 0, true, "Context_voluntary"},
|
||||
{"CONTEXT_INVOLUNTARY", 20, MYSQL_TYPE_LONG, 0, true, "Context_involuntary"},
|
||||
{"BLOCK_OPS_IN", 20, MYSQL_TYPE_LONG, 0, true, "Block_ops_in"},
|
||||
{"BLOCK_OPS_OUT", 20, MYSQL_TYPE_LONG, 0, true, "Block_ops_out"},
|
||||
{"MESSAGES_SENT", 20, MYSQL_TYPE_LONG, 0, true, "Messages_sent"},
|
||||
{"MESSAGES_RECEIVED", 20, MYSQL_TYPE_LONG, 0, true, "Messages_received"},
|
||||
{"PAGE_FAULTS_MAJOR", 20, MYSQL_TYPE_LONG, 0, true, "Page_faults_major"},
|
||||
{"PAGE_FAULTS_MINOR", 20, MYSQL_TYPE_LONG, 0, true, "Page_faults_minor"},
|
||||
{"SWAPS", 20, MYSQL_TYPE_LONG, 0, true, "Swaps"},
|
||||
{"SOURCE_FUNCTION", 30, MYSQL_TYPE_STRING, 0, true, "Source_function"},
|
||||
{"SOURCE_FILE", 20, MYSQL_TYPE_STRING, 0, true, "Source_file"},
|
||||
{"SOURCE_LINE", 20, MYSQL_TYPE_LONG, 0, true, "Source_line"},
|
||||
{NULL, 0, MYSQL_TYPE_STRING, 0, true, NULL}
|
||||
};
|
||||
|
||||
|
||||
int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table)
|
||||
{
|
||||
int profile_options = thd->lex->profile_options;
|
||||
int fields_include_condition_truth_values[]= {
|
||||
FALSE, /* Query_id */
|
||||
FALSE, /* Seq */
|
||||
TRUE, /* Status */
|
||||
TRUE, /* Duration */
|
||||
profile_options & PROFILE_CPU, /* CPU_user */
|
||||
profile_options & PROFILE_CPU, /* CPU_system */
|
||||
profile_options & PROFILE_CONTEXT, /* Context_voluntary */
|
||||
profile_options & PROFILE_CONTEXT, /* Context_involuntary */
|
||||
profile_options & PROFILE_BLOCK_IO, /* Block_ops_in */
|
||||
profile_options & PROFILE_BLOCK_IO, /* Block_ops_out */
|
||||
profile_options & PROFILE_IPC, /* Messages_sent */
|
||||
profile_options & PROFILE_IPC, /* Messages_received */
|
||||
profile_options & PROFILE_PAGE_FAULTS, /* Page_faults_major */
|
||||
profile_options & PROFILE_PAGE_FAULTS, /* Page_faults_minor */
|
||||
profile_options & PROFILE_SWAPS, /* Swaps */
|
||||
profile_options & PROFILE_SOURCE, /* Source_function */
|
||||
profile_options & PROFILE_SOURCE, /* Source_file */
|
||||
profile_options & PROFILE_SOURCE, /* Source_line */
|
||||
};
|
||||
|
||||
ST_FIELD_INFO *field_info;
|
||||
Name_resolution_context *context= &thd->lex->select_lex.context;
|
||||
int i;
|
||||
|
||||
for (i= 0; schema_table->fields_info[i].field_name != NULL; i++)
|
||||
{
|
||||
if (! fields_include_condition_truth_values[i])
|
||||
continue;
|
||||
|
||||
field_info= &schema_table->fields_info[i];
|
||||
Item_field *field= new Item_field(context,
|
||||
NullS, NullS, field_info->field_name);
|
||||
if (field)
|
||||
{
|
||||
field->set_name(field_info->old_name,
|
||||
strlen(field_info->old_name),
|
||||
system_charset_info);
|
||||
if (add_item_to_list(thd, field))
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
|
||||
#define RUSAGE_USEC(tv) ((tv).tv_sec*1000*1000 + (tv).tv_usec)
|
||||
#define RUSAGE_DIFF_USEC(tv1, tv2) (RUSAGE_USEC((tv1))-RUSAGE_USEC((tv2)))
|
||||
|
||||
|
||||
PROF_MEASUREMENT::PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char
|
||||
*status_arg)
|
||||
:profile(profile_arg)
|
||||
{
|
||||
collect();
|
||||
set_label(status_arg, NULL, NULL, 0);
|
||||
}
|
||||
|
||||
PROF_MEASUREMENT::PROF_MEASUREMENT(QUERY_PROFILE *profile_arg,
|
||||
const char *status_arg,
|
||||
const char *function_arg,
|
||||
const char *file_arg,
|
||||
unsigned int line_arg)
|
||||
:profile(profile_arg)
|
||||
{
|
||||
collect();
|
||||
set_label(status_arg, function_arg, file_arg, line_arg);
|
||||
}
|
||||
|
||||
PROF_MEASUREMENT::~PROF_MEASUREMENT()
|
||||
{
|
||||
if (allocated_status_memory != NULL)
|
||||
my_free(allocated_status_memory, MYF(0));
|
||||
status= function= file= NULL;
|
||||
}
|
||||
|
||||
void PROF_MEASUREMENT::set_label(const char *status_arg,
|
||||
const char *function_arg,
|
||||
const char *file_arg, unsigned int line_arg)
|
||||
{
|
||||
size_t sizes[3]; /* 3 == status+function+file */
|
||||
char *cursor;
|
||||
|
||||
/*
|
||||
Compute all the space we'll need to allocate one block for everything
|
||||
we'll need, instead of N mallocs.
|
||||
*/
|
||||
sizes[0]= (status_arg == NULL) ? 0 : strlen(status_arg) + 1;
|
||||
sizes[1]= (function_arg == NULL) ? 0 : strlen(function_arg) + 1;
|
||||
sizes[2]= (file_arg == NULL) ? 0 : strlen(file_arg) + 1;
|
||||
|
||||
allocated_status_memory= (char *) my_malloc(sizes[0] + sizes[1] + sizes[2], MYF(0));
|
||||
DBUG_ASSERT(allocated_status_memory != NULL);
|
||||
|
||||
cursor= allocated_status_memory;
|
||||
|
||||
if (status_arg != NULL)
|
||||
{
|
||||
strcpy(cursor, status_arg);
|
||||
status= cursor;
|
||||
cursor+= sizes[0];
|
||||
}
|
||||
else
|
||||
status= NULL;
|
||||
|
||||
if (function_arg != NULL)
|
||||
{
|
||||
strcpy(cursor, function_arg);
|
||||
function= cursor;
|
||||
cursor+= sizes[1];
|
||||
}
|
||||
else
|
||||
function= NULL;
|
||||
|
||||
if (file_arg != NULL)
|
||||
{
|
||||
strcpy(cursor, file_arg);
|
||||
file= cursor;
|
||||
cursor+= sizes[2];
|
||||
}
|
||||
else
|
||||
file= NULL;
|
||||
|
||||
line= line_arg;
|
||||
}
|
||||
|
||||
/**
|
||||
This updates the statistics for this moment of time. It captures the state
|
||||
of the running system, so later we can compare points in time and infer what
|
||||
happened in the mean time. It should only be called immediately upon
|
||||
instantiation of this PROF_MEASUREMENT.
|
||||
|
||||
@todo Implement resource capture for OSes not like BSD.
|
||||
*/
|
||||
void PROF_MEASUREMENT::collect()
|
||||
{
|
||||
time_usecs= (double) my_getsystime() / 10.0; /* 1 sec was 1e7, now is 1e6 */
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
getrusage(RUSAGE_SELF, &rusage);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
QUERY_PROFILE::QUERY_PROFILE(PROFILING *profiling_arg, const char *status_arg)
|
||||
:profiling(profiling_arg), profiling_query_id(0), query_source(NULL)
|
||||
{
|
||||
profile_start= new PROF_MEASUREMENT(this, status_arg);
|
||||
entries.push_back(profile_start);
|
||||
profile_end= profile_start;
|
||||
}
|
||||
|
||||
QUERY_PROFILE::~QUERY_PROFILE()
|
||||
{
|
||||
while (! entries.is_empty())
|
||||
delete entries.pop();
|
||||
|
||||
if (query_source != NULL)
|
||||
my_free(query_source, MYF(0));
|
||||
}
|
||||
|
||||
/**
|
||||
@todo Provide a way to include the full text, as in SHOW PROCESSLIST.
|
||||
*/
|
||||
void QUERY_PROFILE::set_query_source(char *query_source_arg,
|
||||
uint query_length_arg)
|
||||
{
|
||||
/* Truncate to avoid DoS attacks. */
|
||||
uint length= min(MAX_QUERY_LENGTH, query_length_arg);
|
||||
|
||||
DBUG_ASSERT(query_source == NULL); /* we don't leak memory */
|
||||
if (query_source_arg != NULL)
|
||||
query_source= my_strndup(query_source_arg, length, MYF(0));
|
||||
}
|
||||
|
||||
void QUERY_PROFILE::new_status(const char *status_arg,
|
||||
const char *function_arg, const char *file_arg,
|
||||
unsigned int line_arg)
|
||||
{
|
||||
PROF_MEASUREMENT *prof;
|
||||
DBUG_ENTER("QUERY_PROFILE::status");
|
||||
|
||||
DBUG_ASSERT(status_arg != NULL);
|
||||
|
||||
if ((function_arg != NULL) && (file_arg != NULL))
|
||||
prof= new PROF_MEASUREMENT(this, status_arg, function_arg, file_arg, line_arg);
|
||||
else
|
||||
prof= new PROF_MEASUREMENT(this, status_arg);
|
||||
|
||||
profile_end= prof;
|
||||
entries.push_back(prof);
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
|
||||
PROFILING::PROFILING()
|
||||
:profile_id_counter(1), current(NULL), last(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
PROFILING::~PROFILING()
|
||||
{
|
||||
while (! history.is_empty())
|
||||
delete history.pop();
|
||||
|
||||
if (current != NULL)
|
||||
delete current;
|
||||
}
|
||||
|
||||
/**
|
||||
A new state is given, and that signals the profiler to start a new
|
||||
timed step for the current query's profile.
|
||||
|
||||
@param status_arg name of this step
|
||||
@param function_arg calling function (usually supplied from compiler)
|
||||
@param function_arg calling file (usually supplied from compiler)
|
||||
@param function_arg calling line number (usually supplied from compiler)
|
||||
*/
|
||||
void PROFILING::status_change(const char *status_arg,
|
||||
const char *function_arg,
|
||||
const char *file_arg, unsigned int line_arg)
|
||||
{
|
||||
DBUG_ENTER("PROFILING::status_change");
|
||||
|
||||
if (status_arg == NULL) /* We don't know how to handle that */
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
if (current == NULL) /* This profile was already discarded. */
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
if (unlikely(enabled))
|
||||
current->new_status(status_arg, function_arg, file_arg, line_arg);
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/**
|
||||
Prepare to start processing a new query. It is an error to do this
|
||||
if there's a query already in process; nesting is not supported.
|
||||
|
||||
@param initial_state (optional) name of period before first state change
|
||||
*/
|
||||
void PROFILING::start_new_query(const char *initial_state)
|
||||
{
|
||||
DBUG_ENTER("PROFILING::start_new_query");
|
||||
|
||||
/* This should never happen unless the server is radically altered. */
|
||||
if (unlikely(current != NULL))
|
||||
{
|
||||
DBUG_PRINT("warning", ("profiling code was asked to start a new query "
|
||||
"before the old query was finished. This is "
|
||||
"probably a bug."));
|
||||
finish_current_query();
|
||||
}
|
||||
|
||||
enabled= (((thd)->options & OPTION_PROFILING) != 0);
|
||||
|
||||
if (! enabled) DBUG_VOID_RETURN;
|
||||
|
||||
DBUG_ASSERT(current == NULL);
|
||||
current= new QUERY_PROFILE(this, initial_state);
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/**
|
||||
Throw away the current profile, because it's useless or unwanted
|
||||
or corrupted.
|
||||
*/
|
||||
void PROFILING::discard_current_query()
|
||||
{
|
||||
DBUG_ENTER("PROFILING::discard_current_profile");
|
||||
|
||||
delete current;
|
||||
current= NULL;
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/**
|
||||
Try to save the current profile entry, clean up the data if it shouldn't be
|
||||
saved, and maintain the profile history size. Naturally, this may not
|
||||
succeed if the profile was previously discarded, and that's expected.
|
||||
*/
|
||||
void PROFILING::finish_current_query()
|
||||
{
|
||||
DBUG_ENTER("PROFILING::finish_current_profile");
|
||||
if (current != NULL)
|
||||
{
|
||||
/* The last fence-post, so we can support the span before this. */
|
||||
status_change("ending", NULL, NULL, 0);
|
||||
|
||||
if ((enabled) && /* ON at start? */
|
||||
((thd->options & OPTION_PROFILING) != 0) && /* and ON at end? */
|
||||
(current->query_source != NULL) &&
|
||||
(! current->entries.is_empty()))
|
||||
{
|
||||
current->profiling_query_id= next_profile_id(); /* assign an id */
|
||||
|
||||
history.push_back(current);
|
||||
last= current; /* never contains something that is not in the history. */
|
||||
current= NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete current;
|
||||
current= NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Maintain the history size. */
|
||||
while (history.elements > thd->variables.profiling_history_size)
|
||||
delete history.pop();
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
bool PROFILING::show_profiles()
|
||||
{
|
||||
DBUG_ENTER("PROFILING::show_profiles");
|
||||
QUERY_PROFILE *prof;
|
||||
List<Item> field_list;
|
||||
|
||||
field_list.push_back(new Item_return_int("Query_ID", 10,
|
||||
MYSQL_TYPE_LONG));
|
||||
field_list.push_back(new Item_return_int("Duration", TIME_FLOAT_DIGITS-1,
|
||||
MYSQL_TYPE_DOUBLE));
|
||||
field_list.push_back(new Item_empty_string("Query", 40));
|
||||
|
||||
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);
|
||||
|
||||
void *iterator;
|
||||
for (iterator= history.new_iterator();
|
||||
iterator != NULL;
|
||||
iterator= history.iterator_next(iterator))
|
||||
{
|
||||
prof= history.iterator_value(iterator);
|
||||
|
||||
String elapsed;
|
||||
|
||||
PROF_MEASUREMENT *ps= prof->profile_start;
|
||||
PROF_MEASUREMENT *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->profiling_query_id));
|
||||
protocol->store((double)(pe->time_usecs - ps->time_usecs)/(1000.0*1000),
|
||||
(uint32) TIME_FLOAT_DIGITS-1, &elapsed);
|
||||
if (prof->query_source != NULL)
|
||||
protocol->store(prof->query_source, strlen(prof->query_source),
|
||||
system_charset_info);
|
||||
else
|
||||
protocol->store_null();
|
||||
|
||||
if (protocol->write())
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
send_eof(thd);
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
At a point in execution where we know the query source, save the text
|
||||
of it in the query profile.
|
||||
|
||||
This must be called exactly once per descrete statement.
|
||||
*/
|
||||
void PROFILING::set_query_source(char *query_source_arg, uint query_length_arg)
|
||||
{
|
||||
DBUG_ENTER("PROFILING::set_query_source");
|
||||
|
||||
if (! enabled)
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
if (current != NULL)
|
||||
current->set_query_source(query_source_arg, query_length_arg);
|
||||
else
|
||||
DBUG_PRINT("info", ("no current profile to send query source to"));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/**
|
||||
Fill the information schema table, "query_profile", as defined in show.cc .
|
||||
There are two ways to get to this function: Selecting from the information
|
||||
schema, and a SHOW command.
|
||||
*/
|
||||
int PROFILING::fill_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond)
|
||||
{
|
||||
DBUG_ENTER("PROFILING::fill_statistics_info");
|
||||
TABLE *table= tables->table;
|
||||
ulonglong row_number= 0;
|
||||
|
||||
QUERY_PROFILE *query;
|
||||
/* Go through each query in this thread's stored history... */
|
||||
void *history_iterator;
|
||||
for (history_iterator= history.new_iterator();
|
||||
history_iterator != NULL;
|
||||
history_iterator= history.iterator_next(history_iterator))
|
||||
{
|
||||
query= history.iterator_value(history_iterator);
|
||||
|
||||
/*
|
||||
Because we put all profiling info into a table that may be reordered, let
|
||||
us also include a numbering of each state per query. The query_id and
|
||||
the "seq" together are unique.
|
||||
*/
|
||||
ulonglong seq;
|
||||
|
||||
void *entry_iterator;
|
||||
PROF_MEASUREMENT *entry, *previous= NULL;
|
||||
/* ...and for each query, go through all its state-change steps. */
|
||||
for (seq= 0, entry_iterator= query->entries.new_iterator();
|
||||
entry_iterator != NULL;
|
||||
entry_iterator= query->entries.iterator_next(entry_iterator),
|
||||
seq++, previous=entry, row_number++)
|
||||
{
|
||||
entry= query->entries.iterator_value(entry_iterator);
|
||||
|
||||
/* Skip the first. We count spans of fence, not fence-posts. */
|
||||
if (previous == NULL) continue;
|
||||
|
||||
if (thd->lex->orig_sql_command == SQLCOM_SHOW_PROFILE)
|
||||
{
|
||||
/*
|
||||
We got here via a SHOW command. That means that we stored
|
||||
information about the query we wish to show and that isn't
|
||||
in a WHERE clause at a higher level to filter out rows we
|
||||
wish to exclude.
|
||||
|
||||
Because that functionality isn't available in the server yet,
|
||||
we must filter here, at the wrong level. Once one can con-
|
||||
struct where and having conditions at the SQL layer, then this
|
||||
condition should be ripped out.
|
||||
*/
|
||||
if (thd->lex->profile_query_id == 0) /* 0 == show final query */
|
||||
{
|
||||
if (query != last)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (thd->lex->profile_query_id != query->profiling_query_id)
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set default values for this row. */
|
||||
restore_record(table, s->default_values);
|
||||
|
||||
/*
|
||||
The order of these fields is set by the query_profile_statistics_info
|
||||
array.
|
||||
*/
|
||||
table->field[0]->store((ulonglong) query->profiling_query_id);
|
||||
table->field[1]->store((ulonglong) seq); /* the step in the sequence */
|
||||
/*
|
||||
This entry, n, has a point in time, T(n), and a status phrase, S(n).
|
||||
The status phrase S(n) describes the period of time that begins at
|
||||
T(n). The previous status phrase S(n-1) describes the period of time
|
||||
that starts at T(n-1) and ends at T(n). Since we want to describe the
|
||||
time that a status phrase took T(n)-T(n-1), this line must describe the
|
||||
previous status.
|
||||
*/
|
||||
table->field[2]->store(previous->status, strlen(previous->status),
|
||||
system_charset_info);
|
||||
|
||||
my_decimal duration_decimal;
|
||||
double2my_decimal(E_DEC_FATAL_ERROR,
|
||||
(entry->time_usecs-previous->time_usecs)/(1000.0*1000),
|
||||
&duration_decimal);
|
||||
|
||||
table->field[3]->store_decimal(&duration_decimal);
|
||||
|
||||
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
|
||||
my_decimal cpu_utime_decimal, cpu_stime_decimal;
|
||||
|
||||
double2my_decimal(E_DEC_FATAL_ERROR,
|
||||
RUSAGE_DIFF_USEC(entry->rusage.ru_utime,
|
||||
previous->rusage.ru_utime) /
|
||||
(1000.0*1000),
|
||||
&cpu_utime_decimal);
|
||||
|
||||
double2my_decimal(E_DEC_FATAL_ERROR,
|
||||
RUSAGE_DIFF_USEC(entry->rusage.ru_stime,
|
||||
previous->rusage.ru_stime) /
|
||||
(1000.0*1000),
|
||||
&cpu_stime_decimal);
|
||||
|
||||
table->field[4]->store_decimal(&cpu_utime_decimal);
|
||||
table->field[5]->store_decimal(&cpu_stime_decimal);
|
||||
table->field[4]->set_notnull();
|
||||
table->field[5]->set_notnull();
|
||||
#else
|
||||
/* TODO: Add CPU-usage info for non-BSD systems */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
table->field[6]->store((uint32)(entry->rusage.ru_nvcsw -
|
||||
previous->rusage.ru_nvcsw));
|
||||
table->field[6]->set_notnull();
|
||||
table->field[7]->store((uint32)(entry->rusage.ru_nivcsw -
|
||||
previous->rusage.ru_nivcsw));
|
||||
table->field[7]->set_notnull();
|
||||
#else
|
||||
/* TODO: Add context switch info for non-BSD systems */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
table->field[8]->store((uint32)(entry->rusage.ru_inblock -
|
||||
previous->rusage.ru_inblock));
|
||||
table->field[8]->set_notnull();
|
||||
table->field[9]->store((uint32)(entry->rusage.ru_oublock -
|
||||
previous->rusage.ru_oublock));
|
||||
table->field[9]->set_notnull();
|
||||
#else
|
||||
/* TODO: Add block IO info for non-BSD systems */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
table->field[10]->store((uint32)(entry->rusage.ru_msgsnd -
|
||||
previous->rusage.ru_msgsnd), true);
|
||||
table->field[10]->set_notnull();
|
||||
table->field[11]->store((uint32)(entry->rusage.ru_msgrcv -
|
||||
previous->rusage.ru_msgrcv), true);
|
||||
table->field[11]->set_notnull();
|
||||
#else
|
||||
/* TODO: Add message info for non-BSD systems */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
table->field[12]->store((uint32)(entry->rusage.ru_majflt -
|
||||
previous->rusage.ru_majflt), true);
|
||||
table->field[12]->set_notnull();
|
||||
table->field[13]->store((uint32)(entry->rusage.ru_minflt -
|
||||
previous->rusage.ru_minflt), true);
|
||||
table->field[13]->set_notnull();
|
||||
#else
|
||||
/* TODO: Add page fault info for non-BSD systems */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
table->field[14]->store((uint32)(entry->rusage.ru_nswap -
|
||||
previous->rusage.ru_nswap), true);
|
||||
table->field[14]->set_notnull();
|
||||
#else
|
||||
/* TODO: Add swap info for non-BSD systems */
|
||||
#endif
|
||||
|
||||
/* Emit the location that started this step, not that ended it. */
|
||||
if ((previous->function != NULL) && (previous->file != NULL))
|
||||
{
|
||||
table->field[15]->store(previous->function, strlen(previous->function),
|
||||
system_charset_info);
|
||||
table->field[15]->set_notnull();
|
||||
table->field[16]->store(previous->file, strlen(previous->file), system_charset_info);
|
||||
table->field[16]->set_notnull();
|
||||
table->field[17]->store(previous->line, true);
|
||||
table->field[17]->set_notnull();
|
||||
}
|
||||
|
||||
if (schema_table_store_record(thd, table))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
#endif /* ENABLED_PROFILING */
|
297
sql/sql_profile.h
Normal file
297
sql/sql_profile.h
Normal file
@ -0,0 +1,297 @@
|
||||
/* Copyright (C) 2007 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; version 2 of the License.
|
||||
|
||||
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
|
||||
|
||||
#if __STDC_VERSION__ < 199901L
|
||||
# if __GNUC__ >= 2
|
||||
# define __func__ __FUNCTION__
|
||||
# else
|
||||
# define __func__ _unknown_func_
|
||||
extern const char * const _unknown_func_;
|
||||
# endif
|
||||
#elif defined(_MSC_VER)
|
||||
# if _MSC_VER < 1300
|
||||
# define __func__ _unknown_func_
|
||||
extern const char * const _unknown_func_;
|
||||
# else
|
||||
# define __func__ __FUNCTION__
|
||||
# endif
|
||||
#elif defined(__BORLANDC__)
|
||||
# define __func__ __FUNC__
|
||||
#else
|
||||
# define __func__ _unknown_func_
|
||||
extern const char * const _unknown_func_;
|
||||
#endif
|
||||
|
||||
extern ST_FIELD_INFO query_profile_statistics_info[];
|
||||
int fill_query_profile_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond);
|
||||
int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table);
|
||||
|
||||
|
||||
#define PROFILE_NONE 0
|
||||
#define PROFILE_CPU (1<<0)
|
||||
#define PROFILE_MEMORY (1<<1)
|
||||
#define PROFILE_BLOCK_IO (1<<2)
|
||||
#define PROFILE_CONTEXT (1<<3)
|
||||
#define PROFILE_PAGE_FAULTS (1<<4)
|
||||
#define PROFILE_IPC (1<<5)
|
||||
#define PROFILE_SWAPS (1<<6)
|
||||
#define PROFILE_SOURCE (1<<16)
|
||||
#define PROFILE_ALL (~0)
|
||||
|
||||
|
||||
#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
|
||||
#include "mysql_priv.h"
|
||||
|
||||
#ifdef HAVE_SYS_RESOURCE_H
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
|
||||
|
||||
class PROF_MEASUREMENT;
|
||||
class QUERY_PROFILE;
|
||||
class PROFILING;
|
||||
|
||||
|
||||
/**
|
||||
Implements a persistent FIFO using server List method names. Not
|
||||
thread-safe. Intended to be used on thread-local data only.
|
||||
*/
|
||||
template <class T> class Queue
|
||||
{
|
||||
private:
|
||||
|
||||
struct queue_item
|
||||
{
|
||||
T *payload;
|
||||
struct queue_item *next, *previous;
|
||||
};
|
||||
|
||||
struct queue_item *first, *last;
|
||||
|
||||
public:
|
||||
Queue()
|
||||
{
|
||||
elements= 0;
|
||||
first= last= NULL;
|
||||
}
|
||||
|
||||
void empty()
|
||||
{
|
||||
struct queue_item *i, *after_i;
|
||||
for (i= first; i != NULL; i= after_i)
|
||||
{
|
||||
after_i= i->next;
|
||||
my_free((char *) i, MYF(0));
|
||||
}
|
||||
elements= 0;
|
||||
}
|
||||
|
||||
ulong elements; /* The count of items in the Queue */
|
||||
|
||||
void push_back(T *payload)
|
||||
{
|
||||
struct queue_item *new_item;
|
||||
|
||||
new_item= (struct queue_item *) my_malloc(sizeof(struct queue_item), MYF(0));
|
||||
|
||||
new_item->payload= payload;
|
||||
|
||||
if (first == NULL)
|
||||
first= new_item;
|
||||
if (last != NULL)
|
||||
{
|
||||
DBUG_ASSERT(last->next == NULL);
|
||||
last->next= new_item;
|
||||
}
|
||||
new_item->previous= last;
|
||||
new_item->next= NULL;
|
||||
last= new_item;
|
||||
|
||||
elements++;
|
||||
}
|
||||
|
||||
T *pop()
|
||||
{
|
||||
struct queue_item *old_item= first;
|
||||
T *ret= NULL;
|
||||
|
||||
if (first == NULL)
|
||||
{
|
||||
DBUG_PRINT("warning", ("tried to pop nonexistent item from Queue"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret= old_item->payload;
|
||||
if (first->next != NULL)
|
||||
first->next->previous= NULL;
|
||||
else
|
||||
last= NULL;
|
||||
first= first->next;
|
||||
|
||||
my_free((char *)old_item, MYF(0));
|
||||
elements--;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool is_empty()
|
||||
{
|
||||
DBUG_ASSERT(((elements > 0) && (first != NULL)) || ((elements == 0) || (first == NULL)));
|
||||
return (elements == 0);
|
||||
}
|
||||
|
||||
void *new_iterator()
|
||||
{
|
||||
return first;
|
||||
}
|
||||
|
||||
void *iterator_next(void *current)
|
||||
{
|
||||
return ((struct queue_item *) current)->next;
|
||||
}
|
||||
|
||||
T *iterator_value(void *current)
|
||||
{
|
||||
return ((struct queue_item *) current)->payload;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
A single entry in a single profile.
|
||||
*/
|
||||
class PROF_MEASUREMENT
|
||||
{
|
||||
private:
|
||||
friend class QUERY_PROFILE;
|
||||
friend class PROFILING;
|
||||
|
||||
QUERY_PROFILE *profile;
|
||||
char *status;
|
||||
#ifdef HAVE_GETRUSAGE
|
||||
struct rusage rusage;
|
||||
#endif
|
||||
|
||||
char *function;
|
||||
char *file;
|
||||
unsigned int line;
|
||||
|
||||
double time_usecs;
|
||||
char *allocated_status_memory;
|
||||
|
||||
void set_label(const char *status_arg, const char *function_arg,
|
||||
const char *file_arg, unsigned int line_arg);
|
||||
void clean_up();
|
||||
|
||||
PROF_MEASUREMENT();
|
||||
PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char *status_arg);
|
||||
PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char *status_arg,
|
||||
const char *function_arg,
|
||||
const char *file_arg, unsigned int line_arg);
|
||||
~PROF_MEASUREMENT();
|
||||
void collect();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
The full profile for a single query, and includes multiple PROF_MEASUREMENT
|
||||
objects.
|
||||
*/
|
||||
class QUERY_PROFILE
|
||||
{
|
||||
private:
|
||||
friend class PROFILING;
|
||||
|
||||
PROFILING *profiling;
|
||||
|
||||
query_id_t profiling_query_id; /* Session-specific id. */
|
||||
char *query_source;
|
||||
|
||||
PROF_MEASUREMENT *profile_start;
|
||||
PROF_MEASUREMENT *profile_end;
|
||||
Queue<PROF_MEASUREMENT> entries;
|
||||
|
||||
|
||||
QUERY_PROFILE(PROFILING *profiling_arg, const char *status_arg);
|
||||
~QUERY_PROFILE();
|
||||
|
||||
void set_query_source(char *query_source_arg, uint query_length_arg);
|
||||
|
||||
/* Add a profile status change to the current profile. */
|
||||
void new_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 QUERY_PROFILE objects.
|
||||
*/
|
||||
class PROFILING
|
||||
{
|
||||
private:
|
||||
friend class PROF_MEASUREMENT;
|
||||
friend class QUERY_PROFILE;
|
||||
|
||||
/*
|
||||
Not the system query_id, but a counter unique to profiling.
|
||||
*/
|
||||
query_id_t profile_id_counter;
|
||||
THD *thd;
|
||||
bool keeping;
|
||||
bool enabled;
|
||||
|
||||
QUERY_PROFILE *current;
|
||||
QUERY_PROFILE *last;
|
||||
Queue<QUERY_PROFILE> history;
|
||||
|
||||
query_id_t next_profile_id() { return(profile_id_counter++); }
|
||||
|
||||
public:
|
||||
PROFILING();
|
||||
~PROFILING();
|
||||
void set_query_source(char *query_source_arg, uint query_length_arg);
|
||||
|
||||
void start_new_query(const char *initial_state= "starting");
|
||||
|
||||
void discard_current_query();
|
||||
|
||||
void finish_current_query();
|
||||
|
||||
void status_change(const char *status_arg,
|
||||
const char *function_arg,
|
||||
const char *file_arg, unsigned int line_arg);
|
||||
|
||||
inline void set_thd(THD *thd_arg) { thd= thd_arg; };
|
||||
|
||||
/* SHOW PROFILES */
|
||||
bool show_profiles();
|
||||
|
||||
/* ... from INFORMATION_SCHEMA.PROFILING ... */
|
||||
int fill_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond);
|
||||
};
|
||||
|
||||
# endif /* HAVE_PROFILING */
|
||||
#endif /* _SQL_PROFILE_H */
|
@ -650,7 +650,7 @@ impossible position";
|
||||
|
||||
if (read_packet)
|
||||
{
|
||||
thd->proc_info = "Sending binlog event to slave";
|
||||
thd_proc_info(thd, "Sending binlog event to slave");
|
||||
if (my_net_write(net, (char*)packet->ptr(), packet->length()) )
|
||||
{
|
||||
errmsg = "Failed on my_net_write()";
|
||||
@ -688,7 +688,7 @@ impossible position";
|
||||
bool loop_breaker = 0;
|
||||
/* need this to break out of the for loop from switch */
|
||||
|
||||
thd->proc_info = "Finished reading one binlog; switching to next binlog";
|
||||
thd_proc_info(thd, "Finished reading one binlog; switching to next binlog");
|
||||
switch (mysql_bin_log.find_next_log(&linfo, 1)) {
|
||||
case LOG_INFO_EOF:
|
||||
loop_breaker = (flags & BINLOG_DUMP_NON_BLOCK);
|
||||
@ -734,14 +734,14 @@ end:
|
||||
(void)my_close(file, MYF(MY_WME));
|
||||
|
||||
send_eof(thd);
|
||||
thd->proc_info = "Waiting to finalize termination";
|
||||
thd_proc_info(thd, "Waiting to finalize termination");
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->current_linfo = 0;
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
DBUG_VOID_RETURN;
|
||||
|
||||
err:
|
||||
thd->proc_info = "Waiting to finalize termination";
|
||||
thd_proc_info(thd, "Waiting to finalize termination");
|
||||
end_io_cache(&log);
|
||||
/*
|
||||
Exclude iteration through thread list
|
||||
@ -895,7 +895,7 @@ int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report )
|
||||
|
||||
if (check_access(thd, SUPER_ACL, any_db,0,0,0,0))
|
||||
DBUG_RETURN(1);
|
||||
thd->proc_info = "Killing slave";
|
||||
thd_proc_info(thd, "Killing slave");
|
||||
int thread_mask;
|
||||
lock_slave_threads(mi);
|
||||
// Get a mask of _running_ threads
|
||||
@ -922,7 +922,7 @@ int stop_slave(THD* thd, MASTER_INFO* mi, bool net_report )
|
||||
ER(ER_SLAVE_WAS_NOT_RUNNING));
|
||||
}
|
||||
unlock_slave_threads(mi);
|
||||
thd->proc_info = 0;
|
||||
thd_proc_info(thd, 0);
|
||||
|
||||
if (slave_errno)
|
||||
{
|
||||
@ -1078,7 +1078,7 @@ bool change_master(THD* thd, MASTER_INFO* mi)
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
thd->proc_info = "Changing master";
|
||||
thd_proc_info(thd, "Changing master");
|
||||
LEX_MASTER_INFO* lex_mi= &thd->lex->mi;
|
||||
// TODO: see if needs re-write
|
||||
if (init_master_info(mi, master_info_file, relay_log_info_file, 0,
|
||||
@ -1203,7 +1203,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))
|
||||
@ -1264,7 +1264,7 @@ bool change_master(THD* thd, MASTER_INFO* mi)
|
||||
pthread_mutex_unlock(&mi->rli.data_lock);
|
||||
|
||||
unlock_slave_threads(mi);
|
||||
thd->proc_info = 0;
|
||||
thd_proc_info(thd, 0);
|
||||
send_ok(thd);
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
@ -755,6 +755,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 */
|
||||
@ -871,7 +872,7 @@ JOIN::optimize()
|
||||
thd->fatal_error();
|
||||
error= res;
|
||||
DBUG_PRINT("error",("Error from opt_sum_query"));
|
||||
DBUG_RETURN(1);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
DBUG_PRINT("info",("Select tables optimized away"));
|
||||
zero_result_cause= "Select tables optimized away";
|
||||
@ -907,7 +908,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)
|
||||
{
|
||||
@ -917,7 +918,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"));
|
||||
@ -1306,8 +1307,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) &&
|
||||
@ -1365,7 +1367,7 @@ JOIN::optimize()
|
||||
if (need_tmp)
|
||||
{
|
||||
DBUG_PRINT("info",("Creating tmp table"));
|
||||
thd->proc_info="Creating tmp table";
|
||||
thd_proc_info(thd, "Creating tmp table");
|
||||
|
||||
init_items_ref_array();
|
||||
|
||||
@ -1393,7 +1395,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:
|
||||
@ -1413,28 +1417,34 @@ 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,
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1577,6 +1587,7 @@ JOIN::exec()
|
||||
int tmp_error;
|
||||
DBUG_ENTER("JOIN::exec");
|
||||
|
||||
thd_proc_info(thd, "executing");
|
||||
error= 0;
|
||||
if (procedure)
|
||||
{
|
||||
@ -1724,7 +1735,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)))
|
||||
{
|
||||
@ -1848,7 +1859,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;
|
||||
@ -1862,7 +1873,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)
|
||||
@ -1918,7 +1929,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,
|
||||
@ -1981,7 +1992,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)
|
||||
@ -2105,7 +2116,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),
|
||||
@ -2273,7 +2284,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,
|
||||
@ -2318,8 +2329,9 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
|
||||
err:
|
||||
if (free_join)
|
||||
{
|
||||
thd->proc_info="end";
|
||||
thd_proc_info(thd, "end");
|
||||
err|= select_lex->cleanup();
|
||||
thd_proc_info(thd, "end");
|
||||
DBUG_RETURN(err || thd->net.report_error);
|
||||
}
|
||||
DBUG_RETURN(join->error);
|
||||
@ -10212,7 +10224,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)
|
||||
{
|
||||
@ -10240,7 +10252,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;
|
||||
}
|
||||
@ -10270,7 +10282,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))
|
||||
@ -10325,8 +10337,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:
|
||||
@ -10338,7 +10350,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);
|
||||
table->mem_root= new_table.mem_root;
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
|
@ -1402,7 +1402,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;
|
||||
@ -1549,6 +1549,12 @@ static bool show_status_array(THD *thd, const char *wild,
|
||||
nr= (long) (thd->query_start() - server_start_time);
|
||||
end= int10_to_str(nr, buff, 10);
|
||||
break;
|
||||
#ifdef COMMUNITY_SERVER
|
||||
case SHOW_FLUSHTIME:
|
||||
nr= (long) (thd->query_start() - flush_status_time);
|
||||
end= int10_to_str(nr, buff, 10);
|
||||
break;
|
||||
#endif
|
||||
case SHOW_QUERIES:
|
||||
end= int10_to_str((long) thd->query_id, buff, 10);
|
||||
break;
|
||||
@ -3668,6 +3674,14 @@ ST_SCHEMA_TABLE *get_schema_table(enum enum_schema_tables schema_table_idx)
|
||||
/*
|
||||
Create information_schema table using schema_table data
|
||||
|
||||
@note
|
||||
For MYSQL_TYPE_DECIMAL fields only, the field_length member has encoded
|
||||
into it two numbers, based on modulus of base-10 numbers. In the ones
|
||||
position is the number of decimals. Tens position is unused. In the
|
||||
hundreds and thousands position is a two-digit decimal number representing
|
||||
length. Encode this value with (decimals*100)+length , where
|
||||
0<decimals<10 and 0<=length<100 .
|
||||
|
||||
SYNOPSIS
|
||||
create_schema_table()
|
||||
thd thread handler
|
||||
@ -3712,9 +3726,25 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list)
|
||||
fields_info->field_length)) == NULL)
|
||||
DBUG_RETURN(NULL);
|
||||
break;
|
||||
case MYSQL_TYPE_DECIMAL:
|
||||
if (!(item= new Item_decimal((longlong) fields_info->value, false)))
|
||||
{
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
item->decimals= fields_info->field_length%10;
|
||||
item->max_length= (fields_info->field_length/100)%100;
|
||||
if (item->unsigned_flag == 0)
|
||||
item->max_length+= 1;
|
||||
if (item->decimals > 0)
|
||||
item->max_length+= 1;
|
||||
item->set_name(fields_info->field_name,
|
||||
strlen(fields_info->field_name), cs);
|
||||
break;
|
||||
case MYSQL_TYPE_STRING:
|
||||
default:
|
||||
/* Don't let unimplemented types pass through. Could be a grave error. */
|
||||
DBUG_ASSERT(fields_info->field_type == MYSQL_TYPE_STRING);
|
||||
DBUG_ASSERT(fields_info->field_type == MYSQL_TYPE_STRING ||
|
||||
fields_info->field_type == MYSQL_TYPE_DECIMAL);
|
||||
|
||||
if (!(item= new Item_empty_string("", fields_info->field_length, cs)))
|
||||
{
|
||||
@ -4443,6 +4473,9 @@ ST_SCHEMA_TABLE schema_tables[]=
|
||||
get_all_tables, 0, get_schema_key_column_usage_record, 4, 5, 0},
|
||||
{"OPEN_TABLES", open_tables_fields_info, create_schema_table,
|
||||
fill_open_tables, make_old_format, 0, -1, -1, 1},
|
||||
{"PROFILING", query_profile_statistics_info, create_schema_table,
|
||||
fill_query_profile_statistics_info, make_profile_table_for_show,
|
||||
NULL, -1, -1, false},
|
||||
{"ROUTINES", proc_fields_info, create_schema_table,
|
||||
fill_schema_proc, make_proc_old_format, 0, -1, -1, 0},
|
||||
{"SCHEMATA", schema_fields_info, create_schema_table,
|
||||
|
@ -1791,7 +1791,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)
|
||||
@ -1823,7 +1823,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:
|
||||
@ -2979,7 +2979,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);
|
||||
|
||||
@ -2996,7 +2996,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;
|
||||
@ -3124,7 +3124,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
create_field *new_datetime_field= 0;
|
||||
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;
|
||||
|
||||
@ -3265,7 +3265,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
|
||||
{
|
||||
@ -3316,7 +3316,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. First we need to close all
|
||||
instances of 'source' table.
|
||||
@ -3817,7 +3817,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)
|
||||
@ -3904,7 +3904,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)
|
||||
@ -4010,7 +4010,7 @@ view_err:
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
thd->proc_info="end";
|
||||
thd_proc_info(thd, "end");
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
thd->clear_error();
|
||||
|
@ -165,7 +165,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);
|
||||
|
||||
@ -362,7 +362,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");
|
||||
ha_rows tmp_limit= limit;
|
||||
|
||||
while (!(error=info.read_record(&info)) && !thd->killed)
|
||||
@ -427,7 +427,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();
|
||||
@ -543,7 +543,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));
|
||||
|
||||
/*
|
||||
@ -1033,7 +1033,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);
|
||||
|
||||
@ -1762,7 +1762,7 @@ bool multi_update::send_eof()
|
||||
{
|
||||
char buff[STRING_BUFFER_USUAL_SIZE];
|
||||
THD::killed_state killed_status= THD::NOT_KILLED;
|
||||
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;
|
||||
@ -1774,7 +1774,7 @@ bool multi_update::send_eof()
|
||||
later carried out killing should not affect binlogging.
|
||||
*/
|
||||
killed_status= (local_error == 0)? THD::NOT_KILLED : thd->killed;
|
||||
thd->proc_info= "end";
|
||||
thd_proc_info(thd, "end");
|
||||
|
||||
/* We must invalidate the query cache before binlog writing and
|
||||
ha_autocommit_... */
|
||||
|
@ -672,7 +672,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);
|
||||
|
@ -502,6 +502,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
|
||||
@ -542,10 +543,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
|
||||
@ -619,6 +622,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
|
||||
@ -688,6 +692,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
|
||||
@ -756,6 +762,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
|
||||
@ -814,6 +821,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
|
||||
@ -831,6 +839,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
|
||||
@ -901,6 +911,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
|
||||
@ -931,6 +942,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
|
||||
@ -7943,6 +7956,64 @@ 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_args:
|
||||
/* empty */
|
||||
{
|
||||
Lex->profile_query_id= 0;
|
||||
}
|
||||
| FOR_SYM QUERY_SYM NUM
|
||||
{
|
||||
Lex->profile_query_id= atoi($3.str);
|
||||
}
|
||||
;
|
||||
|
||||
/* Show things */
|
||||
|
||||
show: SHOW
|
||||
@ -8078,6 +8149,16 @@ 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 *lex= Lex;
|
||||
lex->sql_command= SQLCOM_SELECT;
|
||||
lex->orig_sql_command= SQLCOM_SHOW_PROFILE;
|
||||
if (prepare_schema_table(YYTHD, lex, NULL, SCH_PROFILES) != 0)
|
||||
YYABORT;
|
||||
}
|
||||
| opt_var_type STATUS_SYM wild_and_where
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
@ -9356,6 +9437,7 @@ keyword_sp:
|
||||
| BERKELEY_DB_SYM {}
|
||||
| BINLOG_SYM {}
|
||||
| BIT_SYM {}
|
||||
| BLOCK_SYM {}
|
||||
| BOOL_SYM {}
|
||||
| BOOLEAN_SYM {}
|
||||
| BTREE_SYM {}
|
||||
@ -9373,6 +9455,8 @@ keyword_sp:
|
||||
| CONCURRENT {}
|
||||
| CONNECTION_SYM {}
|
||||
| CONSISTENT_SYM {}
|
||||
| CONTEXT_SYM {}
|
||||
| CPU_SYM {}
|
||||
| CUBE_SYM {}
|
||||
| DATA_SYM {}
|
||||
| DATETIME {}
|
||||
@ -9395,6 +9479,7 @@ keyword_sp:
|
||||
| EXPANSION_SYM {}
|
||||
| EXTENDED_SYM {}
|
||||
| FAST_SYM {}
|
||||
| FAULTS_SYM {}
|
||||
| FOUND_SYM {}
|
||||
| DISABLE_SYM {}
|
||||
| ENABLE_SYM {}
|
||||
@ -9419,6 +9504,8 @@ keyword_sp:
|
||||
| ISSUER_SYM {}
|
||||
| INNOBASE_SYM {}
|
||||
| INSERT_METHOD {}
|
||||
| IO_SYM {}
|
||||
| IPC_SYM {}
|
||||
| RELAY_THREAD {}
|
||||
| LAST_SYM {}
|
||||
| LEAVES {}
|
||||
@ -9448,6 +9535,7 @@ keyword_sp:
|
||||
| MAX_UPDATES_PER_HOUR {}
|
||||
| MAX_USER_CONNECTIONS_SYM {}
|
||||
| MEDIUM_SYM {}
|
||||
| MEMORY_SYM {}
|
||||
| MERGE_SYM {}
|
||||
| MICROSECOND_SYM {}
|
||||
| MIGRATE_SYM {}
|
||||
@ -9474,6 +9562,7 @@ keyword_sp:
|
||||
| ONE_SHOT_SYM {}
|
||||
| ONE_SYM {}
|
||||
| PACK_KEYS_SYM {}
|
||||
| PAGE_SYM {}
|
||||
| PARTIAL {}
|
||||
| PASSWORD {}
|
||||
| PHASE_SYM {}
|
||||
@ -9483,6 +9572,8 @@ keyword_sp:
|
||||
| PRIVILEGES {}
|
||||
| PROCESS {}
|
||||
| PROCESSLIST_SYM {}
|
||||
| PROFILE_SYM {}
|
||||
| PROFILES_SYM {}
|
||||
| QUARTER_SYM {}
|
||||
| QUERY_SYM {}
|
||||
| QUICK {}
|
||||
@ -9516,6 +9607,7 @@ keyword_sp:
|
||||
| SHUTDOWN {}
|
||||
| SNAPSHOT_SYM {}
|
||||
| SOUNDS_SYM {}
|
||||
| SOURCE_SYM {}
|
||||
| SQL_CACHE_SYM {}
|
||||
| SQL_BUFFER_RESULT {}
|
||||
| SQL_NO_CACHE_SYM {}
|
||||
@ -9527,6 +9619,8 @@ keyword_sp:
|
||||
| SUBJECT_SYM {}
|
||||
| SUPER_SYM {}
|
||||
| SUSPEND_SYM {}
|
||||
| SWAPS_SYM {}
|
||||
| SWITCHES_SYM {}
|
||||
| TABLES {}
|
||||
| TABLESPACE {}
|
||||
| TEMPORARY {}
|
||||
|
@ -173,6 +173,7 @@ enum SHOW_TYPE
|
||||
SHOW_BOOL, SHOW_MY_BOOL, SHOW_OPENTABLES, SHOW_STARTTIME, SHOW_QUERIES,
|
||||
SHOW_LONG_CONST, SHOW_INT_CONST, SHOW_HAVE, SHOW_SYS, SHOW_HA_ROWS,
|
||||
SHOW_VARS,
|
||||
SHOW_FLUSHTIME,
|
||||
#ifdef HAVE_OPENSSL
|
||||
SHOW_SSL_CTX_SESS_ACCEPT, SHOW_SSL_CTX_SESS_ACCEPT_GOOD,
|
||||
SHOW_SSL_GET_VERSION, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE,
|
||||
|
@ -377,6 +377,7 @@ enum enum_schema_tables
|
||||
SCH_COLUMN_PRIVILEGES,
|
||||
SCH_KEY_COLUMN_USAGE,
|
||||
SCH_OPEN_TABLES,
|
||||
SCH_PROFILES,
|
||||
SCH_PROCEDURES,
|
||||
SCH_SCHEMATA,
|
||||
SCH_SCHEMA_PRIVILEGES,
|
||||
|
@ -330,7 +330,7 @@ do
|
||||
|
||||
BuildMySQL "\
|
||||
%if %{STATIC_BUILD}
|
||||
--disable-shared \
|
||||
--enable-shared \
|
||||
--with-mysqld-ldflags='-all-static' \
|
||||
--with-client-ldflags='-all-static' \
|
||||
$USE_OTHER_LIBC_DIR \
|
||||
@ -364,6 +364,22 @@ done
|
||||
|
||||
./libtool --mode=execute nm --numeric-sort sql/mysqld > sql/mysqld.sym
|
||||
|
||||
# Include libgcc.a in the devel subpackage (BUG 4921)
|
||||
if expr "$CC" : ".*gcc.*" > /dev/null ;
|
||||
then
|
||||
libgcc=`$CC $CFLAGS --print-libgcc-file`
|
||||
if [ -f $libgcc ]
|
||||
then
|
||||
%define have_libgcc 1
|
||||
install -m 644 $libgcc $RBR%{_libdir}/mysql/libmygcc.a
|
||||
fi
|
||||
fi
|
||||
|
||||
# Save the libraries
|
||||
(cd libmysql/.libs; tar cf $RBR/shared-libs.tar *.so*)
|
||||
(cd libmysql_r/.libs; tar rf $RBR/shared-libs.tar *.so*)
|
||||
(cd ndb/src/.libs; tar rf $RBR/shared-libs.tar *.so*)
|
||||
|
||||
# We might want to save the config log file
|
||||
if test -n "$MYSQL_CONFLOG_DEST"
|
||||
then
|
||||
@ -396,18 +412,7 @@ make install-strip DESTDIR=$RBR benchdir_root=%{_datadir}
|
||||
install -s -m 755 $MBD/sql/mysqld-debug $RBR%{_sbindir}/mysqld-debug
|
||||
|
||||
# Install shared libraries (Disable for architectures that don't support it)
|
||||
# (cd $RBR%{_libdir}; tar xf $RBR/shared-libs.tar; rm -f $RBR/shared-libs.tar)
|
||||
|
||||
# Include libgcc.a in the devel subpackage (BUG 4921)
|
||||
if expr "$CC" : ".*gcc.*" > /dev/null ;
|
||||
then
|
||||
libgcc=`$CC $CFLAGS --print-libgcc-file`
|
||||
if [ -f $libgcc ]
|
||||
then
|
||||
%define have_libgcc 1
|
||||
install -m 644 $libgcc $RBR%{_libdir}/mysql/libmygcc.a
|
||||
fi
|
||||
fi
|
||||
(cd $RBR%{_libdir}; tar xf $RBR/shared-libs.tar; rm -f $RBR/shared-libs.tar)
|
||||
|
||||
# install symbol files ( for stack trace resolution)
|
||||
# install -m 644 $MBD/sql/mysqld-max.sym $RBR%{_libdir}/mysql/mysqld-max.sym
|
||||
|
Loading…
x
Reference in New Issue
Block a user