Merge lp:~sergei.glushchenko/percona-server/5.5-slow-log-stored-procs into lp:percona-server/5.5

Proposed by Sergei Glushchenko
Status: Merged
Approved by: Laurynas Biveinis
Approved revision: no longer in the source branch.
Merged at revision: 718
Proposed branch: lp:~sergei.glushchenko/percona-server/5.5-slow-log-stored-procs
Merge into: lp:percona-server/5.5
Diff against target: 277 lines (+112/-26)
6 files modified
mysql-test/r/percona_log_slow_sp_statements.result (+46/-10)
mysql-test/t/percona_log_slow_sp_statements.test (+33/-5)
sql/log.cc (+9/-0)
sql/sp_head.cc (+0/-8)
sql/sp_rcontext.h (+2/-3)
sql/sql_parse.cc (+22/-0)
To merge this branch: bzr merge lp:~sergei.glushchenko/percona-server/5.5-slow-log-stored-procs
Reviewer Review Type Date Requested Status
Laurynas Biveinis (community) Approve
Review via email: mp+241224@code.launchpad.net

Description of the change

    Implementation of log-slow-sp-statements blueprint

    When log_slow_sp_statement is ON
    - Make an entry to slow-log for each query in stored procedures.
    - Don't make an entry to slow-log for the CALL itself, because that
      would count the time twice and skew reports.
    - Slow-log entries are annotated with the stored procedure in
      which it ran.

There is also issue 43131. Customer wants CALL statement not showed in slow log even if it takes long to execute, however individual queries inside stored procedure should be logged if they take long.

The part of this blueprint regarding bug #719386 has already been fixed.

http://jenkins.percona.com/view/PS%205.5/job/percona-server-5.5-param/1065/

