Merge lp:~vlad-lesin/percona-server/sql_timeout into lp:percona-server/5.5

Proposed by Vlad Lesin
Status: Rejected
Rejected by: Alexey Kopytov
Proposed branch: lp:~vlad-lesin/percona-server/sql_timeout
Merge into: lp:percona-server/5.5
Diff against target: 1169 lines (+910/-4)
16 files modified
Percona-Server/mysql-test/r/mysqld--help-notwin.result (+2/-0)
Percona-Server/mysql-test/r/percona_server_variables_debug.result (+1/-0)
Percona-Server/mysql-test/r/percona_server_variables_release.result (+1/-0)
Percona-Server/mysql-test/r/percona_sql_timeout.result (+120/-0)
Percona-Server/mysql-test/suite/sys_vars/r/sql_timeout_basic.result (+164/-0)
Percona-Server/mysql-test/suite/sys_vars/t/sql_timeout_basic.test (+210/-0)
Percona-Server/mysql-test/t/percona_sql_timeout.test (+44/-0)
Percona-Server/sql/CMakeLists.txt (+1/-1)
Percona-Server/sql/mysqld.cc (+59/-2)
Percona-Server/sql/mysqld.h (+5/-1)
Percona-Server/sql/sql_class.cc (+5/-0)
Percona-Server/sql/sql_class.h (+6/-0)
Percona-Server/sql/sql_parse.cc (+3/-0)
Percona-Server/sql/sql_timeout.cc (+228/-0)
Percona-Server/sql/sql_timeout.h (+55/-0)
Percona-Server/sql/sys_vars.cc (+6/-0)
To merge this branch: bzr merge lp:~vlad-lesin/percona-server/sql_timeout
Reviewer Review Type Date Requested Status
Laurynas Biveinis (community) Needs Fixing
Vlad Lesin (community) Needs Resubmitting
Alexey Kopytov (community) Needs Fixing
Vadim Tkachenko Needs Fixing
Review via email: mp+89693@code.launchpad.net

Description of the change

This is draft implementation of https://blueprints.launchpad.net/percona-server/+spec/sql-timeout without tests.

  The QUERY_TIMEOUT keyword is used to point maximum query execution time. The example of using:

  SELECT SLEEP(20) /*! QUERY_TIMEOUT = 10 */;

  This keyword may be used in every statement except "begin".
  The keyword has a higher priority then SQL_TIMEOUT session variable. For example:

  SET SESSION SQL_TIMEOUT = 100;
  SELECT SLEEP(20) /*! QUERY_TIMEOUT = 10 */;

  The second query will be killed in 10 seconds.

  I haven't yet found the way of using the same name for keyword and session variable.

  The smoke tests may be done such way:
  NUM_PROCESSES=50; for i in `seq 1 $NUM_PROCESSES`; do TIMEOUT=$(( $RANDOM % 20 )); (mysql -uroot test -e "select sleep(20) query_timeout=$TIMEOUT" &); (mysql -uroot test -e "select sleep(20)" &); done

To post a comment you must log in.
Revision history for this message
Vadim Tkachenko (vadim-tk) wrote :

The name of option should be the same in all case.

If it is:
SET SESSION SQL_TIMEOUT = 100;

Then it should be:
  SELECT SLEEP(20) /*! SQL_TIMEOUT = 10 */;

review: Needs Fixing
Revision history for this message
Vlad Lesin (vlad-lesin) wrote :

> The name of option should be the same in all case.
>
> If it is:
> SET SESSION SQL_TIMEOUT = 100;
>
> Then it should be:
> SELECT SLEEP(20) /*! SQL_TIMEOUT = 10 */;

Ok. Done.

But when you use this variant of "set" statement you have to wrap the variable name with `` (SET SESSION `SQL_TIMEOUT` = 10) because this name coincides with the keyword. It's the common rule when a variable name coincides with a keyword.

Is it acceptable?

review: Needs Information
Revision history for this message
Vadim Tkachenko (vadim-tk) wrote :

Is it keyword because we use it in comment ?

On Tue, Jan 24, 2012 at 10:33 AM, Vladislav Lesin <email address hidden> wrote:
> Review: Needs Information
>
>> The name of option should be the same in all case.
>>
>> If it is:
>> SET SESSION SQL_TIMEOUT = 100;
>>
>> Then it should be:
>>   SELECT SLEEP(20) /*! SQL_TIMEOUT = 10 */;
>
> Ok. Done.
>
> But when you use this variant of "set" statement you have to wrap the variable name with `` (SET SESSION `SQL_TIMEOUT` = 10) because this name coincides with the keyword. It's the common rule when a variable name coincides with a keyword.
>
> Is it acceptable?
> --
> https://code.launchpad.net/~vlad-lesin/percona-server/sql_timeout/+merge/89693
> Your team Percona developers is subscribed to branch lp:percona-server.

--
Vadim Tkachenko, CTO, Percona Inc.
Phone +1-925-400-7377,  Skype: vadimtk153
Schedule meeting: http://tungle.me/VadimTkachenko

Join us at Percona Live: MySQL Conference And Expo 2012
http://www.percona.com/live/mysql-conference-2012/

Revision history for this message
Alexey Kopytov (akopytov) wrote :

On 24.01.12 22:37, Vadim Tkachenko wrote:
> Is it keyword because we use it in comment ?
>

Yes, /*! */ are executable comments. As in, it must be valid SQL code
inside, not just an arbitrary string.

Revision history for this message
Vadim Tkachenko (vadim-tk) wrote :

Ok, then it is fine.

On Tue, Jan 24, 2012 at 10:43 AM, Alexey Kopytov
<email address hidden> wrote:
> On 24.01.12 22:37, Vadim Tkachenko wrote:
>> Is it keyword because we use it in comment ?
>>
>
> Yes, /*! */ are executable comments. As in, it must be valid SQL code
> inside, not just an arbitrary string.
>
> --
> https://code.launchpad.net/~vlad-lesin/percona-server/sql_timeout/+merge/89693
> Your team Percona developers is subscribed to branch lp:percona-server.

--
Vadim Tkachenko, CTO, Percona Inc.
Phone +1-925-400-7377,  Skype: vadimtk153
Schedule meeting: http://tungle.me/VadimTkachenko

Join us at Percona Live: MySQL Conference And Expo 2012
http://www.percona.com/live/mysql-conference-2012/

Revision history for this message
Vlad Lesin (vlad-lesin) wrote :

Vadim proposed me to use kewpie for testing. I tried to work with it. But a lot of tests fail on the current branch of Percona-Server. May be there are some special ways to run this tool to have successful tests passing. I din't find them in google and documentation. I asked Alexey Kopytov about this and he answered that the integration with Percona-Server had not yet completed and he didn't recommend me to use this tool to avoid troubles with implementation and code review.

The question is should I use the kewpie or old good mysqltest may be used? If kewpie is the preferable solution whom I can contanct to clear some questions up?

review: Needs Information
Revision history for this message
Patrick Crews (patrick-crews) wrote :

I would recommend using mysqltest / MTR if you can express tests in the provided language.
If you have difficulty in testing your changes via what MTR provides, then one can use kewpie.

Out of curiosity - how were you trying to run the software? Could you share command lines / failure output? It is still a work in progress, but should be suitable for your needs here (provided MTR is unsuitable)

Revision history for this message
Vlad Lesin (vlad-lesin) wrote :

> Out of curiosity - how were you trying to run the software? Could you share
> command lines / failure output? It is still a work in progress, but should be
> suitable for your needs here (provided MTR is unsuitable)

Sorry, I used wrong command line agruments for building percona-server. That's why a lot of tests didn't work. It's ok now. I successfully used kewpie for testing this feature. Thank's.

Revision history for this message
Alexey Kopytov (akopytov) wrote :

Hi Vladislav,

On 23.01.12 18:43, Vladislav Lesin wrote:
> Vladislav Lesin has proposed merging lp:~vlad-lesin/percona-server/sql_timeout into lp:percona-server.
>
> Requested reviews:
> Alexey Kopytov (akopytov)
>
> For more details, see:
> https://code.launchpad.net/~vlad-lesin/percona-server/sql_timeout/+merge/89693
>
> This is draft implementation of https://blueprints.launchpad.net/percona-server/+spec/sql-timeout without tests.
>

The current implementation is better than your original design proposal,
but is still worse than what I have suggested (which is now described in
the blueprint).

