summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/profiling.result94
-rw-r--r--mysql-test/t/profiling.test42
-rw-r--r--sql/sp_head.cc30
-rw-r--r--sql/sql_profile.cc4
4 files changed, 168 insertions, 2 deletions
diff --git a/mysql-test/r/profiling.result b/mysql-test/r/profiling.result
index 6435b346f98..1673597d544 100644
--- a/mysql-test/r/profiling.result
+++ b/mysql-test/r/profiling.result
@@ -300,6 +300,100 @@ id
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//
+select count(*) as count_before_p1 from information_schema.profiling;
+count_before_p1
+535
+first call to p1
+call p1;
+This p1 should show up in profiling
+This p1 should show up in profiling
+select * from profile_log;
+how_many
+528
+second call to p1
+call p1;
+This p1 should show up in profiling
+This p1 should show up in profiling
+select * from profile_log;
+how_many
+528
+478
+third call to p1
+call p1;
+This p1 should show up in profiling
+This p1 should show up in profiling
+select * from profile_log;
+how_many
+528
+478
+443
+set session profiling = OFF;
+call p2;
+This p1 should show up in profiling
+This p1 should show up in profiling
+This p2 should show up in profiling
+This p2 should show up in profiling
+set session profiling = OFF;
+call p3;
+This p3 should show up in profiling
+This p3 should show up in profiling
+Status Duration
+continuing inside routine #
+checking permissions #
+Opening tables #
+init #
+optimizing #
+executing #
+end #
+query end #
+closing tables #
+show profiles;
+Query_ID Duration Query
+# # 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)
+# # select * from t1
+# # delete from t1
+# # insert into t1 values (1), (2), (3)
+# # insert into t1 values (1), (2), (3)
+# # select * from t1
+# # select @@profiling
+# # create function f1() returns varchar(50) return 'hello'
+# # select @@profiling
+# # select @@profiling
+# # select 'This p1 should show up in profiling'
+# # insert into profile_log select count(*) from information_schema.profiling
+# # select * from profile_log
+# # SET profiling = ON
+# # select 'This p1 should show up in profiling'
+# # insert into profile_log select count(*) from information_schema.profiling
+# # select * from profile_log
+# # SET profiling = ON
+# # select 'This p1 should show up in profiling'
+# # insert into profile_log select count(*) from information_schema.profiling
+# # select * from profile_log
+# # SET profiling = ON
+# # select 'This p1 should show up in profiling'
+# # insert into profile_log select count(*) from information_schema.profiling
+# # select 'This p2 should show up in profiling'
+# # select 'This p3 should show up in profiling'
+# # show profile
+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);
diff --git a/mysql-test/t/profiling.test b/mysql-test/t/profiling.test
index 9e73c63a977..9e5328e030f 100644
--- a/mysql-test/t/profiling.test
+++ b/mysql-test/t/profiling.test
@@ -138,7 +138,7 @@ show profiles;
## Verify that the various juggling of THD contexts doesn't affect profiling.
-## Functions
+## Functions and procedures
set session profiling = ON;
select @@profiling;
create function f1() returns varchar(50) return 'hello';
@@ -146,6 +146,46 @@ 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 ;//
+
+select count(*) as count_before_p1 from information_schema.profiling;
+--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;
+--replace_column 2 #
+call p3;
+
+--replace_column 1 # 2 #
+show profiles;
+
+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;
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 09ae572152f..3becfd6bcf4 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -1162,15 +1162,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
@@ -1248,6 +1269,11 @@ 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
+
/* Restore query context. */
m_creation_ctx->restore_env(thd, saved_creation_ctx);
@@ -2725,6 +2751,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)) &&
!(res=subst_spvars(thd, this, &m_query)))
{
diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc
index fd2ae32c711..1922fa3bc2b 100644
--- a/sql/sql_profile.cc
+++ b/sql/sql_profile.cc
@@ -33,7 +33,9 @@
#include "my_sys.h"
#define TIME_FLOAT_DIGITS 9
-#define TIME_I_S_DECIMAL_SIZE (6*100)+6 /**< two vals encoded: (dec*100)+len */
+/** 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. */