To post a comment you must log in.
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :

    - How are statements referencing procedure args logged? With var
      names, values, or something else?
    - Same question for the combination of stored procedures and
      prepared statements (i.e. case 1: PREPARE s CALL p(@foo, 2);
      EXECUTE s; case 2: PREPARE s CALL p(?, ?); EXECUTE s USING 1,
      @foo; maybe case 3: PROCEDURE foo BEGIN EXECUTE bar;
    - In the case of non-trivial answers, the above needs MTR
      testing.

review: Needs Information
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :

In all cases statement will look like

SELECT NAME_CONST('a',101), NAME_CONST('b',102);

But prepared CALL statement will be logged into slow log because it is SQLCOM_EXECUTE, not the SQLCOM_CALL. Not sure how to differentiate this case yet.

Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :

I made changes needed to recognize prepared statements which are CALL statements. Answer to the question posted in prev comment. Jenkins:
http://jenkins.percona.com/view/PS%205.5/job/percona-server-5.5-param/1070/

Revision history for this message
Laurynas Biveinis (laurynas-biveinis) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'mysql-test/r/percona_log_slow_sp_statements.result'
--- mysql-test/r/percona_log_slow_sp_statements.result 2013-02-11 08:09:00 +0000
+++ mysql-test/r/percona_log_slow_sp_statements.result 2014-12-01 21:16:02 +0000
@@ -1,28 +1,64 @@
1DROP PROCEDURE IF EXISTS test_f;1DROP PROCEDURE IF EXISTS test_outer;
2DROP PROCEDURE IF EXISTS test_inner;
2SET SESSION min_examined_row_limit=0;3SET SESSION min_examined_row_limit=0;
3SET SESSION long_query_time=0;4SET SESSION long_query_time=0;
4SET SESSION query_cache_type=0;5SET SESSION query_cache_type=0;
5CREATE PROCEDURE test_f()6CREATE PROCEDURE test_inner()
7BEGIN
8SELECT 2;
9END^
10CREATE PROCEDURE test_outer()
6BEGIN11BEGIN
7SELECT 1;12SELECT 1;
13CALL test_inner();
8END^14END^
15PREPARE stmt FROM "CALL test_outer()";
9SET GLOBAL log_slow_sp_statements=ON;16SET GLOBAL log_slow_sp_statements=ON;
10[log_start.inc] percona.slow_extended.sp117[log_start.inc] percona.slow_extended.sp1
11CALL test_f();18CALL test_outer();
121191
131201
212
222
23EXECUTE stmt;
241
251
262
272
14[log_stop.inc] percona.slow_extended.sp128[log_stop.inc] percona.slow_extended.sp1
15[log_grep.inc] file: percona.slow_extended.sp1 pattern: SELECT 1;29[log_grep.inc] file: percona.slow_extended.sp1 pattern: SELECT 1;
16[log_grep.inc] lines: 130[log_grep.inc] lines: 2
31[log_grep.inc] file: percona.slow_extended.sp1 pattern: SELECT 2;
32[log_grep.inc] lines: 2
33[log_grep.inc] file: percona.slow_extended.sp1 pattern: CALL test_
34[log_grep.inc] lines: 0
35[log_grep.inc] file: percona.slow_extended.sp1 pattern: # Stored routine: test.test_outer
36[log_grep.inc] lines: 2
37[log_grep.inc] file: percona.slow_extended.sp1 pattern: # Stored routine: test.test_inner
38[log_grep.inc] lines: 2
17SET GLOBAL log_slow_sp_statements=OFF;39SET GLOBAL log_slow_sp_statements=OFF;
18[log_start.inc] percona.slow_extended.sp240[log_start.inc] percona.slow_extended.sp2
19CALL test_f();41CALL test_outer();
201421
211431
442
452
46EXECUTE stmt;
471
481
492
502
22[log_stop.inc] percona.slow_extended.sp251[log_stop.inc] percona.slow_extended.sp2
23[log_grep.inc] file: percona.slow_extended.sp2 pattern: SELECT 1;52[log_grep.inc] file: percona.slow_extended.sp2 pattern: SELECT 1;
24[log_grep.inc] lines: 053[log_grep.inc] lines: 0
25DROP PROCEDURE test_f;54[log_grep.inc] file: percona.slow_extended.sp2 pattern: SELECT 2;
55[log_grep.inc] lines: 0
56[log_grep.inc] file: percona.slow_extended.sp2 pattern: CALL test_
57[log_grep.inc] lines: 2
58[log_grep.inc] file: percona.slow_extended.sp2 pattern: # Stored routine: test.test_
59[log_grep.inc] lines: 0
60DROP PROCEDURE test_outer;
61DROP PROCEDURE test_inner;
26SET GLOBAL log_slow_sp_statements=default;62SET GLOBAL log_slow_sp_statements=default;
27SET SESSION long_query_time=default;63SET SESSION long_query_time=default;
28SET SESSION min_examined_row_limit=default;64SET SESSION min_examined_row_limit=default;
2965
=== modified file 'mysql-test/t/percona_log_slow_sp_statements.test'
--- mysql-test/t/percona_log_slow_sp_statements.test 2013-02-11 08:09:00 +0000
+++ mysql-test/t/percona_log_slow_sp_statements.test 2014-12-01 21:16:02 +0000
@@ -2,7 +2,8 @@
2# Test slow-logging of statements in stored procedures2# Test slow-logging of statements in stored procedures
3#3#
4--disable_warnings4--disable_warnings
5DROP PROCEDURE IF EXISTS test_f;5DROP PROCEDURE IF EXISTS test_outer;
6DROP PROCEDURE IF EXISTS test_inner;
6--enable_warnings7--enable_warnings
78
8SET SESSION min_examined_row_limit=0;9SET SESSION min_examined_row_limit=0;
@@ -10,29 +11,56 @@
10SET SESSION query_cache_type=0;11SET SESSION query_cache_type=0;
1112
12delimiter ^;13delimiter ^;
13CREATE PROCEDURE test_f()14CREATE PROCEDURE test_inner()
15BEGIN
16 SELECT 2;
17END^
18delimiter ;^
19
20delimiter ^;
21CREATE PROCEDURE test_outer()
14BEGIN22BEGIN
15 SELECT 1;23 SELECT 1;
24 CALL test_inner();
16END^25END^
17delimiter ;^26delimiter ;^
1827
28PREPARE stmt FROM "CALL test_outer()";
29
19SET GLOBAL log_slow_sp_statements=ON;30SET GLOBAL log_slow_sp_statements=ON;
20--let log_file=percona.slow_extended.sp131--let log_file=percona.slow_extended.sp1
21--source include/log_start.inc32--source include/log_start.inc
22CALL test_f();33CALL test_outer();
34EXECUTE stmt;
23--source include/log_stop.inc35--source include/log_stop.inc
24--let grep_pattern=SELECT 1;36--let grep_pattern=SELECT 1;
25--source include/log_grep.inc37--source include/log_grep.inc
38--let grep_pattern=SELECT 2;
39--source include/log_grep.inc
40--let grep_pattern=CALL test_
41--source include/log_grep.inc
42--let grep_pattern=# Stored routine: test.test_outer
43--source include/log_grep.inc
44--let grep_pattern=# Stored routine: test.test_inner
45--source include/log_grep.inc
2646
27SET GLOBAL log_slow_sp_statements=OFF;47SET GLOBAL log_slow_sp_statements=OFF;
28--let log_file=percona.slow_extended.sp248--let log_file=percona.slow_extended.sp2
29--source include/log_start.inc49--source include/log_start.inc
30CALL test_f();50CALL test_outer();
51EXECUTE stmt;
31--source include/log_stop.inc52--source include/log_stop.inc
32--let grep_pattern=SELECT 1;53--let grep_pattern=SELECT 1;
33--source include/log_grep.inc54--source include/log_grep.inc
55--let grep_pattern=SELECT 2;
56--source include/log_grep.inc
57--let grep_pattern=CALL test_
58--source include/log_grep.inc
59--let grep_pattern=# Stored routine: test.test_
60--source include/log_grep.inc
3461
35DROP PROCEDURE test_f;62DROP PROCEDURE test_outer;
63DROP PROCEDURE test_inner;
3664
37SET GLOBAL log_slow_sp_statements=default;65SET GLOBAL log_slow_sp_statements=default;
38SET SESSION long_query_time=default;66SET SESSION long_query_time=default;
3967
=== modified file 'sql/log.cc'
--- sql/log.cc 2014-09-24 09:00:06 +0000
+++ sql/log.cc 2014-12-01 21:16:02 +0000
@@ -39,6 +39,8 @@
39#include "rpl_filter.h"39#include "rpl_filter.h"
40#include "rpl_rli.h"40#include "rpl_rli.h"
41#include "sql_audit.h"41#include "sql_audit.h"
42#include "sp_rcontext.h"
43#include "sp_head.h"
4244
43#include <my_dir.h>45#include <my_dir.h>
44#include <stdarg.h>46#include <stdarg.h>
@@ -2828,6 +2830,13 @@
2828 if (my_b_write(&log_file, (uchar*) "\n", 1))2830 if (my_b_write(&log_file, (uchar*) "\n", 1))
2829 tmp_errno= errno;2831 tmp_errno= errno;
28302832
2833 if (opt_log_slow_sp_statements &&
2834 thd->spcont &&
2835 my_b_printf(&log_file,
2836 "# Stored routine: %s\n",
2837 thd->spcont->sp->m_qname.str) == (uint) -1)
2838 tmp_errno= errno;
2839
2831#if defined(ENABLED_PROFILING)2840#if defined(ENABLED_PROFILING)
2832 thd->profiling.print_current(&log_file);2841 thd->profiling.print_current(&log_file);
2833#endif2842#endif
28342843
=== modified file 'sql/sp_head.cc'
--- sql/sp_head.cc 2013-10-22 13:33:14 +0000
+++ sql/sp_head.cc 2014-12-01 21:16:02 +0000
@@ -1729,9 +1729,7 @@
1729 goto err_with_cleanup;1729 goto err_with_cleanup;
1730 }1730 }
17311731
1732#ifndef DBUG_OFF
1733 nctx->sp= this;1732 nctx->sp= this;
1734#endif
17351733
1736 thd->spcont= nctx;1734 thd->spcont= nctx;
17371735
@@ -1855,9 +1853,7 @@
1855 */1853 */
1856 thd->restore_active_arena(&call_arena, &backup_arena);1854 thd->restore_active_arena(&call_arena, &backup_arena);
18571855
1858#ifndef DBUG_OFF
1859 nctx->sp= this;1856 nctx->sp= this;
1860#endif
18611857
1862 /* Pass arguments. */1858 /* Pass arguments. */
1863 for (arg_no= 0; arg_no < argcount; arg_no++)1859 for (arg_no= 0; arg_no < argcount; arg_no++)
@@ -2063,9 +2059,7 @@
2063 DBUG_RETURN(TRUE);2059 DBUG_RETURN(TRUE);
2064 }2060 }
20652061
2066#ifndef DBUG_OFF
2067 octx->sp= 0;2062 octx->sp= 0;
2068#endif
2069 thd->spcont= octx;2063 thd->spcont= octx;
20702064
2071 /* set callers_arena to thd, for upper-level function to work */2065 /* set callers_arena to thd, for upper-level function to work */
@@ -2079,9 +2073,7 @@
2079 thd->spcont= save_spcont;2073 thd->spcont= save_spcont;
2080 DBUG_RETURN(TRUE);2074 DBUG_RETURN(TRUE);
2081 }2075 }
2082#ifndef DBUG_OFF
2083 nctx->sp= this;2076 nctx->sp= this;
2084#endif
20852077
2086 if (params > 0)2078 if (params > 0)
2087 {2079 {
20882080
=== modified file 'sql/sp_rcontext.h'
--- sql/sp_rcontext.h 2013-03-19 12:36:34 +0000
+++ sql/sp_rcontext.h 2014-12-01 21:16:02 +0000
@@ -139,13 +139,12 @@
139 */139 */
140 bool end_partial_result_set;140 bool end_partial_result_set;
141141
142#ifndef DBUG_OFF
143 /*142 /*
144 The routine for which this runtime context is created. Used for checking143 The routine for which this runtime context is created. Used for checking
145 if correct runtime context is used for variable handling.144 if correct runtime context is used for variable handling and for logging
145 slow statements inside of stored procedure.
146 */146 */
147 sp_head *sp;147 sp_head *sp;
148#endif
149148
150 sp_rcontext(sp_pcontext *root_parsing_ctx, Field *return_value_fld,149 sp_rcontext(sp_pcontext *root_parsing_ctx, Field *return_value_fld,
151 sp_rcontext *prev_runtime_ctx);150 sp_rcontext *prev_runtime_ctx);
152151
=== modified file 'sql/sql_parse.cc'
--- sql/sql_parse.cc 2014-08-22 09:58:37 +0000
+++ sql/sql_parse.cc 2014-12-01 21:16:02 +0000
@@ -1580,6 +1580,28 @@
1580#endif1580#endif
15811581
1582 /*1582 /*
1583 Don't log the CALL statement if slow statements logging
1584 inside of stored procedures is enabled.
1585 This code should be run after query_response_time_collect(...)
1586 function to avoid influence on query_response_time_stats logic.
1587 */
1588 if (opt_log_slow_sp_statements &&
1589 thd->lex)
1590 {
1591 if (thd->lex->sql_command == SQLCOM_CALL)
1592 DBUG_VOID_RETURN;
1593 /* Can be prepared CALL statement */
1594 if (thd->lex->sql_command == SQLCOM_EXECUTE)
1595 {
1596 Statement *stmt;
1597 LEX_STRING *name= &thd->lex->prepared_stmt_name;
1598 if ((stmt= thd->stmt_map.find_by_name(name)) != NULL &&
1599 stmt->lex && stmt->lex->sql_command == SQLCOM_CALL)
1600 DBUG_VOID_RETURN;
1601 }
1602 }
1603
1604 /*
1583 Low long_query_time value most likely means user is debugging stuff and even1605 Low long_query_time value most likely means user is debugging stuff and even
1584 though some thread's queries are not supposed to be logged b/c of the rate1606 though some thread's queries are not supposed to be logged b/c of the rate
1585 limit, if one of them takes long enough (>= 1 second) it will be sensible1607 limit, if one of them takes long enough (>= 1 second) it will be sensible

Subscribers

People subscribed via source and target branches