There's still a lot of unnecessary work. Suppose you have 100 threads
started about the same time with a 600 seconds timeout. What the timeout
monitor thread will be doing with the current implementation is wake up
every 0.25 sec, walk through all 100 threads while holding the
LOCK_timeout mutex (so, for example, no new connections can be created
during this time). Around 4 * 600 * 100 loop iterations before it has to
do any real work. And then when it has to kill a thread, it will
possibly wait in LOCK_thd_data (while still holding LOCK_timeout, and
thus possibly blocking new connections).

Why not implement it as I written in the worklog, i.e. as a queue?

Other comments and questions in no particular order:

- why is sql_timeout a session-only variable? I don't see any reasons
for that.

- please implement the per-query syntax as a SELECT option.

- I don't see any comments except those in the copy-pasted code

- calling add_to_sql_timeout_monitor() from the parser is not a good
idea for a number of reasons. The most important one is that timeouts
will not work for prepared statements, and work not as one would expect
for stored routines. Besides, don't you call it twice in case of
per-query syntax?

- please don't use SLEEP() in cases. It always means trouble, because on
slow/overloaded test machines such tests behave unpredictably. For
example, on a slow/overloaded machine, SELECT SLEEP(3) may actually take
4 or more seconds, so the test case from your patch would fail.

I think we can simplify tests to make them reliable. For example, use
SLEEP(1000) and just verified it's interrupted (i.e. returns 1) when a
timeout is set.

- please remove the copy-pasted code related to Dec and IA64 from
sql_timeout_thread_func(), you don't really need that

- many lines with trailing whitespace, try for example:

grep '^+.* \+$' sql_timeout.patch

- please always put opening braces on separate lines, there's a few
cases where this rule is violated

Revision history for this message
Alexey Kopytov (akopytov) :
review: Needs Fixing
Revision history for this message
Vlad Lesin (vlad-lesin) wrote :

Everything is done except making SQL_TIMEOUT not only session but global variable too. Because blueprint describes it as a session variable. It's not an issue to do this but in this case we should change the blueprint too.

Each item in the queue has a pointer to the thread object to have
ability to invoke "kill query" function for that thread. Every time we use sql_timeout we push that pointer and expiration time to the queue. And after the query is executed we remove the item from the queue. The "remove" operation searches the queue item with certain thread pointer using hash table.

review: Needs Resubmitting
Revision history for this message
Vadim Tkachenko (vadim-tk) wrote :

Vlad,

We need to have GLOBAL variable also, that's my bad, I did not think
about it initially.
I updated blueprint.

On Tue, Feb 7, 2012 at 4:10 AM, Vladislav Lesin <email address hidden> wrote:
> Review: Resubmit
>
> Everything is done except making SQL_TIMEOUT not only session but global variable too. Because blueprint describes it as a session variable. It's not an issue to do this but in this case we should change the blueprint too.
>
> Each item in the queue has a pointer to the thread object to have
> ability to invoke "kill query" function for that thread. Every time we use sql_timeout we push that pointer and expiration time to the queue. And after the query is executed we remove the item from the queue. The "remove" operation searches the queue item with certain thread pointer using hash table.
> --
> https://code.launchpad.net/~vlad-lesin/percona-server/sql_timeout/+merge/89693
> You are reviewing the proposed merge of lp:~vlad-lesin/percona-server/sql_timeout into lp:percona-server.

--
Vadim Tkachenko, CTO, Percona Inc.
Phone +1-925-400-7377,  Skype: vadimtk153
Schedule meeting: http://tungle.me/VadimTkachenko

Join us at Percona Live: MySQL Conference And Expo 2012
http://www.percona.com/live/mysql-conference-2012/

Revision history for this message
Vlad Lesin (vlad-lesin) wrote :

> Vlad,
>
> We need to have GLOBAL variable also, that's my bad, I did not think
> about it initially.
> I updated blueprint.

Ok, done.

Revision history for this message
Alexey Kopytov (akopytov) wrote :

Vladislav,

I have reviewed the new version of patch and have a number of comments and questions:

   - why a thread is only added to the monitor if it's a SELECT query:

> + sql_timeout_monitor.add(thd);
> res= execute_sqlcom_select(thd, all_tables);
> + sql_timeout_monitor.remove(thd);

   What happens with non-SELECT statements when we have a global or a session timeout value?

   - please merge from trunk, there's a conflict in 'series'
   - sql_timeout_hand is defined but never used
   - init_thread_environment() seems to be a wrong place to initialize
     the monitor state. Why not do it in the sql_timeout_thread_func()?
   - clean_up_mutexes() seems to be a wrong place to destroy the monitor
     state. Why not do it in sql_timeout_thread_func()?
   - please add my_thread_init() to sql_timeout_thread_func()
   - http://jenkins.percona.com/view/Percona%20Server%205.5/job/percona-server-5.5-param/277/#showFailuresLink
     - please adjust main.mysqld--help-win, main.mysqld--help-win,
       main.percona_server_variables_release and
       main.percona_server_variables_debug
     - there's a compiler warning on 32-bit systems in sys_vars.cc
   - in sys_vars.cc the variable is declared as Sys_var_ulong, but the
     max value is ULONGLONG_MAX (which is the reason for the warning)
   - I don't like that we allocate/free the Sql_timeout_info structure in
     add()/remove(). What about adding a variable of that type to THD
     and then making add()/remove() use that variable instead?
   - I think it's a huge overkill to modify queues API in the server just to
     be able to use hash when removing. Just walking the queue to find
     the element to remove should be sufficient. It's a relatively rare
     event, right?
   - I wonder what's the reasoning behind making
     was_added_to_sql_timeout_monitor in THD and sql_timeout in LEX
     volatile
   - please rename was_added_to_sql_timeout_monitor to something
     shorter. 'has_sql_timeout' sounds descriptive enough to me.
   - there's a number of cases when assignments have a space before '='
   - please wrap the statements in QUEUE_ITEM_INDEX_CHANGED() macro into
     "do {...} while(0)". please also explain why it is needed :)
   - there's a number of cases when variable assignments do NOT have a
     space after '='
   - please don't use comma-separated assignments
   - add a space after a typecast
   - please use 'static inline' rather than just 'inline' in sql_timeout.cc
   - you don't have to use my_sleep() in ::exit(), if you do all
     destruction/deallocation in the thread itself. you just tell the
     montor thread to shutdown, and it will handle everything else
   - I still see a few cases when opening braces are not on a separate
     line
   - some lines are wider than 80 characters
   - please put declarations at the start of a block. it makes reading
     the code and finding variable types much easier, especially when
     declarations are separated from the code with a blank line
   - do you really need to separate tests sql_timeout_basic_32 and
     sql_timeout_basic_64?

review: Needs Fixing
Revision history for this message
Alexey Kopytov (akopytov) wrote :

Vladislav,

Please also remove support for per-query syntax. As we discussed previously, we will implement them in a different way later.

Revision history for this message
Vlad Lesin (vlad-lesin) wrote :

Done.

review: Needs Resubmitting
Revision history for this message
Vlad Lesin (vlad-lesin) wrote :

Jenkins build:

http://jenkins.percona.com/view/Percona%20Server%205.5/job/percona-server-5.5-param/318/

All remarks of Alexey Kopytov were taken into account.

Revision history for this message
Vlad Lesin (vlad-lesin) wrote :
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote :
Download full text (3.6 KiB)

   The blueprint has to be expanded with more details,
   i.e. parts of "Description of the Change" in the MP have to be
   moved there. Likewise, there is some discussion in bug 671227,
   which should be accounted for in the blueprint, (i.e. we decided to
   do this and not that etc).

   If there is no query option variable support, then this part should
   be moved to another blueprint, probably set as dependant on this
   one.

   Line 363: for reference can put the blueprint link.
   Line 368: unless I'm missing something, there is no need to include
   load_sysvars.inc. That file is for platform-specific variables and
   values, SQL_TIMEOUT is not such.
   Lines 399--410: I don't understand what does the
   "FN_DYNVARS_083_02" section do what the previous one doesn't.
   Lines 449--450, 460--461 seem redundant.

   Lines 462--463: why it's only a warning to set a negative time out
   value which then gets "truncated" to zero? IMHO it makes more sense
   to make it error instead, if that's possible of course.

   I don't like the SET @@global.sql_timeout = TRUE; SELECT
   @@global.sql_timeout test because of actual SQL timeout possibility
   on loaded Jenkins hosts. Since it's not sane (even if legal) to
   assign TRUE timeout, I'd leave the test only for FALSE.

   I am not sure if the test is stable on busy servers. Some of the
   connection threads might get starved and return results at
   unexpected times, breaking the test. I'd test the basic feature
   with a single connection test, and if there's need to have
   concurrent testing, I'd do it separately with the query log
   disabled (basically just to test that the server does not crash).
   Also, the timed-out statements produce any warnings? If yes, maybe
   it's possible to record only thesm with the query log disabled.
   Then the result file part for them would be a sequence of warnings,
   independent of their actual order.

   No need for extra empty line at 774.

   The sql_timeout_expire can be set in THD::THD initializer list.

   What about prepared statements? Is timeout honored for them? What
   about setting it inside of a PS? Perhaps makes sense to add test
   cases for it?

   Whitespace issue in lines 878--880. Also can just use return (a -
   b);

   Line 901 s/properly/proper

   For defensive programming I'd protect the queue_init_ex with
   LOCK_queue too.

   Please use C++ static_cast instead of C-style cast in
   Sql_timeout_monitor::deinit(). Perhaps elsewhere too, if I missed
   any C casts where C++ casts would make more sense.

   In the monitor function, I'd get rid of now variable and always
   invoke my_micro_time(). The reason is that THD data lock, kill,
   unlock might take a long time for busy queries or buggy code paths
   that do not check kill state very often.

   For the reason we need to release LOCK_queue around that code and
   move queue_remove to be the 1st statement in the loop so that
   queue_top and queue_remove happen atomically.

   Space after (%s) in line 993.

   In the add method, the LOCK_queue can be held for shorter time:
   thd->sql_timeout_expire and sql_print_error calls should happen
   outside it. Or, I'd set t...

