diff options
author | unknown <anozdrin/alik@quad.> | 2008-03-17 14:26:00 +0300 |
---|---|---|
committer | unknown <anozdrin/alik@quad.> | 2008-03-17 14:26:00 +0300 |
commit | c1e69a77a6f6563214b5f5e8813db423c4f3a04c (patch) | |
tree | dbed4b209c7f0db9b9c6015b42e71bd1761897b8 | |
parent | 30d644f859ee65748f12e3861abaf1fbb2c3b2c7 (diff) | |
download | mariadb-git-c1e69a77a6f6563214b5f5e8813db423c4f3a04c.tar.gz |
Avoid races in connect.test.
The problem was in a test case for Bug33507:
- when the number of active connections reaches the limit,
the server accepts only root connections. That's achieved by
accepting a connection, negotiating with the client and
checking user credentials. If it is not SUPER, the connection
is dropped.
- when the server accepts connection, it increases the counter;
- when the server drops connection, it decreases the counter;
- the race was in between of decreasing the counter and accepting
new connection:
- max_user_connections = 2;
- 2 oridinary user connections accepted;
- extra user connection is establishing;
- server checked user credentials, and sent 'Too many connections'
error;
- the client receives the error and establishes extra SUPER user
connection;
- the server however didn't decrease the counter (the extra
user connection still is "alive" in the server) -- so, the new
SUPER-user connection, will be dropped, because it exceeds
(max_user_connections + 1).
The fix is to implement "safe connect", which makes several attempts
to connect and use it in the test script.
mysql-test/r/connect.result:
Update test file.
mysql-test/t/connect.test:
Avoid races in connect.test.
mysql-test/include/connect2.inc:
Auxiliary routine to establish a connection reliably.
-rw-r--r-- | mysql-test/include/connect2.inc | 56 | ||||
-rw-r--r-- | mysql-test/r/connect.result | 29 | ||||
-rw-r--r-- | mysql-test/t/connect.test | 80 |
3 files changed, 110 insertions, 55 deletions
diff --git a/mysql-test/include/connect2.inc b/mysql-test/include/connect2.inc new file mode 100644 index 00000000000..6b830a909ed --- /dev/null +++ b/mysql-test/include/connect2.inc @@ -0,0 +1,56 @@ +# include/connect2.inc +# +# SUMMARY +# +# Make several attempts to connect. +# +# USAGE +# +# EXAMPLE +# +# connect.test +# + +--disable_query_log + +let $wait_counter= 300; +if ($wait_timeout) +{ + let $wait_counter= `SELECT $wait_timeout * 10`; +} +# Reset $wait_timeout so that its value won't be used on subsequent +# calls, and default will be used instead. +let $wait_timeout= 0; + +--echo # -- Establishing connection '$con_name' (user: $con_user_name)... + +while ($wait_counter) +{ + --disable_abort_on_error + --disable_result_log + --connect ($con_name,localhost,$con_user_name) + --enable_result_log + --enable_abort_on_error + + let $error = $mysql_errno; + + if (!$error) + { + let $wait_counter= 0; + } + if ($error) + { + real_sleep 0.1; + dec $wait_counter; + } +} +if ($error) +{ + --echo # -- Error: can not establish connection '$con_name'. +} +if (!$error) +{ + --echo # -- Connection '$con_name' has been established. +} + +--enable_query_log diff --git a/mysql-test/r/connect.result b/mysql-test/r/connect.result index f2bacf92cc8..727433d3032 100644 --- a/mysql-test/r/connect.result +++ b/mysql-test/r/connect.result @@ -127,8 +127,7 @@ GRANT USAGE ON *.* TO mysqltest_u1@localhost; SET GLOBAL max_connections = 3; SET GLOBAL event_scheduler = ON; -# -- Waiting for old connections to close... - +# -- Waiting for Event Scheduler to start... # -- Disconnecting default connection... @@ -136,22 +135,33 @@ SET GLOBAL event_scheduler = ON; # -- many threads are running. # -- Connecting (1)... - -# -- Waiting for root connection to close... +# -- Establishing connection 'con_1' (user: mysqltest_u1)... +# -- Connection 'con_1' has been established. # -- Connecting (2)... +# -- Establishing connection 'con_2' (user: mysqltest_u1)... +# -- Connection 'con_2' has been established. + # -- Connecting (3)... -# -- Connecting (4)... -ERROR 08004: Too many connections +# -- Establishing connection 'con_3' (user: mysqltest_u1)... +# -- Connection 'con_3' has been established. -# -- Waiting for the last connection to close... +# -- Connecting (4) [should fail]... +# -- Establishing connection 'con_4' (user: mysqltest_u1)... +# -- Error: can not establish connection 'con_4'. # -- Check that we allow one extra SUPER-user connection. # -- Connecting super (1)... -# -- Connecting super (2)... -ERROR HY000: Too many connections +# -- Establishing connection 'con_super_1' (user: root)... +# -- Connection 'con_super_1' has been established. + +# -- Connecting super (2) [should fail]... +# -- Establishing connection 'con_super_2' (user: root)... +# -- Error: can not establish connection 'con_super_2'. +# -- Ensure that we have Event Scheduler thread, 3 ordinary user +# -- connections and one extra super-user connection. SELECT user FROM information_schema.processlist ORDER BY id; user event_scheduler @@ -165,6 +175,7 @@ SET GLOBAL max_connections = 151; # -- Stopping Event Scheduler... SET GLOBAL event_scheduler = OFF; + # -- Waiting for Event Scheduler to stop... # -- That's it. Closing connections... diff --git a/mysql-test/t/connect.test b/mysql-test/t/connect.test index c8b69a050ba..0893bf9ad18 100644 --- a/mysql-test/t/connect.test +++ b/mysql-test/t/connect.test @@ -114,106 +114,94 @@ drop table t1; --echo # -- End of 4.1 tests --echo # ------------------------------------------------------------------ +########################################################################### + --echo --echo # -- Bug#33507: Event scheduler creates more threads than max_connections --echo # -- which results in user lockout. ---echo +--echo GRANT USAGE ON *.* TO mysqltest_u1@localhost; # NOTE: if the test case fails sporadically due to spurious connections, # consider disabling all users. --echo - let $saved_max_connections = `SELECT @@global.max_connections`; - SET GLOBAL max_connections = 3; SET GLOBAL event_scheduler = ON; --echo ---echo # -- Waiting for old connections to close... -let $wait_condition = - SELECT COUNT(*) = 1 - FROM information_schema.processlist - WHERE db = 'test'; ---source include/wait_condition.inc - ---echo +--echo # -- Waiting for Event Scheduler to start... let $wait_condition = SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE user = 'event_scheduler'; --source include/wait_condition.inc ---echo +--echo --echo # -- Disconnecting default connection... --disconnect default --echo --echo # -- Check that we allow exactly three user connections, no matter how --echo # -- many threads are running. ---echo +--echo --echo # -- Connecting (1)... ---connect (con_1,localhost,mysqltest_u1) +let $con_name = con_1; +let $con_user_name = mysqltest_u1; +--source include/connect2.inc --echo ---echo # -- Waiting for root connection to close... -let $wait_condition = - SELECT COUNT(*) = 1 - FROM information_schema.processlist - WHERE db = 'test'; ---source include/wait_condition.inc ---echo - --echo # -- Connecting (2)... ---connect (con_2,localhost,mysqltest_u1) +let $con_name = con_2; +let $con_user_name = mysqltest_u1; +--source include/connect2.inc +--echo --echo # -- Connecting (3)... ---connect (con_3,localhost,mysqltest_u1) - ---echo # -- Connecting (4)... ---disable_query_log ---error ER_CON_COUNT_ERROR ---connect (con_4,localhost,mysqltest_u1) ---enable_query_log +let $con_name = con_3; +let $con_user_name = mysqltest_u1; +--source include/connect2.inc --echo ---echo # -- Waiting for the last connection to close... -let $wait_condition = - SELECT COUNT(*) = 3 - FROM information_schema.processlist - WHERE db = 'test'; ---source include/wait_condition.inc +--echo # -- Connecting (4) [should fail]... +let $con_name = con_4; +let $con_user_name = mysqltest_u1; +let $wait_timeout = 5; +--source include/connect2.inc --echo --echo # -- Check that we allow one extra SUPER-user connection. ---echo +--echo --echo # -- Connecting super (1)... ---connect (con_super_1,localhost,root) +let $con_name = con_super_1; +let $con_user_name = root; +--source include/connect2.inc ---echo # -- Connecting super (2)... ---disable_query_log ---error ER_CON_COUNT_ERROR ---connect (con_super_2,localhost,root) ---enable_query_log +--echo +--echo # -- Connecting super (2) [should fail]... +let $con_name = con_super_2; +let $con_user_name = root; +let $wait_timeout = 5; +--source include/connect2.inc --echo -# Ensure that we have Event Scheduler thread, 3 ordinary user connections and -# one extra super-user connection. +--echo # -- Ensure that we have Event Scheduler thread, 3 ordinary user +--echo # -- connections and one extra super-user connection. SELECT user FROM information_schema.processlist ORDER BY id; --echo --echo # -- Resetting variables... - --eval SET GLOBAL max_connections = $saved_max_connections --echo --echo # -- Stopping Event Scheduler... SET GLOBAL event_scheduler = OFF; +--echo --echo # -- Waiting for Event Scheduler to stop... let $wait_condition = SELECT COUNT(*) = 0 |