mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
Merge mysql.com:/home/mydev/mysql-5.0
into mysql.com:/home/mydev/mysql-5.0-bug11527
This commit is contained in:
commit
f8862a056b
8 changed files with 221 additions and 92 deletions
|
@ -1647,19 +1647,20 @@ int do_sleep(struct st_query *query, my_bool real_sleep)
|
|||
char *p= query->first_argument;
|
||||
char *sleep_start, *sleep_end= query->end;
|
||||
double sleep_val;
|
||||
char *cmd = (real_sleep ? "real_sleep" : "sleep");
|
||||
|
||||
while (my_isspace(charset_info, *p))
|
||||
p++;
|
||||
if (!*p)
|
||||
die("Missing argument to %s", cmd);
|
||||
die("Missing argument to %.*s", query->first_word_len, query->query);
|
||||
sleep_start= p;
|
||||
/* Check that arg starts with a digit, not handled by my_strtod */
|
||||
if (!my_isdigit(charset_info, *sleep_start))
|
||||
die("Invalid argument to %s \"%s\"", cmd, query->first_argument);
|
||||
die("Invalid argument to %.*s \"%s\"", query->first_word_len, query->query,
|
||||
query->first_argument);
|
||||
sleep_val= my_strtod(sleep_start, &sleep_end, &error);
|
||||
if (error)
|
||||
die("Invalid argument to %s \"%s\"", cmd, query->first_argument);
|
||||
die("Invalid argument to %.*s \"%s\"", query->first_word_len, query->query,
|
||||
query->first_argument);
|
||||
|
||||
/* Fixed sleep time selected by --sleep option */
|
||||
if (opt_sleep && !real_sleep)
|
||||
|
@ -2529,8 +2530,8 @@ my_bool end_of_query(int c)
|
|||
size size of the buffer i.e max size to read
|
||||
|
||||
DESCRIPTION
|
||||
This function actually reads several lines an adds them to the
|
||||
buffer buf. It will continue to read until it finds what it believes
|
||||
This function actually reads several lines and adds them to the
|
||||
buffer buf. It continues to read until it finds what it believes
|
||||
is a complete query.
|
||||
|
||||
Normally that means it will read lines until it reaches the
|
||||
|
@ -3760,7 +3761,7 @@ static void handle_no_error(struct st_query *q)
|
|||
command - currrent command pointer
|
||||
query - query string to execute
|
||||
query_len - length query string to execute
|
||||
ds - output buffer wherte to store result form query
|
||||
ds - output buffer where to store result form query
|
||||
|
||||
RETURN VALUE
|
||||
error - function will not return
|
||||
|
@ -3778,7 +3779,7 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command,
|
|||
DBUG_PRINT("query", ("'%-.60s'", query));
|
||||
|
||||
/*
|
||||
Init a new stmt if it's not alreday one created for this connectoon
|
||||
Init a new stmt if it's not already one created for this connection
|
||||
*/
|
||||
if(!(stmt= cur_con->stmt))
|
||||
{
|
||||
|
@ -3867,7 +3868,7 @@ static void run_query_stmt(MYSQL *mysql, struct st_query *command,
|
|||
goto end;
|
||||
}
|
||||
|
||||
/* If we got here the statement was both executed and read succeesfully */
|
||||
/* If we got here the statement was both executed and read successfully */
|
||||
handle_no_error(command);
|
||||
if (!disable_result_log)
|
||||
{
|
||||
|
@ -4594,7 +4595,7 @@ int main(int argc, char **argv)
|
|||
case Q_QUERY_HORIZONTAL:
|
||||
{
|
||||
my_bool old_display_result_vertically= display_result_vertically;
|
||||
/* fix up query pointer if this is * first iteration for this line */
|
||||
/* fix up query pointer if this is first iteration for this line */
|
||||
if (q->query == q->query_buf)
|
||||
q->query += q->first_word_len + 1;
|
||||
display_result_vertically= (q->type==Q_QUERY_VERTICAL);
|
||||
|
@ -4639,15 +4640,15 @@ int main(int argc, char **argv)
|
|||
case Q_SEND:
|
||||
if (!q->query[q->first_word_len])
|
||||
{
|
||||
/* This happens when we use 'send' on it's own line */
|
||||
/* This happens when we use 'send' on its own line */
|
||||
q_send_flag=1;
|
||||
break;
|
||||
}
|
||||
/* fix up query pointer if this is * first iteration for this line */
|
||||
/* fix up query pointer if this is first iteration for this line */
|
||||
if (q->query == q->query_buf)
|
||||
q->query += q->first_word_len;
|
||||
/*
|
||||
run_query() can execute a query partially, depending on the flags
|
||||
run_query() can execute a query partially, depending on the flags.
|
||||
QUERY_SEND flag without QUERY_REAP tells it to just send the
|
||||
query and read the result some time later when reap instruction
|
||||
is given on this connection.
|
||||
|
@ -4731,7 +4732,7 @@ int main(int argc, char **argv)
|
|||
break;
|
||||
case Q_ENABLE_PARSING:
|
||||
/*
|
||||
Ensure we don't get parsing_disabled < 0 as this would accidently
|
||||
Ensure we don't get parsing_disabled < 0 as this would accidentally
|
||||
disable code we don't want to have disabled
|
||||
*/
|
||||
if (parsing_disabled > 0)
|
||||
|
@ -4777,9 +4778,9 @@ int main(int argc, char **argv)
|
|||
start_lineno= 0;
|
||||
|
||||
/*
|
||||
The whole test has been executed _sucessfully_
|
||||
Time to compare result or save it to record file
|
||||
The entire output from test is now kept in ds_res
|
||||
The whole test has been executed _sucessfully_.
|
||||
Time to compare result or save it to record file.
|
||||
The entire output from test is now kept in ds_res.
|
||||
*/
|
||||
if (ds_res.length)
|
||||
{
|
||||
|
@ -5509,7 +5510,7 @@ static int get_next_bit(REP_SET *set,uint lastpos)
|
|||
}
|
||||
|
||||
/* find if there is a same set in sets. If there is, use it and
|
||||
free given set, else put in given set in sets and return it's
|
||||
free given set, else put in given set in sets and return its
|
||||
position */
|
||||
|
||||
static int find_set(REP_SETS *sets,REP_SET *find)
|
||||
|
@ -5528,7 +5529,7 @@ static int find_set(REP_SETS *sets,REP_SET *find)
|
|||
|
||||
/* find if there is a found_set with same table_offset & found_offset
|
||||
If there is return offset to it, else add new offset and return pos.
|
||||
Pos returned is -offset-2 in found_set_structure because it's is
|
||||
Pos returned is -offset-2 in found_set_structure because it is
|
||||
saved in set->next and set->next[] >= 0 points to next set and
|
||||
set->next[] == -1 is reserved for end without replaces.
|
||||
*/
|
||||
|
|
|
@ -2,114 +2,118 @@
|
|||
Overview
|
||||
--------
|
||||
|
||||
Stress script is designed to perform testsing of mysql server in
|
||||
multi-thread environment.
|
||||
The stress script is designed to perform testing of the MySQL server in
|
||||
a multi-threaded environment.
|
||||
|
||||
Stress script allows:
|
||||
All functionality regarding stress testing is implemented in the
|
||||
mysql-stress-test.pl script.
|
||||
|
||||
The stress script allows:
|
||||
|
||||
- to use for stress testing mysqltest binary as test engine
|
||||
- to use for stress testing both regular test suite and any
|
||||
additional test suites (e.g. mysql-test-extra-5.0)
|
||||
- to specify files with lists of tests both for initialization of
|
||||
stress db and for further testing itself
|
||||
- to define number of threads that will be concurrently used in testing
|
||||
- to define limitations for test run. e.g. number of tests or loops
|
||||
for execution or duration of testing, delay between test executions, etc.
|
||||
- to get readable log file which can be used for identification of
|
||||
errors arose during testing
|
||||
- To stress test the mysqltest binary test engine.
|
||||
- To stress test the regular test suite and any additional test suites
|
||||
(such as mysql-test-extra-5.0).
|
||||
- To specify files with lists of tests both for initialization of
|
||||
stress db and for further testing itself.
|
||||
- To define the number of threads to be concurrently used in testing.
|
||||
- To define limitations for the test run. such as the number of tests or
|
||||
loops for execution or duration of testing, delay between test
|
||||
executions, and so forth.
|
||||
- To get a readable log file that can be used for identification of
|
||||
errors that occur during testing.
|
||||
|
||||
All functionality regarding stress testing was implemeted in
|
||||
mysql-stress-test.pl script and there are two ways to run stress test:
|
||||
There are two ways to run the mysql-stress-test.pl script:
|
||||
|
||||
- for most cases it is enough to use options below for starting of
|
||||
stress test from mysql-test-run wrapper. In this case server will
|
||||
be run automatically, all preparation steps will be performed
|
||||
and after that stress test will be started.
|
||||
- For most cases, it is enough to use the options below for starting
|
||||
the stress test from the mysql-test-run wrapper. In this case, the
|
||||
server is run automatically, all preparation steps are performed,
|
||||
and after that the stress test is started.
|
||||
|
||||
- in advanced case one can run mysql-stress-test.pl script directly.
|
||||
But it requires to perform some preparation steps and to specify a
|
||||
bunch of options as well so this way may look a bit complicate.
|
||||
- In advanced case, you can run the mysql-stress-test.pl script directly.
|
||||
But this requires that you perform some preparation steps and to specify
|
||||
a bunch of options as well, so this invocation method may be a bit
|
||||
complicated.
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Below is list of stress test specific options for mysql-test-run:
|
||||
The following mysql-test-run options are specific to stress-testing:
|
||||
|
||||
--stress
|
||||
Enable stress mode
|
||||
|
||||
--stress-suite=<suite name>
|
||||
Test suite name that will be used in stress testing.
|
||||
We assume that all suites are located in mysql-test/suite directory
|
||||
Test suite name to use in stress testing. We assume that all suites
|
||||
are located in the mysql-test/suite directory.
|
||||
There is one special suite name - <main|default> that corresponds
|
||||
to regular test suite located in mysql-test directory.
|
||||
to the regular test suite located in the mysql-test directory.
|
||||
|
||||
--stress-threads=<number of threads>
|
||||
Number of threads that will be used in stress testing
|
||||
The number of threads to use in stress testing.
|
||||
|
||||
--stress-tests-file=<filename with list of tests>
|
||||
Filename with list of tests(without .test suffix) that will be used in
|
||||
stress testing. Default filename is stress_tests.txt and default
|
||||
The file that contains the list of tests (without .test suffix) to use in
|
||||
stress testing. The default filename is stress_tests.txt and the default
|
||||
location of this file is suite/<suite name>/stress_tests.txt
|
||||
|
||||
--stress-init-file=<filename with list of tests>
|
||||
Filename with list of tests(without .test suffix) that will be used in
|
||||
stress testing for initialization of stress db. These tests will be
|
||||
executed only once before starting of test itself. Default filename
|
||||
is stress_init.txt and default location of this file is
|
||||
The file that contains list of tests (without .test suffix) to use in
|
||||
stress testing for initialization of the stress db. These tests will be
|
||||
executed only once before starting the test itself. The default filename
|
||||
is stress_init.txt and the default location of this file is
|
||||
suite/<suite name>/stress_init.txt
|
||||
|
||||
--stress-mode=<method which will be used for choosing tests from the list>
|
||||
Possible values are: random(default), seq
|
||||
|
||||
There are two possible modes which affect order of selecting of tests
|
||||
There are two possible modes that affect the order of test selection
|
||||
from the list:
|
||||
- in random mode tests will be selected in random order
|
||||
- in seq mode each thread will execute tests in the loop one by one as
|
||||
they specified in the list file.
|
||||
- In random mode, tests are selected in random order
|
||||
- In seq mode, each thread executes tests in a loop one by one in
|
||||
the order specified in the list file.
|
||||
|
||||
--stress-test-count= <number>
|
||||
--stress-test-count=<number>
|
||||
Total number of tests that will be executed concurrently by all threads
|
||||
|
||||
--stress-loop-count= <number>
|
||||
--stress-loop-count=<number>
|
||||
Total number of loops in seq mode that will be executed concurrently
|
||||
by all threads
|
||||
|
||||
--stress-test-duration= <number>
|
||||
--stress-test-duration=<number>
|
||||
Duration of stress testing in seconds
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
1. Example of simple command line to start stress test:
|
||||
1. Example of a simple command line to start a stress test:
|
||||
|
||||
mysql-test-run --stress alias
|
||||
|
||||
Runs stress test with default values for number of threads and number of tests,
|
||||
with test 'alias' from suite 'main'.
|
||||
Runs a stress test with default values for number of threads and number
|
||||
of tests, with test 'alias' from suite 'main'.
|
||||
|
||||
2. Using in stress testing tests from other suites:
|
||||
|
||||
- mysql-test-run --stress --stress-threads=10 --stress-test-count=1000 \
|
||||
--stress-suite=example --stress-tests-file=testslist.txt
|
||||
|
||||
Will run stress test with 10 threads, will execute 1000 tests by all
|
||||
threads, test will be used from suite 'example', list of test will be
|
||||
Runs a stress test with 10 threads, executes 1000 tests by all
|
||||
threads, tests are used from suite 'example', the list of tests is
|
||||
taken from file 'testslist.txt'
|
||||
|
||||
- mysql-test-run --stress --stress-threads=10 --stress-test-count=1000 \
|
||||
--stress-suite=example sum_distinct
|
||||
|
||||
Will run stress test with 10 threads, will execute 1000 tests by all
|
||||
threads, test will be used from suite 'example', list of test contains
|
||||
only one test 'sum_distinct'
|
||||
Runs stress test with 10 threads, executes 1000 tests by all
|
||||
threads, tests are used from suite 'example', the list of tests
|
||||
contains only one test 'sum_distinct'
|
||||
|
||||
3. Debugging of issues found with stress test
|
||||
|
||||
Right now stress test is not fully integrated in mysql-test-run
|
||||
and does not support --gdb option so to debug issue found with stress
|
||||
test you have to start separately mysql server under debuger and then
|
||||
run stress test as:
|
||||
Right now, the stress test is not fully integrated in mysql-test-run
|
||||
and does not support the --gdb option. To debug issues found with the
|
||||
stress test, you must start the MySQL server separately under a debugger
|
||||
and then run the stress test like this:
|
||||
|
||||
- mysql-test-run --extern --stress --stress-threads=10 \
|
||||
--stress-test-count=1000 --stress-suite=example \
|
||||
|
|
|
@ -14,16 +14,17 @@
|
|||
#
|
||||
# Design of stress script should allow one:
|
||||
#
|
||||
# - to use for stress testing mysqltest binary as test engine
|
||||
# - to use for stress testing both regular test suite and any
|
||||
# additional test suites (e.g. mysql-test-extra-5.0)
|
||||
# - to specify files with lists of tests both for initialization of
|
||||
# stress db and for further testing itself
|
||||
# - to define number of threads that will be concurrently used in testing
|
||||
# - to define limitations for test run. e.g. number of tests or loops
|
||||
# for execution or duration of testing, delay between test executions, etc.
|
||||
# - to get readable log file which can be used for identification of
|
||||
# errors arose during testing
|
||||
# - To stress test the mysqltest binary test engine.
|
||||
# - To stress test the regular test suite and any additional test suites
|
||||
# (such as mysql-test-extra-5.0).
|
||||
# - To specify files with lists of tests both for initialization of
|
||||
# stress db and for further testing itself.
|
||||
# - To define the number of threads to be concurrently used in testing.
|
||||
# - To define limitations for the test run. such as the number of tests or
|
||||
# loops for execution or duration of testing, delay between test
|
||||
# executions, and so forth.
|
||||
# - To get a readable log file that can be used for identification of
|
||||
# errors that occur during testing.
|
||||
#
|
||||
# Basic scenarios:
|
||||
#
|
||||
|
|
|
@ -4801,4 +4801,60 @@ date_format(t3.d, pDateFormat) count(*)
|
|||
2005-02 2
|
||||
drop table t3|
|
||||
drop procedure bug17476|
|
||||
drop table if exists t3|
|
||||
drop procedure if exists bug16887|
|
||||
create table t3 ( c varchar(1) )|
|
||||
insert into t3 values
|
||||
(' '),('.'),(';'),(','),('-'),('_'),('('),(')'),('/'),('\\')|
|
||||
create procedure bug16887()
|
||||
begin
|
||||
declare i int default 10;
|
||||
again:
|
||||
while i > 0 do
|
||||
begin
|
||||
declare breakchar varchar(1);
|
||||
declare done int default 0;
|
||||
declare t3_cursor cursor for select c from t3;
|
||||
declare continue handler for not found set done = 1;
|
||||
set i = i - 1;
|
||||
select i;
|
||||
if i = 3 then
|
||||
iterate again;
|
||||
end if;
|
||||
open t3_cursor;
|
||||
loop
|
||||
fetch t3_cursor into breakchar;
|
||||
if done = 1 then
|
||||
begin
|
||||
close t3_cursor;
|
||||
iterate again;
|
||||
end;
|
||||
end if;
|
||||
end loop;
|
||||
end;
|
||||
end while;
|
||||
end|
|
||||
call bug16887()|
|
||||
i
|
||||
9
|
||||
i
|
||||
8
|
||||
i
|
||||
7
|
||||
i
|
||||
6
|
||||
i
|
||||
5
|
||||
i
|
||||
4
|
||||
i
|
||||
3
|
||||
i
|
||||
2
|
||||
i
|
||||
1
|
||||
i
|
||||
0
|
||||
drop table t3|
|
||||
drop procedure bug16887|
|
||||
drop table t1,t2;
|
||||
|
|
|
@ -5638,6 +5638,7 @@ drop function bug17615|
|
|||
drop table t3|
|
||||
|
||||
|
||||
#
|
||||
# BUG#17476: Stored procedure not returning data when it is called first
|
||||
# time per connection
|
||||
#
|
||||
|
@ -5662,6 +5663,60 @@ drop table t3|
|
|||
drop procedure bug17476|
|
||||
|
||||
|
||||
#
|
||||
# BUG#16887: Cursor causes server segfault
|
||||
#
|
||||
--disable_warnings
|
||||
drop table if exists t3|
|
||||
drop procedure if exists bug16887|
|
||||
--enable_warnings
|
||||
|
||||
create table t3 ( c varchar(1) )|
|
||||
|
||||
insert into t3 values
|
||||
(' '),('.'),(';'),(','),('-'),('_'),('('),(')'),('/'),('\\')|
|
||||
|
||||
create procedure bug16887()
|
||||
begin
|
||||
declare i int default 10;
|
||||
|
||||
again:
|
||||
while i > 0 do
|
||||
begin
|
||||
declare breakchar varchar(1);
|
||||
declare done int default 0;
|
||||
declare t3_cursor cursor for select c from t3;
|
||||
declare continue handler for not found set done = 1;
|
||||
|
||||
set i = i - 1;
|
||||
select i;
|
||||
|
||||
if i = 3 then
|
||||
iterate again;
|
||||
end if;
|
||||
|
||||
open t3_cursor;
|
||||
|
||||
loop
|
||||
fetch t3_cursor into breakchar;
|
||||
|
||||
if done = 1 then
|
||||
begin
|
||||
close t3_cursor;
|
||||
iterate again;
|
||||
end;
|
||||
end if;
|
||||
end loop;
|
||||
end;
|
||||
end while;
|
||||
end|
|
||||
|
||||
call bug16887()|
|
||||
|
||||
drop table t3|
|
||||
drop procedure bug16887|
|
||||
|
||||
|
||||
#
|
||||
# BUG#NNNN: New bug synopsis
|
||||
#
|
||||
|
|
|
@ -122,30 +122,38 @@ sp_pcontext::pop_context()
|
|||
}
|
||||
|
||||
uint
|
||||
sp_pcontext::diff_handlers(sp_pcontext *ctx)
|
||||
sp_pcontext::diff_handlers(sp_pcontext *ctx, bool exclusive)
|
||||
{
|
||||
uint n= 0;
|
||||
sp_pcontext *pctx= this;
|
||||
sp_pcontext *last_ctx= NULL;
|
||||
|
||||
while (pctx && pctx != ctx)
|
||||
{
|
||||
n+= pctx->m_handlers;
|
||||
last_ctx= pctx;
|
||||
pctx= pctx->parent_context();
|
||||
}
|
||||
if (pctx)
|
||||
return n;
|
||||
return (exclusive && last_ctx ? n - last_ctx->m_handlers : n);
|
||||
return 0; // Didn't find ctx
|
||||
}
|
||||
|
||||
uint
|
||||
sp_pcontext::diff_cursors(sp_pcontext *ctx)
|
||||
sp_pcontext::diff_cursors(sp_pcontext *ctx, bool exclusive)
|
||||
{
|
||||
uint n= 0;
|
||||
sp_pcontext *pctx= this;
|
||||
sp_pcontext *last_ctx= NULL;
|
||||
|
||||
while (pctx && pctx != ctx)
|
||||
{
|
||||
n+= pctx->m_cursor.elements;
|
||||
last_ctx= pctx;
|
||||
pctx= pctx->parent_context();
|
||||
}
|
||||
if (pctx)
|
||||
return ctx->current_cursors() - pctx->current_cursors();
|
||||
return (exclusive && last_ctx ? n - last_ctx->m_cursor.elements : n);
|
||||
return 0; // Didn't find ctx
|
||||
}
|
||||
|
||||
|
|
|
@ -119,11 +119,15 @@ class sp_pcontext : public Sql_alloc
|
|||
return m_parent;
|
||||
}
|
||||
|
||||
/*
|
||||
Number of handlers/cursors to pop between this context and 'ctx'.
|
||||
If 'exclusive' is true, don't count the last block we are leaving;
|
||||
this is used for LEAVE where we will jump to the cpop/hpop instructions.
|
||||
*/
|
||||
uint
|
||||
diff_handlers(sp_pcontext *ctx);
|
||||
|
||||
diff_handlers(sp_pcontext *ctx, bool exclusive);
|
||||
uint
|
||||
diff_cursors(sp_pcontext *ctx);
|
||||
diff_cursors(sp_pcontext *ctx, bool exclusive);
|
||||
|
||||
|
||||
//
|
||||
|
|
|
@ -2080,10 +2080,10 @@ sp_proc_stmt:
|
|||
uint ip= sp->instructions();
|
||||
uint n;
|
||||
|
||||
n= ctx->diff_handlers(lab->ctx);
|
||||
n= ctx->diff_handlers(lab->ctx, TRUE); /* Exclusive the dest. */
|
||||
if (n)
|
||||
sp->add_instr(new sp_instr_hpop(ip++, ctx, n));
|
||||
n= ctx->diff_cursors(lab->ctx);
|
||||
n= ctx->diff_cursors(lab->ctx, TRUE); /* Exclusive the dest. */
|
||||
if (n)
|
||||
sp->add_instr(new sp_instr_cpop(ip++, ctx, n));
|
||||
i= new sp_instr_jump(ip, ctx);
|
||||
|
@ -2109,10 +2109,10 @@ sp_proc_stmt:
|
|||
uint ip= sp->instructions();
|
||||
uint n;
|
||||
|
||||
n= ctx->diff_handlers(lab->ctx);
|
||||
n= ctx->diff_handlers(lab->ctx, FALSE); /* Inclusive the dest. */
|
||||
if (n)
|
||||
sp->add_instr(new sp_instr_hpop(ip++, ctx, n));
|
||||
n= ctx->diff_cursors(lab->ctx);
|
||||
n= ctx->diff_cursors(lab->ctx, FALSE); /* Inclusive the dest. */
|
||||
if (n)
|
||||
sp->add_instr(new sp_instr_cpop(ip++, ctx, n));
|
||||
i= new sp_instr_jump(ip, ctx, lab->ip); /* Jump back */
|
||||
|
|
Loading…
Reference in a new issue