Read more...

review: Needs Fixing
Revision history for this message
Alexey Kopytov (akopytov) wrote :

Closing, as sql_timeout will only be implemented in 5.6.

Unmerged revisions

237. By Vlad Lesin

Get SQL_TIMEOUT=X variable to make queries automatically be killed
when they are taking too long time.
Example:
SET SQL_TIMEOUT=10;
SELECT SLEEP(20);

The query will be killed in 10 seconds.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'Percona-Server/mysql-test/r/mysqld--help-notwin.result'
--- Percona-Server/mysql-test/r/mysqld--help-notwin.result 2012-04-19 16:51:34 +0000
+++ Percona-Server/mysql-test/r/mysqld--help-notwin.result 2012-04-26 09:57:20 +0000
@@ -724,6 +724,7 @@
724 replication.724 replication.
725 --sql-mode=name Syntax: sql-mode=mode[,mode[,mode...]]. See the manual725 --sql-mode=name Syntax: sql-mode=mode[,mode[,mode...]]. See the manual
726 for the complete list of valid sql modes726 for the complete list of valid sql modes
727 --sql-timeout=# Timeout in seconds to wait before killing query.
727 --stored-program-cache=# 728 --stored-program-cache=#
728 The soft upper limit for number of cached stored routines729 The soft upper limit for number of cached stored routines
729 for one connection.730 for one connection.
@@ -1013,6 +1014,7 @@
1013sort-buffer-size 20971521014sort-buffer-size 2097152
1014sporadic-binlog-dump-fail FALSE1015sporadic-binlog-dump-fail FALSE
1015sql-mode 1016sql-mode
1017sql-timeout 0
1016stored-program-cache 2561018stored-program-cache 256
1017symbolic-links FALSE1019symbolic-links FALSE
1018sync-binlog 01020sync-binlog 0
10191021
=== modified file 'Percona-Server/mysql-test/r/percona_server_variables_debug.result'
--- Percona-Server/mysql-test/r/percona_server_variables_debug.result 2012-04-18 23:26:11 +0000
+++ Percona-Server/mysql-test/r/percona_server_variables_debug.result 2012-04-26 09:57:20 +0000
@@ -344,6 +344,7 @@
344SQL_SAFE_UPDATES344SQL_SAFE_UPDATES
345SQL_SELECT_LIMIT345SQL_SELECT_LIMIT
346SQL_SLAVE_SKIP_COUNTER346SQL_SLAVE_SKIP_COUNTER
347SQL_TIMEOUT
347SQL_WARNINGS348SQL_WARNINGS
348SSL_CA349SSL_CA
349SSL_CAPATH350SSL_CAPATH
350351
=== modified file 'Percona-Server/mysql-test/r/percona_server_variables_release.result'
--- Percona-Server/mysql-test/r/percona_server_variables_release.result 2012-04-18 23:26:11 +0000
+++ Percona-Server/mysql-test/r/percona_server_variables_release.result 2012-04-26 09:57:20 +0000
@@ -338,6 +338,7 @@
338SQL_SAFE_UPDATES338SQL_SAFE_UPDATES
339SQL_SELECT_LIMIT339SQL_SELECT_LIMIT
340SQL_SLAVE_SKIP_COUNTER340SQL_SLAVE_SKIP_COUNTER
341SQL_TIMEOUT
341SQL_WARNINGS342SQL_WARNINGS
342SSL_CA343SSL_CA
343SSL_CAPATH344SSL_CAPATH
344345
=== added file 'Percona-Server/mysql-test/r/percona_sql_timeout.result'
--- Percona-Server/mysql-test/r/percona_sql_timeout.result 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/r/percona_sql_timeout.result 2012-04-26 09:57:20 +0000
@@ -0,0 +1,120 @@
1SLEEP(1)
20
3SLEEP(1000)
41
5SLEEP(2)
60
7SLEEP(1)
80
9SLEEP(1000)
101
11SLEEP(2)
120
13SLEEP(1)
140
15SLEEP(1000)
161
17SLEEP(2)
180
19SLEEP(1)
200
21SLEEP(1000)
221
23SLEEP(2)
240
25SLEEP(1)
260
27SLEEP(1000)
281
29SLEEP(2)
300
31SLEEP(1)
320
33SLEEP(1000)
341
35SLEEP(2)
360
37SLEEP(1)
380
39SLEEP(1000)
401
41SLEEP(2)
420
43SLEEP(1)
440
45SLEEP(1000)
461
47SLEEP(2)
480
49SLEEP(1)
500
51SLEEP(1000)
521
53SLEEP(2)
540
55SLEEP(1)
560
57SLEEP(1000)
581
59SLEEP(2)
600
61SLEEP(1)
620
63SLEEP(1000)
641
65SLEEP(2)
660
67SLEEP(1)
680
69SLEEP(1000)
701
71SLEEP(2)
720
73SLEEP(1)
740
75SLEEP(1000)
761
77SLEEP(2)
780
79SLEEP(1)
800
81SLEEP(1000)
821
83SLEEP(2)
840
85SLEEP(1)
860
87SLEEP(1000)
881
89SLEEP(2)
900
91SLEEP(1)
920
93SLEEP(1000)
941
95SLEEP(2)
960
97SLEEP(1)
980
99SLEEP(1000)
1001
101SLEEP(2)
1020
103SLEEP(1)
1040
105SLEEP(1000)
1061
107SLEEP(2)
1080
109SLEEP(1)
1100
111SLEEP(1000)
1121
113SLEEP(2)
1140
115SLEEP(1)
1160
117SLEEP(1000)
1181
119SLEEP(2)
1200
0121
=== added file 'Percona-Server/mysql-test/suite/sys_vars/r/sql_timeout_basic.result'
--- Percona-Server/mysql-test/suite/sys_vars/r/sql_timeout_basic.result 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/suite/sys_vars/r/sql_timeout_basic.result 2012-04-26 09:57:20 +0000
@@ -0,0 +1,164 @@
1SET @start_global_value = @@global.sql_timeout;
2SELECT @start_global_value;
3@start_global_value
40
5SET @start_session_value = @@session.sql_timeout;
6SELECT @start_session_value;
7@start_session_value
80
9'#--------------------FN_DYNVARS_083_01-------------------------#'
10SET @@global.sql_timeout = 100;
11SET @@global.sql_timeout = DEFAULT;
12SELECT @@global.sql_timeout;
13@@global.sql_timeout
140
15SET @@session.sql_timeout = 200;
16SET @@session.sql_timeout = DEFAULT;
17SELECT @@session.sql_timeout;
18@@session.sql_timeout
190
20'#--------------------FN_DYNVARS_083_02-------------------------#'
21SET @@global.sql_timeout = DEFAULT;
22SELECT @@global.sql_timeout = 0;
23@@global.sql_timeout = 0
241
25SET @@session.sql_timeout = DEFAULT;
26SELECT @@session.sql_timeout = 0;
27@@session.sql_timeout = 0
281
29'#--------------------FN_DYNVARS_083_03-------------------------#'
30SET @@global.sql_timeout = 100;
31SELECT @@global.sql_timeout;
32@@global.sql_timeout
33100
34SET @@global.sql_timeout = 200;
35SELECT @@global.sql_timeout;
36@@global.sql_timeout
37200
38SET @@global.sql_timeout = 65536;
39SELECT @@global.sql_timeout;
40@@global.sql_timeout
4165536
42SET @@global.sql_timeout = 4294967295;
43SELECT @@global.sql_timeout;
44@@global.sql_timeout
454294967295
46SET @@global.sql_timeout = 4294967294;
47SELECT @@global.sql_timeout;
48@@global.sql_timeout
494294967294
50'#--------------------FN_DYNVARS_083_04-------------------------#'
51SET @@session.sql_timeout = 100;
52SELECT @@session.sql_timeout;
53@@session.sql_timeout
54100
55SET @@session.sql_timeout = 200;
56SELECT @@session.sql_timeout;
57@@session.sql_timeout
58200
59SET @@session.sql_timeout = 4294967295;
60SELECT @@session.sql_timeout;
61@@session.sql_timeout
624294967295
63SET @@session.sql_timeout = 4294967294;
64SELECT @@session.sql_timeout;
65@@session.sql_timeout
664294967294
67SET @@session.sql_timeout = 65535;
68SELECT @@session.sql_timeout;
69@@session.sql_timeout
7065535
71'#------------------FN_DYNVARS_083_05-----------------------#'
72SET @@global.sql_timeout = 0;
73SELECT @@global.sql_timeout;
74@@global.sql_timeout
750
76SET @@global.sql_timeout = -1024;
77Warnings:
78Warning 1292 Truncated incorrect sql_timeout value: '-1024'
79SELECT @@global.sql_timeout;
80@@global.sql_timeout
810
82SET @@global.sql_timeout = 65530.34;
83ERROR 42000: Incorrect argument type to variable 'sql_timeout'
84SELECT @@global.sql_timeout;
85@@global.sql_timeout
860
87SET @@global.sql_timeout = test;
88ERROR 42000: Incorrect argument type to variable 'sql_timeout'
89SELECT @@global.sql_timeout;
90@@global.sql_timeout
910
92SET @@session.sql_timeout = 0;
93SELECT @@session.sql_timeout;
94@@session.sql_timeout
950
96SET @@session.sql_timeout = -2;
97Warnings:
98Warning 1292 Truncated incorrect sql_timeout value: '-2'
99SELECT @@session.sql_timeout;
100@@session.sql_timeout
1010
102SET @@session.sql_timeout = 65530.34;
103ERROR 42000: Incorrect argument type to variable 'sql_timeout'
104SELECT @@session.sql_timeout;
105@@session.sql_timeout
1060
107SET @@session.sql_timeout = test;
108ERROR 42000: Incorrect argument type to variable 'sql_timeout'
109SELECT @@session.sql_timeout;
110@@session.sql_timeout
1110
112'#------------------FN_DYNVARS_083_06-----------------------#'
113SELECT @@global.sql_timeout = VARIABLE_VALUE
114FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
115WHERE VARIABLE_NAME='sql_timeout';
116@@global.sql_timeout = VARIABLE_VALUE
1171
118'#------------------FN_DYNVARS_083_07-----------------------#'
119SELECT @@session.sql_timeout = VARIABLE_VALUE
120FROM INFORMATION_SCHEMA.SESSION_VARIABLES
121WHERE VARIABLE_NAME='sql_timeout';
122@@session.sql_timeout = VARIABLE_VALUE
1231
124'#------------------FN_DYNVARS_083_08-----------------------#'
125SET @@global.sql_timeout = TRUE;
126SELECT @@global.sql_timeout;
127@@global.sql_timeout
1281
129SET @@global.sql_timeout = FALSE;
130SELECT @@global.sql_timeout;
131@@global.sql_timeout
1320
133'#---------------------FN_DYNVARS_083_09----------------------#'
134SET @@global.sql_timeout = 100;
135SELECT @@sql_timeout = @@global.sql_timeout;
136@@sql_timeout = @@global.sql_timeout
1370
138'#---------------------FN_DYNVARS_083_10----------------------#'
139SET @@sql_timeout = 1000;
140SELECT @@sql_timeout = @@local.sql_timeout;
141@@sql_timeout = @@local.sql_timeout
1421
143SELECT @@local.sql_timeout = @@session.sql_timeout;
144@@local.sql_timeout = @@session.sql_timeout
1451
146'#---------------------FN_DYNVARS_083_11----------------------#'
147SET sql_timeout = 100;
148SELECT @@sql_timeout;
149@@sql_timeout
150100
151SELECT local.sql_timeout;
152ERROR 42S02: Unknown table 'local' in field list
153SELECT session.sql_timeout;
154ERROR 42S02: Unknown table 'session' in field list
155SELECT sql_timeout = @@session.sql_timeout;
156ERROR 42S22: Unknown column 'sql_timeout' in 'field list'
157SET @@global.sql_timeout = @start_global_value;
158SELECT @@global.sql_timeout;
159@@global.sql_timeout
1600
161SET @@session.sql_timeout = @start_session_value;
162SELECT @@session.sql_timeout;
163@@session.sql_timeout
1640
0165
=== added file 'Percona-Server/mysql-test/suite/sys_vars/t/sql_timeout_basic.test'
--- Percona-Server/mysql-test/suite/sys_vars/t/sql_timeout_basic.test 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/suite/sys_vars/t/sql_timeout_basic.test 2012-04-26 09:57:20 +0000
@@ -0,0 +1,210 @@
1############mysql-test\suite\sysvars\t\sql_timeout_basic.test##################
2# #
3# Variable Name: sql_timeout #
4# Scope: GLOBAL | SESSION #
5# Access Type: Dynamic #
6# Data Type: numeric #
7# Default Value: 0 #
8# Range: 1-4294967295 #
9# #
10# #
11# Creation Date: 2012-02-08 #
12# Author: Vlad Lesin #
13# #
14# Description: Test Cases of Dynamic System Variable sql_timeout #
15# that checks the behavior of this variable in the following ways#
16# * Default Value #
17# * Valid & Invalid values #
18# * Scope & Access method #
19# * Data Integrity #
20# #
21# Reference: none #
22# #
23# #
24###############################################################################
25
26--source include/load_sysvars.inc
27
28############################################################
29# START OF sql_timeout TESTS #
30############################################################
31
32
33#############################################################
34# Save initial value #
35#############################################################
36
37SET @start_global_value = @@global.sql_timeout;
38SELECT @start_global_value;
39SET @start_session_value = @@session.sql_timeout;
40SELECT @start_session_value;
41
42
43--echo '#--------------------FN_DYNVARS_083_01-------------------------#'
44#################################################################
45# Display the DEFAULT value of sql_timeout #
46#################################################################
47
48SET @@global.sql_timeout = 100;
49SET @@global.sql_timeout = DEFAULT;
50SELECT @@global.sql_timeout;
51
52SET @@session.sql_timeout = 200;
53SET @@session.sql_timeout = DEFAULT;
54SELECT @@session.sql_timeout;
55
56
57--echo '#--------------------FN_DYNVARS_083_02-------------------------#'
58#################################################################
59# Check the DEFAULT value of sql_timeout #
60#################################################################
61
62SET @@global.sql_timeout = DEFAULT;
63SELECT @@global.sql_timeout = 0;
64
65SET @@session.sql_timeout = DEFAULT;
66SELECT @@session.sql_timeout = 0;
67
68
69--echo '#--------------------FN_DYNVARS_083_03-------------------------#'
70###########################################################################
71# Change the value of sql_timeout to a valid value for GLOBAL Scope #
72###########################################################################
73
74SET @@global.sql_timeout = 100;
75SELECT @@global.sql_timeout;
76SET @@global.sql_timeout = 200;
77SELECT @@global.sql_timeout;
78SET @@global.sql_timeout = 65536;
79SELECT @@global.sql_timeout;
80SET @@global.sql_timeout = 4294967295;
81SELECT @@global.sql_timeout;
82SET @@global.sql_timeout = 4294967294;
83SELECT @@global.sql_timeout;
84
85
86--echo '#--------------------FN_DYNVARS_083_04-------------------------#'
87############################################################################
88# Change the value of sql_timeout to a valid value for SESSION Scope #
89############################################################################
90SET @@session.sql_timeout = 100;
91SELECT @@session.sql_timeout;
92SET @@session.sql_timeout = 200;
93SELECT @@session.sql_timeout;
94SET @@session.sql_timeout = 4294967295;
95SELECT @@session.sql_timeout;
96SET @@session.sql_timeout = 4294967294;
97SELECT @@session.sql_timeout;
98SET @@session.sql_timeout = 65535;
99SELECT @@session.sql_timeout;
100
101
102--echo '#------------------FN_DYNVARS_083_05-----------------------#'
103#############################################################
104# Change the value of sql_timeout to an invalid value #
105#############################################################
106
107SET @@global.sql_timeout = 0;
108SELECT @@global.sql_timeout;
109SET @@global.sql_timeout = -1024;
110SELECT @@global.sql_timeout;
111--Error ER_WRONG_TYPE_FOR_VAR
112SET @@global.sql_timeout = 65530.34;
113SELECT @@global.sql_timeout;
114--Error ER_WRONG_TYPE_FOR_VAR
115SET @@global.sql_timeout = test;
116SELECT @@global.sql_timeout;
117
118SET @@session.sql_timeout = 0;
119SELECT @@session.sql_timeout;
120SET @@session.sql_timeout = -2;
121SELECT @@session.sql_timeout;
122--Error ER_WRONG_TYPE_FOR_VAR
123SET @@session.sql_timeout = 65530.34;
124SELECT @@session.sql_timeout;
125
126--Error ER_WRONG_TYPE_FOR_VAR
127SET @@session.sql_timeout = test;
128SELECT @@session.sql_timeout;
129
130
131--echo '#------------------FN_DYNVARS_083_06-----------------------#'
132####################################################################
133# Check if the value in GLOBAL Table matches value in variable #
134####################################################################
135
136
137SELECT @@global.sql_timeout = VARIABLE_VALUE
138FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
139WHERE VARIABLE_NAME='sql_timeout';
140
141--echo '#------------------FN_DYNVARS_083_07-----------------------#'
142####################################################################
143# Check if the value in SESSION Table matches value in variable #
144####################################################################
145
146SELECT @@session.sql_timeout = VARIABLE_VALUE
147FROM INFORMATION_SCHEMA.SESSION_VARIABLES
148WHERE VARIABLE_NAME='sql_timeout';
149
150
151--echo '#------------------FN_DYNVARS_083_08-----------------------#'
152####################################################################
153# Check if TRUE and FALSE values can be used on variable #
154####################################################################
155
156SET @@global.sql_timeout = TRUE;
157SELECT @@global.sql_timeout;
158SET @@global.sql_timeout = FALSE;
159SELECT @@global.sql_timeout;
160
161
162--echo '#---------------------FN_DYNVARS_083_09----------------------#'
163#############################################################################
164# Check if accessing variable with and without GLOBAL point #
165# to same variable #
166#############################################################################
167
168SET @@global.sql_timeout = 100;
169SELECT @@sql_timeout = @@global.sql_timeout;
170
171
172--echo '#---------------------FN_DYNVARS_083_10----------------------#'
173#############################################################################
174# Check if accessing variable with SESSION,LOCAL and without SCOPE points #
175# to same session variable #
176#############################################################################
177
178SET @@sql_timeout = 1000;
179SELECT @@sql_timeout = @@local.sql_timeout;
180SELECT @@local.sql_timeout = @@session.sql_timeout;
181
182
183--echo '#---------------------FN_DYNVARS_083_11----------------------#'
184############################################################################
185# Check if sql_timeout can be accessed with and without @@ sign #
186############################################################################
187
188SET sql_timeout = 100;
189SELECT @@sql_timeout;
190--Error ER_UNKNOWN_TABLE
191SELECT local.sql_timeout;
192--Error ER_UNKNOWN_TABLE
193SELECT session.sql_timeout;
194--Error ER_BAD_FIELD_ERROR
195SELECT sql_timeout = @@session.sql_timeout;
196
197
198####################################
199# Restore initial value #
200####################################
201
202SET @@global.sql_timeout = @start_global_value;
203SELECT @@global.sql_timeout;
204SET @@session.sql_timeout = @start_session_value;
205SELECT @@session.sql_timeout;
206
207
208#############################################################
209# END OF sql_timeout TESTS #
210#############################################################
0211
=== added file 'Percona-Server/mysql-test/t/percona_sql_timeout.test'
--- Percona-Server/mysql-test/t/percona_sql_timeout.test 1970-01-01 00:00:00 +0000
+++ Percona-Server/mysql-test/t/percona_sql_timeout.test 2012-04-26 09:57:20 +0000
@@ -0,0 +1,44 @@
1#
2# SQL_TIMEOUT test
3#
4# SQL_TIMEOUT is a session variable or
5# query keyword which sets the time
6# limit for query execution.
7
8# Save the initial number of concurrent sessions
9--source include/count_sessions.inc
10
11
12--disable_query_log
13
14--let $sessions_count=20
15
16--let $i=$sessions_count
17while ($i) {
18--dec $i
19
20--let $connection_name=connection_$i
21--connect ($connection_name,localhost,root,,)
22--delimiter +++
23 let $statement=
24 SELECT SLEEP(1);
25 SET @@SESSION.SQL_TIMEOUT = 1;
26 SELECT SLEEP(1000);
27 SET @@SESSION.SQL_TIMEOUT = 0;
28 SELECT SLEEP(2);
29+++
30--delimiter ;
31--send_eval $statement
32}
33
34--let $i=$sessions_count
35while ($i) {
36--dec $i
37--let $connection_name=connection_$i
38--connection $connection_name
39--reap
40--disconnect $connection_name
41}
42
43--connection default
44--source include/wait_until_count_sessions.inc
045
=== modified file 'Percona-Server/sql/CMakeLists.txt'
--- Percona-Server/sql/CMakeLists.txt 2012-04-19 16:51:34 +0000
+++ Percona-Server/sql/CMakeLists.txt 2012-04-26 09:57:20 +0000
@@ -76,7 +76,7 @@
76 sql_profile.cc event_parse_data.cc sql_alter.cc76 sql_profile.cc event_parse_data.cc sql_alter.cc
77 sql_signal.cc rpl_handler.cc mdl.cc sql_admin.cc77 sql_signal.cc rpl_handler.cc mdl.cc sql_admin.cc
78 transaction.cc sys_vars.cc sql_truncate.cc datadict.cc78 transaction.cc sys_vars.cc sql_truncate.cc datadict.cc
79 sql_reload.cc79 sql_reload.cc sql_timeout.cc
80 ${GEN_SOURCES}80 ${GEN_SOURCES}
81 ${MYSYS_LIBWRAP_SOURCE})81 ${MYSYS_LIBWRAP_SOURCE})
8282
8383
=== modified file 'Percona-Server/sql/mysqld.cc'
--- Percona-Server/sql/mysqld.cc 2012-04-19 16:51:34 +0000
+++ Percona-Server/sql/mysqld.cc 2012-04-26 09:57:20 +0000
@@ -71,6 +71,8 @@
7171
72#include "query_response_time.h"72#include "query_response_time.h"
7373
74#include "sql_timeout.h"
75
74#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE76#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
75#include "../storage/perfschema/pfs_server.h"77#include "../storage/perfschema/pfs_server.h"
76#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */78#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
@@ -671,6 +673,7 @@
671mysql_rwlock_t LOCK_system_variables_hash;673mysql_rwlock_t LOCK_system_variables_hash;
672mysql_cond_t COND_thread_count;674mysql_cond_t COND_thread_count;
673pthread_t signal_thread;675pthread_t signal_thread;
676pthread_t sql_timeout_thread;
674pthread_attr_t connection_attrib;677pthread_attr_t connection_attrib;
675mysql_mutex_t LOCK_server_started;678mysql_mutex_t LOCK_server_started;
676mysql_cond_t COND_server_started;679mysql_cond_t COND_server_started;
@@ -1439,6 +1442,7 @@
1439 */1442 */
1440 wait_for_signal_thread_to_end();1443 wait_for_signal_thread_to_end();
1441 mysql_audit_finalize();1444 mysql_audit_finalize();
1445 sql_timeout_monitor.exit();
1442 clean_up_mutexes();1446 clean_up_mutexes();
1443 clean_up_error_log_mutex();1447 clean_up_error_log_mutex();
1444#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE1448#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
@@ -4289,6 +4293,48 @@
4289}4293}
4290#endif//DBUG_OFF4294#endif//DBUG_OFF
42914295
4296
4297pthread_handler_t sql_timeout_thread_func(void *arg __attribute__((unused)))
4298{
4299 my_thread_init();
4300 sql_timeout_monitor.init();
4301 /* SQL_TIMEOUT loop */
4302 sql_timeout_monitor.monitor();
4303 sql_timeout_monitor.deinit();
4304 my_thread_end();
4305 return(0);
4306}
4307
4308/**
4309 Start SQL_TIMEOUT monitor loop in a separate thread.
4310*/
4311static void start_sql_timeout_thread(void)
4312{
4313 int error;
4314 pthread_attr_t thr_attr;
4315 DBUG_ENTER("start_sql_timeout_thread");
4316 (void) pthread_attr_init(&thr_attr);
4317 (void) pthread_attr_setdetachstate(&thr_attr, PTHREAD_CREATE_DETACHED);
4318 pthread_attr_setstacksize(&thr_attr, my_thread_stack_size);
4319 mysql_mutex_lock(&LOCK_thread_count);
4320 if ((error= mysql_thread_create(key_thread_sql_timeout,
4321 &sql_timeout_thread,
4322 &thr_attr,
4323 sql_timeout_thread_func,
4324 0)))
4325 {
4326 sql_print_error("Can't create sql_timeout-thread (error %d, errno: %d)",
4327 error,errno);
4328 exit(1);
4329 }
4330 /* Waiting for monitor thread start */
4331 mysql_cond_wait(&COND_thread_count, &LOCK_thread_count);
4332 mysql_mutex_unlock(&LOCK_thread_count);
4333
4334 (void) pthread_attr_destroy(&thr_attr);
4335 DBUG_VOID_RETURN;
4336}
4337
4292#ifdef __WIN__4338#ifdef __WIN__
4293int win_main(int argc, char **argv)4339int win_main(int argc, char **argv)
4294#else4340#else
@@ -4579,6 +4625,7 @@
4579 */4625 */
4580 error_handler_hook= my_message_sql;4626 error_handler_hook= my_message_sql;
4581 start_signal_handler(); // Creates pidfile4627 start_signal_handler(); // Creates pidfile
4628 start_sql_timeout_thread();
45824629
4583 if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||4630 if (mysql_rm_tmp_tables() || acl_init(opt_noacl) ||
4584 my_tz_init((THD *)0, default_tz_name, opt_bootstrap))4631 my_tz_init((THD *)0, default_tz_name, opt_bootstrap))
@@ -7879,6 +7926,7 @@
7879 key_LOCK_prepared_stmt_count,7926 key_LOCK_prepared_stmt_count,
7880 key_LOCK_rpl_status, key_LOCK_server_started, key_LOCK_status,7927 key_LOCK_rpl_status, key_LOCK_server_started, key_LOCK_status,
7881 key_LOCK_system_variables_hash, key_LOCK_table_share, key_LOCK_thd_data,7928 key_LOCK_system_variables_hash, key_LOCK_table_share, key_LOCK_thd_data,
7929 key_LOCK_sql_timeout_monitor,
7882 key_LOCK_user_conn, key_LOCK_uuid_generator, key_LOG_LOCK_log,7930 key_LOCK_user_conn, key_LOCK_uuid_generator, key_LOG_LOCK_log,
7883 key_master_info_data_lock, key_master_info_run_lock,7931 key_master_info_data_lock, key_master_info_run_lock,
7884 key_master_info_sleep_lock,7932 key_master_info_sleep_lock,
@@ -7931,6 +7979,9 @@
7931 { &key_LOCK_prepared_stmt_count, "LOCK_prepared_stmt_count", PSI_FLAG_GLOBAL},7979 { &key_LOCK_prepared_stmt_count, "LOCK_prepared_stmt_count", PSI_FLAG_GLOBAL},
7932 { &key_LOCK_rpl_status, "LOCK_rpl_status", PSI_FLAG_GLOBAL},7980 { &key_LOCK_rpl_status, "LOCK_rpl_status", PSI_FLAG_GLOBAL},
7933 { &key_LOCK_server_started, "LOCK_server_started", PSI_FLAG_GLOBAL},7981 { &key_LOCK_server_started, "LOCK_server_started", PSI_FLAG_GLOBAL},
7982 { &key_LOCK_sql_timeout_monitor,
7983 "Sql_timeout_monitor::LOCK_timeouts",
7984 PSI_FLAG_GLOBAL},
7934 { &key_LOCK_status, "LOCK_status", PSI_FLAG_GLOBAL},7985 { &key_LOCK_status, "LOCK_status", PSI_FLAG_GLOBAL},
7935 { &key_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL},7986 { &key_LOCK_system_variables_hash, "LOCK_system_variables_hash", PSI_FLAG_GLOBAL},
7936 { &key_LOCK_table_share, "LOCK_table_share", PSI_FLAG_GLOBAL},7987 { &key_LOCK_table_share, "LOCK_table_share", PSI_FLAG_GLOBAL},
@@ -7991,6 +8042,7 @@
7991 key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache;8042 key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache;
7992PSI_cond_key key_RELAYLOG_update_cond;8043PSI_cond_key key_RELAYLOG_update_cond;
7993PSI_cond_key key_COND_wakeup_ready, key_COND_queue_busy;8044PSI_cond_key key_COND_wakeup_ready, key_COND_queue_busy;
8045PSI_cond_key key_COND_sql_timeout_monitor;
79948046
7995static PSI_cond_info all_server_conds[]=8047static PSI_cond_info all_server_conds[]=
7996{8048{
@@ -8010,6 +8062,9 @@
8010 { &key_COND_queue_busy, "COND_queue_busy", PSI_FLAG_GLOBAL},8062 { &key_COND_queue_busy, "COND_queue_busy", PSI_FLAG_GLOBAL},
8011 { &key_COND_rpl_status, "COND_rpl_status", PSI_FLAG_GLOBAL},8063 { &key_COND_rpl_status, "COND_rpl_status", PSI_FLAG_GLOBAL},
8012 { &key_COND_server_started, "COND_server_started", PSI_FLAG_GLOBAL},8064 { &key_COND_server_started, "COND_server_started", PSI_FLAG_GLOBAL},
8065 { &key_COND_sql_timeout_monitor,
8066 "Sql_timeout_monitor::COND_timeouts",
8067 PSI_FLAG_GLOBAL},
8013 { &key_COND_wakeup_ready, "THD::COND_wakeup_ready", 0},8068 { &key_COND_wakeup_ready, "THD::COND_wakeup_ready", 0},
8014 { &key_delayed_insert_cond, "Delayed_insert::cond", 0},8069 { &key_delayed_insert_cond, "Delayed_insert::cond", 0},
8015 { &key_delayed_insert_cond_client, "Delayed_insert::cond_client", 0},8070 { &key_delayed_insert_cond_client, "Delayed_insert::cond_client", 0},
@@ -8032,7 +8087,8 @@
80328087
8033PSI_thread_key key_thread_bootstrap, key_thread_delayed_insert,8088PSI_thread_key key_thread_bootstrap, key_thread_delayed_insert,
8034 key_thread_handle_manager, key_thread_main,8089 key_thread_handle_manager, key_thread_main,
8035 key_thread_one_connection, key_thread_signal_hand;8090 key_thread_one_connection, key_thread_signal_hand,
8091 key_thread_sql_timeout;
80368092
8037static PSI_thread_info all_server_threads[]=8093static PSI_thread_info all_server_threads[]=
8038{8094{
@@ -8057,7 +8113,8 @@
8057 { &key_thread_handle_manager, "manager", PSI_FLAG_GLOBAL},8113 { &key_thread_handle_manager, "manager", PSI_FLAG_GLOBAL},
8058 { &key_thread_main, "main", PSI_FLAG_GLOBAL},8114 { &key_thread_main, "main", PSI_FLAG_GLOBAL},
8059 { &key_thread_one_connection, "one_connection", 0},8115 { &key_thread_one_connection, "one_connection", 0},
8060 { &key_thread_signal_hand, "signal_handler", PSI_FLAG_GLOBAL}8116 { &key_thread_signal_hand, "signal_handler", PSI_FLAG_GLOBAL},
8117 { &key_thread_sql_timeout, "sql_timeout", PSI_FLAG_GLOBAL},
8061};8118};
80628119
8063#ifdef HAVE_MMAP8120#ifdef HAVE_MMAP
80648121
=== modified file 'Percona-Server/sql/mysqld.h'
--- Percona-Server/sql/mysqld.h 2012-04-19 16:51:34 +0000
+++ Percona-Server/sql/mysqld.h 2012-04-26 09:57:20 +0000
@@ -269,6 +269,7 @@
269 key_LOCK_prepared_stmt_count,269 key_LOCK_prepared_stmt_count,
270 key_LOCK_rpl_status, key_LOCK_server_started, key_LOCK_status,270 key_LOCK_rpl_status, key_LOCK_server_started, key_LOCK_status,
271 key_LOCK_table_share, key_LOCK_thd_data,271 key_LOCK_table_share, key_LOCK_thd_data,
272 key_LOCK_sql_timeout_monitor,
272 key_LOCK_user_conn, key_LOCK_uuid_generator, key_LOG_LOCK_log,273 key_LOCK_user_conn, key_LOCK_uuid_generator, key_LOG_LOCK_log,
273 key_master_info_data_lock, key_master_info_run_lock,274 key_master_info_data_lock, key_master_info_run_lock,
274 key_master_info_sleep_lock,275 key_master_info_sleep_lock,
@@ -302,10 +303,13 @@
302 key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache;303 key_COND_thread_count, key_COND_thread_cache, key_COND_flush_thread_cache;
303extern PSI_cond_key key_RELAYLOG_update_cond;304extern PSI_cond_key key_RELAYLOG_update_cond;
304extern PSI_cond_key key_COND_wakeup_ready, key_COND_queue_busy;305extern PSI_cond_key key_COND_wakeup_ready, key_COND_queue_busy;
306extern PSI_cond_key key_COND_sql_timeout_monitor;
307
305308
306extern PSI_thread_key key_thread_bootstrap, key_thread_delayed_insert,309extern PSI_thread_key key_thread_bootstrap, key_thread_delayed_insert,
307 key_thread_handle_manager, key_thread_kill_server, key_thread_main,310 key_thread_handle_manager, key_thread_kill_server, key_thread_main,
308 key_thread_one_connection, key_thread_signal_hand;311 key_thread_one_connection, key_thread_signal_hand,
312 key_thread_sql_timeout;
309313
310#ifdef HAVE_MMAP314#ifdef HAVE_MMAP
311extern PSI_file_key key_file_map;315extern PSI_file_key key_file_map;
312316
=== modified file 'Percona-Server/sql/sql_class.cc'
--- Percona-Server/sql/sql_class.cc 2012-04-19 16:51:34 +0000
+++ Percona-Server/sql/sql_class.cc 2012-04-26 09:57:20 +0000
@@ -60,6 +60,7 @@
60#include "debug_sync.h"60#include "debug_sync.h"
61#include "sql_parse.h" // is_update_query61#include "sql_parse.h" // is_update_query
62#include "sql_callback.h"62#include "sql_callback.h"
63#include "sql_timeout.h"
6364
64/*65/*
65 The following is used to initialise Table_ident with a internal66 The following is used to initialise Table_ident with a internal
@@ -871,6 +872,7 @@
871 lex->current_select= 0;872 lex->current_select= 0;
872 start_time=(time_t) 0;873 start_time=(time_t) 0;
873 start_utime= prior_thr_create_utime= 0L;874 start_utime= prior_thr_create_utime= 0L;
875 sql_timeout_expire= 0;
874 utime_after_lock= 0L;876 utime_after_lock= 0L;
875 current_linfo = 0;877 current_linfo = 0;
876 slave_thread = 0;878 slave_thread = 0;
@@ -1490,6 +1492,9 @@
1490{1492{
1491 THD_CHECK_SENTRY(this);1493 THD_CHECK_SENTRY(this);
1492 DBUG_ENTER("~THD()");1494 DBUG_ENTER("~THD()");
1495
1496 sql_timeout_monitor.remove(this);
1497
1493 /* Ensure that no one is using THD */1498 /* Ensure that no one is using THD */
1494 mysql_mutex_lock(&LOCK_thd_data);1499 mysql_mutex_lock(&LOCK_thd_data);
1495 mysys_var=0; // Safety (shouldn't be needed)1500 mysys_var=0; // Safety (shouldn't be needed)
14961501
=== modified file 'Percona-Server/sql/sql_class.h'
--- Percona-Server/sql/sql_class.h 2012-04-18 23:26:38 +0000
+++ Percona-Server/sql/sql_class.h 2012-04-26 09:57:20 +0000
@@ -492,6 +492,7 @@
492 ulong trans_prealloc_size;492 ulong trans_prealloc_size;
493 ulong log_warnings;493 ulong log_warnings;
494 ulong group_concat_max_len;494 ulong group_concat_max_len;
495 ulong sql_timeout;
495496
496 ulong binlog_format; ///< binlog format for this thd (see enum_binlog_format)497 ulong binlog_format; ///< binlog format for this thd (see enum_binlog_format)
497 my_bool binlog_direct_non_trans_update;498 my_bool binlog_direct_non_trans_update;
@@ -1653,6 +1654,11 @@
1653 /* remote (peer) port */1654 /* remote (peer) port */
1654 uint16 peer_port;1655 uint16 peer_port;
1655 time_t start_time, user_time;1656 time_t start_time, user_time;
1657 /*
1658 Expire time in microseconds for sql_timeout monitor thread. The 0 value
1659 means the current thread is not monitored by sql_timeout monitor.
1660 */
1661 ulonglong sql_timeout_expire;
1656 // track down slow pthread_create1662 // track down slow pthread_create
1657 ulonglong prior_thr_create_utime, thr_create_utime;1663 ulonglong prior_thr_create_utime, thr_create_utime;
1658 ulonglong start_utime, utime_after_lock;1664 ulonglong start_utime, utime_after_lock;
16591665
=== modified file 'Percona-Server/sql/sql_parse.cc'
--- Percona-Server/sql/sql_parse.cc 2012-04-19 16:51:34 +0000
+++ Percona-Server/sql/sql_parse.cc 2012-04-26 09:57:20 +0000
@@ -95,6 +95,7 @@
95#include "debug_sync.h"95#include "debug_sync.h"
96#include "probes_mysql.h"96#include "probes_mysql.h"
97#include "set_var.h"97#include "set_var.h"
98#include "sql_timeout.h"
9899
99#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")100#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
100101
@@ -5801,7 +5802,9 @@
5801 (char *) thd->security_ctx->host_or_ip,5802 (char *) thd->security_ctx->host_or_ip,
5802 0);5803 0);
58035804
5805 sql_timeout_monitor.add(thd);
5804 error= mysql_execute_command(thd);5806 error= mysql_execute_command(thd);
5807 sql_timeout_monitor.remove(thd);
5805 MYSQL_QUERY_EXEC_DONE(error);5808 MYSQL_QUERY_EXEC_DONE(error);
5806 }5809 }
5807 }5810 }
58085811
=== added file 'Percona-Server/sql/sql_timeout.cc'
--- Percona-Server/sql/sql_timeout.cc 1970-01-01 00:00:00 +0000
+++ Percona-Server/sql/sql_timeout.cc 2012-04-26 09:57:20 +0000
@@ -0,0 +1,228 @@
1#include "sql_timeout.h"
2#include "my_sys.h"
3#include "mysqld.h"
4
5#define INITIAL_QUEUE_SIZE 1000
6
7/**
8 Is used in priority queue to compare THDs by expire time.
9*/
10
11static int compare_thd(void *not_used __attribute__((unused)),
12 uchar *a_ptr,uchar* b_ptr)
13{
14 ulonglong a= ((THD *) a_ptr)->sql_timeout_expire;
15 ulonglong b= ((THD *) b_ptr)->sql_timeout_expire;
16 return (a < b) ? -1 : (a == b) ? 0 : 1;
17}
18
19
20/**
21 Initialize SQL_TIMEOUT monitor.
22
23 @note This function must be called before any actions with monitor.
24*/
25
26void Sql_timeout_monitor::init()
27{
28 need_to_exit= false;
29 completed= true;
30 mysql_mutex_init(key_LOCK_sql_timeout_monitor,
31 &LOCK_queue,
32 MY_MUTEX_INIT_FAST);
33 mysql_cond_init(key_COND_sql_timeout_monitor, &COND_queue, NULL);
34 /*
35 THD is not POD type. Thats why offsetof(...) is not used here to get
36 priority member offset for the queue. The 0 offset is passed as an
37 argument but compare_thd(...) function does properly comparison.
38 */
39 init_queue_ex(&queue, INITIAL_QUEUE_SIZE + 1, 0, 0,
40 compare_thd, NULL, INITIAL_QUEUE_SIZE + 1);
41}
42
43
44/**
45 Deinitialize SQL_TIMEOUT monitor.
46
47 Clean up and destroy all monitor data.
48*/
49
50void Sql_timeout_monitor::deinit()
51{
52 mysql_mutex_lock(&LOCK_queue);
53 for (size_t i= 0; i < queue.elements; ++i)
54 ((THD *)queue_element(&queue, i))->sql_timeout_expire= 0;
55 queue_remove_all(&queue);
56 delete_queue(&queue);
57 mysql_mutex_unlock(&LOCK_queue);
58 mysql_cond_destroy(&COND_queue);
59 mysql_mutex_destroy(&LOCK_queue);
60}
61
62
63/**
64 SQL_TIMEOUT monitor loop.
65
66 If thread wants to be monitored it must add itself to the monitor
67 before query execution and remove after. The monitor holds all
68 threads in prority queue. The priority is an expiration time of
69 query execution. The monitor idles till the top expiration time
70 in the queue. Then it kills all theads with expired execution time.
71 If there are no threads in the queue the monitor thread completely
72 idles.
73
74 This function must be invoked in a separate thread. To exit from
75 this function Sql_timeout_monitor::exit() must be called.
76*/
77
78void Sql_timeout_monitor::monitor()
79{
80 completed= false;
81
82 /* Signal monitor is started */
83 mysql_mutex_lock(&LOCK_thread_count);
84 mysql_mutex_unlock(&LOCK_thread_count);
85 mysql_cond_broadcast(&COND_thread_count);
86
87 mysql_mutex_lock(&LOCK_queue);
88 while (!need_to_exit)
89 {
90 int error= 0;
91
92 if (queue.elements)
93 {
94 THD *thd;
95 ulonglong sleep_time;
96 struct timespec abstime;
97 ulonglong now= my_micro_time();
98
99 while ( (thd= (THD *) queue_top(&queue))->sql_timeout_expire <= now)
100 {
101 mysql_mutex_lock(&thd->LOCK_thd_data);
102 thd->awake(THD::KILL_QUERY);
103 mysql_mutex_unlock(&thd->LOCK_thd_data);
104 queue_remove(&queue, 0);
105 /*
106 Mark the thread as removed from SQL_TIMEOUT monitor.
107 So there is no need to remove it in
108 Sql_timeout_monitor::remove(THD *thd)
109 after query execution.
110 */
111 thd->sql_timeout_expire= 0;
112 if (!queue.elements)
113 break;
114 }
115
116 if (!queue.elements)
117 continue;
118
119 sleep_time= thd->sql_timeout_expire - now;
120 set_timespec_nsec(abstime, sleep_time);
121 error= mysql_cond_timedwait(&COND_queue, &LOCK_queue, &abstime);
122 }
123 else
124 error= mysql_cond_wait(&COND_queue, &LOCK_queue);
125
126 if (error && error != EINTR && error != ETIMEDOUT && error != ETIME)
127 {
128 if (!shutdown_in_progress && !abort_loop)
129 sql_print_error("The error %d (%s)occured on wait condition variable "
130 "in sql_timeout monitor. Exit thread.",
131 error, strerror((ulong)error));
132 break;
133 }
134 }
135
136 mysql_mutex_unlock(&LOCK_queue);
137 completed= true;
138}
139
140
141/**
142 Add connection thread to the SQL_TIMEOUT monitor.
143
144 Add connection thread to the SQL_TIMEOUT monitor.
145 Do nothing if SQL_TIMEOUT is 0 or the thread has already
146 added.
147
148 @param thd pointer to the thread to add
149*/
150
151void Sql_timeout_monitor::add(THD *thd)
152{
153 DBUG_ASSERT(thd);
154
155 ulong timeout= thd->variables.sql_timeout;
156
157 if (thd->sql_timeout_expire || !timeout)
158 return;
159
160 mysql_mutex_lock(&LOCK_queue);
161 thd->sql_timeout_expire= my_micro_time() + (ulonglong)timeout*1000000;
162
163 if (queue_insert_safe(&queue, (uchar *)thd))
164 {
165 thd->sql_timeout_expire= 0;
166 sql_print_error("The memory is not enough to put the query into "
167 "SQL_TIMEOUT queue");
168 }
169 else
170 mysql_cond_broadcast(&COND_queue);
171
172 mysql_mutex_unlock(&LOCK_queue);
173}
174
175
176
177/**
178 Remove connection thread from the SQL_TIMEOUT monitor.
179
180 Remove connection thread from the SQL_TIMEOUT monitor.
181 Do nothing if the thread is not added.
182
183 @param thd pointer to the thread to remove
184*/
185
186void Sql_timeout_monitor::remove(THD *thd)
187{
188 size_t i;
189
190 DBUG_ASSERT(thd);
191
192 if (!thd->sql_timeout_expire)
193 return;
194
195 mysql_mutex_lock(&LOCK_queue);
196
197 for (i= 0; i < queue.elements; ++i)
198 if (((THD *) queue_element(&queue, i)) == thd)
199 break;
200 /*
201 It may be deleted in monitor thread between thd->sql_timeout_expire == 0
202 condition checking and mutex locking in current thread.
203 */
204 if (i < queue.elements)
205 queue_remove(&queue, i);
206
207 thd->sql_timeout_expire= 0;
208
209 mysql_mutex_unlock(&LOCK_queue);
210}
211
212
213/**
214 Signal to the monitor thread to exit .
215*/
216
217void Sql_timeout_monitor::exit()
218{
219 need_to_exit= true;
220 if (completed)
221 return;
222 mysql_mutex_lock(&LOCK_queue);
223 mysql_cond_broadcast(&COND_queue);
224 mysql_mutex_unlock(&LOCK_queue);
225}
226
227/* The global SQL_TIMEOUT monitor object */
228Sql_timeout_monitor sql_timeout_monitor;
0229
=== added file 'Percona-Server/sql/sql_timeout.h'
--- Percona-Server/sql/sql_timeout.h 1970-01-01 00:00:00 +0000
+++ Percona-Server/sql/sql_timeout.h 2012-04-26 09:57:20 +0000
@@ -0,0 +1,55 @@
1#ifndef SQL_TIMEOUT_INCLUDED
2#define SQL_TIMEOUT_INCLUDED
3#include "sql_class.h"
4#include "my_pthread.h"
5#include "queues.h"
6#include "hash.h"
7
8/**
9 @class Sql_timeout_monitor
10 The class to monitor threads for query execution time
11 in case of SQL_TIMEOUT session variable is set.
12
13 EXAMPLE
14 @verbatim
15 SET @@SESSION.SQL_TIMEOUT=5;
16 SELECT SLEEP(10);
17 @endverbatim
18*/
19
20class Sql_timeout_monitor
21{
22public:
23 void init();
24 void deinit();
25
26 void monitor();
27 void add(THD *thd);
28 void remove(THD *thd);
29 void exit();
30
31private:
32 int find(THD *thd);
33 /* Is locked during work with queue. */
34 mysql_mutex_t LOCK_queue;
35 /*
36 Condition variable to wake up monitor
37 thread when item is added to the queue
38 or exit from monitor() function
39 is requered.
40 */
41 mysql_cond_t COND_queue;
42 /*
43 The flag for notifying the monitor thread
44 about exit is requred.
45 */
46 volatile bool need_to_exit;
47 /* Shows that monitor thread is completed. */
48 volatile bool completed;
49 /* Priority queue of Sql_timeout_info objects */
50 QUEUE queue;
51};
52
53/* The global SQL_TIMEOUT monitor object */
54extern Sql_timeout_monitor sql_timeout_monitor;
55#endif /* SQL_TIMEOUT_INCLUDED */
056
=== modified file 'Percona-Server/sql/sys_vars.cc'
--- Percona-Server/sql/sys_vars.cc 2012-04-19 16:51:34 +0000
+++ Percona-Server/sql/sys_vars.cc 2012-04-26 09:57:20 +0000
@@ -2825,6 +2825,12 @@
2825 SESSION_VAR(group_concat_max_len), CMD_LINE(REQUIRED_ARG),2825 SESSION_VAR(group_concat_max_len), CMD_LINE(REQUIRED_ARG),
2826 VALID_RANGE(4, ULONG_MAX), DEFAULT(1024), BLOCK_SIZE(1));2826 VALID_RANGE(4, ULONG_MAX), DEFAULT(1024), BLOCK_SIZE(1));
28272827
2828static Sys_var_ulong Sys_sql_timeout(
2829 "sql_timeout",
2830 "Timeout in seconds to wait before killing query.",
2831 SESSION_VAR(sql_timeout), CMD_LINE(REQUIRED_ARG),
2832 VALID_RANGE(0, ULONG_MAX), DEFAULT(0), BLOCK_SIZE(1));
2833
2828static char *glob_hostname_ptr;2834static char *glob_hostname_ptr;
2829static Sys_var_charptr Sys_hostname(2835static Sys_var_charptr Sys_hostname(
2830 "hostname", "Server host name",2836 "hostname", "Server host name",

Subscribers

People subscribed via source and target branches