Commit fcb52609 authored by unknown's avatar unknown

Changing the state of whether we're recording profiling information

halfway through a query (as happens in "SET SESSION PROFILING = ...")
has a few side-effects, the worst of which is a memory leak for
prepared statements, which poke directly from the parser into the 
profiling code (we don't have the query text when we need it) and 
that overwrites a pointer to heap-allocated memory when the previous
statement turns on profiling.

Instead, now set a flag when we begin a new statement that tracks 
whether profiling is on _at the start_ of the query.  Use that to
track whether we gather info.

Additionally, use that AND use the state of the profiling variable
after the end of a query to know whether to store information about 
the query that just finished.


mysql-test/r/profiling.result:
  Testing whether profiling is on at the beginning of a query and at
  the end of a query makes "SET SESSION PROFILING = ..." statements
  disappear from the profiling.  They were never reliable before.
sql/sql_profile.cc:
  Check to see if profiling was enabled at the beginning of this query
  before trying to store query_source.  This avoids a memory leak for
  prepared statements, which get here by direct means.
  
  If profiling was toggled in this query, then don't store this query
  profile.
sql/sql_profile.h:
  Keep track of whether profiling is on.
parent c717287c
......@@ -69,34 +69,33 @@ big_string
012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890
show profiles;
Query_ID Duration Query
1 # set session profiling = ON
2 # set session profiling_history_size=30
3 # show session variables like 'profil%'
4 # select @@profiling
5 # create table t1 (
1 # set session profiling_history_size=30
2 # show session variables like 'profil%'
3 # select @@profiling
4 # create table t1 (
a int,
b int
)
6 # insert into t1 values (1,1), (2,null), (3, 4)
7 # insert into t1 values (5,1), (6,null), (7, 4)
8 # insert into t1 values (1,1), (2,null), (3, 4)
9 # insert into t1 values (5,1), (6,null), (7, 4)
10 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
11 # insert into t1 select * from t1
12 # select count(*) from t1
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 # insert into t1 select * from t1
16 # select count(*) 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 # insert into t1 select * from t1
20 # select count(*) from t1
21 # select sum(a) from t1
22 # select sum(a) from t1 group by b
23 # select sum(a) + sum(b) from t1 group by b
24 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
25 # select '0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345
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;
......@@ -131,36 +130,36 @@ insert into t2 values (1), (2), (3);
insert into t3 values (1), (2), (3);
show profiles;
Query_ID Duration Query
11 # insert into t1 select * from t1
12 # select count(*) from t1
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 # insert into t1 select * from t1
16 # select count(*) 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 # insert into t1 select * from t1
20 # select count(*) from t1
21 # select sum(a) from t1
22 # select sum(a) from t1 group by b
23 # select sum(a) + sum(b) from t1 group by b
24 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
25 # select '0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345
26 # select * from information_schema.profiling
27 # select query_id, state, duration from information_schema.profiling
28 # select query_id, sum(duration) from information_schema.profiling group by query_id
29 # select query_id, count(*) from information_schema.profiling group by query_id
30 # select sum(duration) from information_schema.profiling
31 # select query_id, count(*), sum(duration) from information_schema.profiling group by query_id
32 # 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
33 # drop table if exists t1, t2, t3
34 # SHOW WARNINGS
35 # create table t1 (id int )
36 # create table t2 (id int not null)
37 # create table t3 (id int not null primary key)
38 # insert into t1 values (1), (2), (3)
39 # insert into t2 values (1), (2), (3)
40 # insert into t3 values (1), (2), (3)
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
......@@ -168,36 +167,36 @@ id
3
show profiles;
Query_ID Duration Query
12 # select count(*) 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 # insert into t1 select * from t1
16 # select count(*) 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 # insert into t1 select * from t1
20 # select count(*) from t1
21 # select sum(a) from t1
22 # select sum(a) from t1 group by b
23 # select sum(a) + sum(b) from t1 group by b
24 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
25 # select '0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345
26 # select * from information_schema.profiling
27 # select query_id, state, duration from information_schema.profiling
28 # select query_id, sum(duration) from information_schema.profiling group by query_id
29 # select query_id, count(*) from information_schema.profiling group by query_id
30 # select sum(duration) from information_schema.profiling
31 # select query_id, count(*), sum(duration) from information_schema.profiling group by query_id
32 # 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
33 # drop table if exists t1, t2, t3
34 # SHOW WARNINGS
35 # create table t1 (id int )
36 # create table t2 (id int not null)
37 # create table t3 (id int not null primary key)
38 # insert into t1 values (1), (2), (3)
39 # insert into t2 values (1), (2), (3)
40 # insert into t3 values (1), (2), (3)
41 # 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);
......@@ -212,72 +211,72 @@ id
3
show profiles;
Query_ID Duration Query
16 # select count(*) 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 # insert into t1 select * from t1
20 # select count(*) from t1
21 # select sum(a) from t1
22 # select sum(a) from t1 group by b
23 # select sum(a) + sum(b) from t1 group by b
24 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
25 # select '0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345
26 # select * from information_schema.profiling
27 # select query_id, state, duration from information_schema.profiling
28 # select query_id, sum(duration) from information_schema.profiling group by query_id
29 # select query_id, count(*) from information_schema.profiling group by query_id
30 # select sum(duration) from information_schema.profiling
31 # select query_id, count(*), sum(duration) from information_schema.profiling group by query_id
32 # 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
33 # drop table if exists t1, t2, t3
34 # SHOW WARNINGS
35 # create table t1 (id int )
36 # create table t2 (id int not null)
37 # create table t3 (id int not null primary key)
38 # insert into t1 values (1), (2), (3)
39 # insert into t2 values (1), (2), (3)
40 # insert into t3 values (1), (2), (3)
41 # select * from t1
42 # delete 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 # insert into t1 values (1), (2), (3)
45 # select * from t1
44 # select * from t1
set session profiling = OFF;
select sum(id) from t1;
sum(id)
12
show profiles;
Query_ID Duration Query
16 # select count(*) 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 # insert into t1 select * from t1
20 # select count(*) from t1
21 # select sum(a) from t1
22 # select sum(a) from t1 group by b
23 # select sum(a) + sum(b) from t1 group by b
24 # select max(x) from (select sum(a) as x from t1 group by b) as teeone
25 # select '0123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345678900123456789001234567890012345
26 # select * from information_schema.profiling
27 # select query_id, state, duration from information_schema.profiling
28 # select query_id, sum(duration) from information_schema.profiling group by query_id
29 # select query_id, count(*) from information_schema.profiling group by query_id
30 # select sum(duration) from information_schema.profiling
31 # select query_id, count(*), sum(duration) from information_schema.profiling group by query_id
32 # 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
33 # drop table if exists t1, t2, t3
34 # SHOW WARNINGS
35 # create table t1 (id int )
36 # create table t2 (id int not null)
37 # create table t3 (id int not null primary key)
38 # insert into t1 values (1), (2), (3)
39 # insert into t2 values (1), (2), (3)
40 # insert into t3 values (1), (2), (3)
41 # select * from t1
42 # delete 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 # insert into t1 values (1), (2), (3)
45 # select * from t1
44 # select * from t1
set session profiling = ON;
select @@profiling;
@@profiling
......
......@@ -168,10 +168,14 @@ QUERY_PROFILE::QUERY_PROFILE(PROFILING *profiling_arg, char *query_source_arg,
void QUERY_PROFILE::set_query_source(char *query_source_arg,
uint query_length_arg)
{
if (! profiling->enabled)
return;
/* Truncate to avoid DoS attacks. */
uint length= min(MAX_QUERY_LENGTH, query_length_arg);
/* TODO?: Provide a way to include the full text, as in SHOW PROCESSLIST. */
DBUG_ASSERT(query_source == NULL);
if (query_source_arg != NULL)
query_source= my_strdup_with_length(query_source_arg, length, MYF(0));
}
......@@ -445,7 +449,7 @@ bool QUERY_PROFILE::show(uint options)
}
PROFILING::PROFILING()
:profile_id_counter(1), keeping(1), current(NULL), last(NULL)
:profile_id_counter(1), keeping(TRUE), enabled(FALSE), current(NULL), last(NULL)
{
}
......@@ -464,7 +468,7 @@ void PROFILING::status_change(const char *status_arg,
{
DBUG_ENTER("PROFILING::status_change");
if (unlikely((thd->options & OPTION_PROFILING) != 0))
if (unlikely(enabled))
{
if (unlikely(current == NULL))
reset();
......@@ -499,6 +503,8 @@ void PROFILING::store()
if (current != NULL)
{
if (keeping &&
(enabled) && /* ON at start? */
(((thd)->options & OPTION_PROFILING) != 0) && /* and ON at end? */
(current->query_source != NULL) &&
(current->query_source[0] != '\0') &&
(!current->entries.is_empty()))
......@@ -517,6 +523,7 @@ void PROFILING::store()
}
DBUG_ASSERT(current == NULL);
if (enabled)
current= new QUERY_PROFILE(this, thd->query, thd->query_length);
DBUG_VOID_RETURN;
......@@ -534,7 +541,12 @@ void PROFILING::reset()
store();
if (likely(((thd)->options & OPTION_PROFILING) == 0))
{
enabled= FALSE;
DBUG_VOID_RETURN;
}
else
enabled= TRUE;
if (current != NULL)
current->reset();
......
......@@ -277,6 +277,7 @@ class PROFILING
query_id_t profile_id_counter;
THD *thd;
bool keeping;
bool enabled;
QUERY_PROFILE *current;
QUERY_PROFILE *last;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment