461 lines
9.9 KiB
Plaintext
461 lines
9.9 KiB
Plaintext
## Test various client close/dispose scenarios
|
|
|
|
# // client just disconnected on us
|
|
# Close_peer_disconnected,
|
|
# // client sent a close command
|
|
# Close_requested_by_client,
|
|
# // server is shutting down
|
|
# Close_server_shutdown,
|
|
# // client was killed (as in via SQL KILL command by another client)
|
|
# Close_client_killed,
|
|
# // unrecoverable network error occurred
|
|
# Close_net_error,
|
|
# // a fatal application error occurred
|
|
# Close_fatal_error,
|
|
# // like Client_fatal_error, except that error is not reported to the client
|
|
# Close_aborted
|
|
|
|
--source include/restart_mysqld.inc
|
|
--source include/xplugin_preamble.inc
|
|
--source include/xplugin_create_user.inc
|
|
|
|
call mtr.add_suppression('Message of size 4294967040 received, exceeding the limit of 1048576');
|
|
# Plugin 'InnoDB' has ref_count=1 after shutdown
|
|
call mtr.add_suppression("Plugin \'InnoDB\'");
|
|
# wait a little to give time for internal temporary session to die out
|
|
select sleep(1);
|
|
--replace_regex /localhost[:0-9]*/localhost/ /Execute/Query/
|
|
SELECT `user`,`host`,`db`,`command`,`state`,`info` FROM INFORMATION_SCHEMA.PROCESSLIST WHERE `state` != 'cleaning up' ORDER BY user ASC;
|
|
|
|
## Test starts here
|
|
--write_file $MYSQL_TMP_DIR/client_close.tmp
|
|
-->import connection.macro
|
|
# number of seconds to sleep... increase to a higher value once killing sessions on disconnect works
|
|
-->varlet %SLEEP% 2
|
|
|
|
-->macro Close_active_and_sync
|
|
Mysqlx.Connection.Close {
|
|
}
|
|
-->recvtype Mysqlx.Ok
|
|
-->peerdisc 1000 5000
|
|
-->endmacro
|
|
|
|
|
|
-->sql
|
|
delimiter //;
|
|
create procedure test.get_stuck()
|
|
begin
|
|
declare i int;
|
|
declare x int;
|
|
set i = 1;
|
|
while i < 1000 do
|
|
set i = i + 1;
|
|
set x = sleep(0.5);
|
|
end while;
|
|
end//;
|
|
delimiter ;
|
|
|
|
show global status like 'mysqlx_connections_%';
|
|
-->endsql
|
|
|
|
-->title #Close_peer_disconnected
|
|
-->title -Connect and disconnect while idle
|
|
-->newsession sess x_root
|
|
-->closesession abort
|
|
|
|
-->sql
|
|
select sleep(%SLEEP%);
|
|
show global status like 'mysqlx_connections_%';
|
|
-->endsql
|
|
|
|
##########
|
|
|
|
-->title -Connect and disconnect while running a query
|
|
-->newsession sess x_root
|
|
|
|
Mysqlx.Sql.StmtExecute {
|
|
stmt: "select sleep(%SLEEP%)"
|
|
}
|
|
|
|
# read the resultset metadata, which is sent immediately
|
|
-->recv
|
|
|
|
-->closesession abort
|
|
-->sql
|
|
select sleep(%SLEEP%);
|
|
show global status like 'mysqlx_connections_%';
|
|
-->endsql
|
|
|
|
##########
|
|
|
|
-->title -Connect and disconnect while streaming result
|
|
-->newsession sess x_root
|
|
|
|
Mysqlx.Sql.StmtExecute {
|
|
stmt: "show variables"
|
|
}
|
|
|
|
-->closesession abort
|
|
-->sleep 2
|
|
-->sql
|
|
select sleep(%SLEEP%);
|
|
show global status like 'mysqlx_connections_%';
|
|
-->endsql
|
|
|
|
###########
|
|
|
|
-->title -Connect and disconnect while input queue is full
|
|
-->newsession sess x_root
|
|
|
|
Mysqlx.Sql.StmtExecute {
|
|
stmt: "select sleep(%SLEEP%)"
|
|
}
|
|
Mysqlx.Sql.StmtExecute {
|
|
stmt: "select 1"
|
|
}
|
|
|
|
-->closesession abort
|
|
-->sleep 4
|
|
-->sql
|
|
show global status like 'mysqlx_connections_%';
|
|
-->endsql
|
|
|
|
-->title -Disconnect while in a pipeline
|
|
|
|
-->newsession sess x_root
|
|
Mysqlx.Sql.StmtExecute {
|
|
stmt: "select 6"
|
|
}
|
|
Mysqlx.Sql.StmtExecute {
|
|
stmt: "select 1"
|
|
}
|
|
-->recv
|
|
-->closesession abort
|
|
|
|
|
|
############
|
|
-->title #Close_requested_by_client
|
|
|
|
-->title -Close when idle
|
|
|
|
-->newsession sess x_root
|
|
Mysqlx.Sql.StmtExecute {
|
|
stmt: "select 1"
|
|
}
|
|
-->recvresult
|
|
-->callmacro Close_active_and_sync
|
|
|
|
-->sql
|
|
select sleep(%SLEEP%);
|
|
show global status like 'mysqlx_connections_%';
|
|
-->endsql
|
|
|
|
-->title -Close in a pipeline
|
|
|
|
-->newsession sess x_root
|
|
Mysqlx.Sql.StmtExecute {
|
|
stmt: "select 2"
|
|
}
|
|
Mysqlx.Sql.StmtExecute {
|
|
stmt: "select 3"
|
|
}
|
|
Mysqlx.Connection.Close {
|
|
}
|
|
# ALL results up to the Close must be readable by client
|
|
-->recvresult
|
|
-->recvresult
|
|
-->recvok
|
|
-->expecterror CR_SERVER_GONE_ERROR
|
|
-->sleep 1
|
|
-->sql
|
|
select 4;
|
|
-->endsql
|
|
|
|
# "abort", since we already sent the close
|
|
-->closesession abort
|
|
|
|
-->title #Close_client_killed
|
|
|
|
-->title -Kill a session while idle
|
|
|
|
-->newsession sess x_root
|
|
-->varlet %SESS_CLIENT_ID% %ACTIVE_CLIENT_ID%
|
|
-->setsession
|
|
|
|
Mysqlx.Sql.StmtExecute {
|
|
namespace: "xplugin"
|
|
stmt: "kill_client"
|
|
args {
|
|
type: SCALAR
|
|
scalar {
|
|
type: V_UINT
|
|
v_unsigned_int: %SESS_CLIENT_ID%
|
|
}
|
|
}
|
|
}
|
|
# The kill operation can return an error here. If the thread being killed is in "kill immune" mode
|
|
# its killing is delayed till it leaves that mode. This is temporary solution in the server for the DD opartions.
|
|
# The kill immune mode is to be removed in the future.
|
|
-->expecterror 0, 1095
|
|
-->recvresult be-quiet
|
|
|
|
-->setsession sess
|
|
-->closesession abort
|
|
|
|
-->title -Kill a session executing query
|
|
|
|
-->newsession sess x_root
|
|
-->varlet %SESS_CLIENT_ID% %ACTIVE_CLIENT_ID%
|
|
Mysqlx.Sql.StmtExecute {
|
|
stmt: "call test.get_stuck()"
|
|
}
|
|
Mysqlx.Sql.StmtExecute {
|
|
stmt: "select 1"
|
|
}
|
|
|
|
-->setsession
|
|
Mysqlx.Sql.StmtExecute {
|
|
namespace: "xplugin"
|
|
stmt: "kill_client"
|
|
args {
|
|
type: SCALAR
|
|
scalar {
|
|
type: V_UINT
|
|
v_unsigned_int: %SESS_CLIENT_ID%
|
|
}
|
|
}
|
|
}
|
|
# The kill operation can return an error here. If the thread being killed is in "kill immune" mode
|
|
# its killing is delayed till it leaves that mode. This is temporary solution in the server for the DD opartions.
|
|
# The kill immune mode is to be removed in the future.
|
|
-->expecterror 0, 1095
|
|
-->recvresult be-quiet
|
|
|
|
-->setsession sess
|
|
|
|
-->expecterror 1317,2006,2007,5010
|
|
-->recvresult
|
|
|
|
-->closesession abort
|
|
|
|
-->title -Kill a session that hasnt authenticated yet
|
|
|
|
-->newsession sess -
|
|
-->callmacro Verify_its_xprotocol_connection
|
|
-->varlet %SESS_CLIENT_ID% 11
|
|
|
|
-->sleep 1
|
|
|
|
-->setsession
|
|
Mysqlx.Sql.StmtExecute {
|
|
namespace: "xplugin"
|
|
stmt: "kill_client"
|
|
args {
|
|
type: SCALAR
|
|
scalar {
|
|
type: V_UINT
|
|
v_unsigned_int: %SESS_CLIENT_ID%
|
|
}
|
|
}
|
|
}
|
|
# The kill operation can return an error here. If the thread being killed is in "kill immune" mode
|
|
# its killing is delayed till it leaves that mode. This is temporary solution in the server for the DD opartions.
|
|
# The kill immune mode is to be removed in the future.
|
|
-->expecterror 0, 1095
|
|
-->recvresult be-quiet
|
|
|
|
-->setsession sess
|
|
-->expecterror 2006,2007
|
|
-->sql
|
|
select 1;
|
|
-->endsql
|
|
|
|
-->closesession abort
|
|
|
|
-->title -Kill a session that hasnt authenticated yet, with data queued
|
|
|
|
-->newsession sess -
|
|
-->callmacro Verify_its_xprotocol_connection
|
|
-->varlet %SESS_CLIENT_ID% 12
|
|
|
|
-->sleep 1
|
|
|
|
Mysqlx.Connection.CapabilitiesGet {
|
|
}
|
|
|
|
-->setsession
|
|
Mysqlx.Sql.StmtExecute {
|
|
namespace: "xplugin"
|
|
stmt: "kill_client"
|
|
args {
|
|
type: SCALAR
|
|
scalar {
|
|
type: V_UINT
|
|
v_unsigned_int: %SESS_CLIENT_ID%
|
|
}
|
|
}
|
|
}
|
|
# The kill operation can return an error here. If the thread being killed is in "kill immune" mode
|
|
# its killing is delayed till it leaves that mode. This is temporary solution in the server for the DD opartions.
|
|
# The kill immune mode is to be removed in the future.
|
|
-->expecterror 0, 1095
|
|
-->recvresult be-quiet
|
|
|
|
-->setsession sess
|
|
-->recv quiet
|
|
-->expecterror 2006,2007
|
|
-->recvresult
|
|
|
|
-->closesession abort
|
|
|
|
|
|
# Can't test via normal means: Close_net_error
|
|
|
|
-->title #Close_fatal_error
|
|
|
|
-->title -Authentication error
|
|
|
|
-->newsession sess -
|
|
-->callmacro Verify_its_xprotocol_connection
|
|
Mysqlx.Session.AuthenticateStart {
|
|
mech_name: "invalid"
|
|
}
|
|
-->recverror 1251
|
|
|
|
-->closesession abort
|
|
|
|
-->title -Authentication error (try to close normally)
|
|
-->newsession sess -
|
|
-->callmacro Verify_its_xprotocol_connection
|
|
Mysqlx.Session.AuthenticateStart {
|
|
mech_name: "invalid"
|
|
}
|
|
|
|
-->recverror 1251
|
|
|
|
-->expecterror 2006,2007
|
|
-->closesession
|
|
|
|
-->title -Disconnect while authenticating
|
|
-->newsession sess -
|
|
-->callmacro Verify_its_xprotocol_connection
|
|
Mysqlx.Session.AuthenticateStart {
|
|
mech_name: "MYSQL41"
|
|
}
|
|
|
|
-->closesession abort
|
|
|
|
-->title -Send unexpected message at handshake
|
|
|
|
-->newsession sess -
|
|
-->callmacro Verify_its_xprotocol_connection
|
|
Mysqlx.Sql.StmtExecute {
|
|
stmt: "select 1"
|
|
}
|
|
|
|
-->recverror 5000
|
|
|
|
-->closesession abort
|
|
|
|
-->title -Disconnect at handshake
|
|
-->newsession sess -
|
|
-->callmacro Verify_its_xprotocol_connection
|
|
-->closesession abort
|
|
|
|
|
|
-->title -Disconnect at handshake
|
|
-->newsession sess -
|
|
-->callmacro Verify_its_xprotocol_connection
|
|
Mysqlx.Connection.CapabilitiesGet {
|
|
}
|
|
|
|
-->closesession abort
|
|
|
|
|
|
-->title #Close_aborted
|
|
|
|
-->title -Send illegal message at handshake
|
|
-->newsession sess -
|
|
-->callmacro Verify_its_xprotocol_connection
|
|
-->binsend \x00\xff\xff\xff\xffxxxxx
|
|
|
|
-->peerdisc 500 500
|
|
|
|
-->title -Send illegal message after handshake
|
|
|
|
-->newsession sess x_root
|
|
-->binsend \x00\xff\xff\xff\xffxxxxx
|
|
|
|
-->peerdisc 500 500
|
|
|
|
-->title -Connection failure by auth
|
|
|
|
-->expecterror 2510
|
|
-->newsession sess x_root badpass
|
|
|
|
###########
|
|
|
|
-->title #Other conditions
|
|
-->title -Connect and disconnect after queue read timeout
|
|
-->newsession sess x_root
|
|
|
|
# 1s more than the value in the plugin
|
|
-->varlet %SESSION_MESSAGE_QUEUE_TIMEOUT% 7
|
|
-->sleep %SESSION_MESSAGE_QUEUE_TIMEOUT%
|
|
|
|
-->closesession abort
|
|
|
|
-->sleep 1
|
|
|
|
#Close_server_shutdown
|
|
# covered elsewhere
|
|
######
|
|
|
|
-->title -Final check of clients still around
|
|
|
|
Mysqlx.Sql.StmtExecute {
|
|
stmt: "list_clients"
|
|
namespace: "xplugin"
|
|
}
|
|
-->recvresult
|
|
|
|
|
|
#####
|
|
|
|
-->title -Bug #21825183 - WHEN CLIENTS LAST SESSION IS CLOSED THEN NOT ALL QUEUED MESSAGES ARE SEND
|
|
|
|
-->newsession sess
|
|
-->varlet %VALUE% 1234
|
|
-->repeat 200 %VALUE%
|
|
Mysqlx.Sql.StmtExecute {
|
|
stmt:"SELECT %VALUE% as `Column`;"
|
|
namespace: "sql"
|
|
}
|
|
-->endrepeat
|
|
Mysqlx.Connection.Close {
|
|
}
|
|
#-->abort
|
|
-->repeat 200 %VALUE%
|
|
-->recvresult
|
|
-->endrepeat
|
|
-->recv
|
|
-->closesession abort
|
|
|
|
EOF
|
|
|
|
--replace_regex /([a-z]*.+localhost[ ]+)[0-9]+/\1$SESSION/
|
|
--exec $MYSQLXTEST -ux_root --password='' --file=$MYSQL_TMP_DIR/client_close.tmp 2>&1
|
|
|
|
# sleep for a while to ensure clean up finished
|
|
select sleep(10);
|
|
|
|
show global status like 'mysqlx_sessions';
|
|
show global status like 'mysqlx_connections_%';
|
|
--replace_regex /localhost[:0-9]*/localhost/ /Execute/Query/
|
|
SELECT `user`,`host`,`db`,`command`,`state`,`info` FROM INFORMATION_SCHEMA.PROCESSLIST WHERE `state` != 'cleaning up' ORDER BY user ASC;
|
|
drop procedure test.get_stuck;
|
|
|
|
## Cleanup
|
|
--remove_file $MYSQL_TMP_DIR/client_close.tmp
|
|
--source include/xplugin_drop_user.inc
|