Add "kill_server", call shutdown on current conneciton and then make sure

the server dissapears
Check return code of 'mysql_ping'
Add "shutdown", call 'mysql_shutdown' on the current connection 
parent 9198608e
...@@ -268,6 +268,7 @@ enum enum_commands { ...@@ -268,6 +268,7 @@ enum enum_commands {
Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP, Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP,
Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES, Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES,
Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR, Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR,
Q_SHUTDOWN, Q_KILL_SERVER,
Q_UNKNOWN, /* Unknown command. */ Q_UNKNOWN, /* Unknown command. */
Q_COMMENT, /* Comments, ignored. */ Q_COMMENT, /* Comments, ignored. */
...@@ -359,6 +360,8 @@ const char *command_names[]= ...@@ -359,6 +360,8 @@ const char *command_names[]=
"change_user", "change_user",
"mkdir", "mkdir",
"rmdir", "rmdir",
"shutdown",
"kill_server",
0 0
}; };
...@@ -3806,6 +3809,120 @@ void do_set_charset(struct st_command *command) ...@@ -3806,6 +3809,120 @@ void do_set_charset(struct st_command *command)
} }
/*
Run query and return one field in the result set from the
first row and <column>
*/
int query_get_string(MYSQL* mysql, const char* query,
int column, DYNAMIC_STRING* ds)
{
MYSQL_RES *res;
MYSQL_ROW row;
if (mysql_query(mysql,query) || !(res=mysql_store_result(mysql)))
die("'%s' failed: %d %s", query,
mysql_errno(mysql), mysql_error(mysql));
if (!(row=mysql_fetch_row(res)) || !row[column])
{
mysql_free_result(res);
ds= 0;
return 1;
}
init_dynamic_string(ds, row[1], strlen(row[column]), 32);
mysql_free_result(res);
return 0;
}
/*
Shutdown the server of current connection and
make sure it goes away within <timeout> seconds
NOTE! Currently only works with local server
SYNOPSIS
do_kill_server()
command called command
DESCRIPTION
kill_server [<timeout>]
*/
void do_kill_server(struct st_command *command)
{
int timeout=60, pid;
DYNAMIC_STRING* ds_pidfile_name;
MYSQL* mysql = &cur_con->mysql;
static DYNAMIC_STRING ds_timeout;
const struct command_arg kill_args[] = {
"timeout", ARG_STRING, FALSE, &ds_timeout, "Timeout before killing server"
};
DBUG_ENTER("do_kill_server");
check_command_args(command, command->first_argument,
kill_args, sizeof(kill_args)/sizeof(struct command_arg),
' ');
if (ds_timeout.length)
{
timeout= atoi(ds_timeout.str);
if (timeout == 0)
die("Illegal argument for timeout: '%s'", ds_timeout.str);
}
/* Get the servers pid_file name and use it to read pid */
if (query_get_string(mysql, "SHOW VARIABLES LIKE 'pid_file'", 1,
ds_pidfile_name))
die("Failed to get pid_file from server");
/* Read the pid from the file */
{
int fd;
char buff[32];
if ((fd= my_open(ds_pidfile_name->str, O_RDONLY, MYF(0))) < 0)
die("Failed to open file '%s'", ds_pidfile_name->str);
if (my_read(fd, (uchar*)&buff,
sizeof(buff), MYF(0)) <= 0){
my_close(fd, MYF(0));
die("pid file was empty");
}
pid= atoi(buff);
if (pid == 0){
my_close(fd, MYF(0));
die("pid file was empty");
}
DBUG_PRINT("info", ("Read pid %d from '%s'", pid, ds_pidfile_name->str));
my_close(fd, MYF(0));
}
DBUG_PRINT("info", ("Got pid %d", pid));
/* Tell server to shutdown */
if (mysql_shutdown(&cur_con->mysql, SHUTDOWN_DEFAULT))
die("mysql_shutdown failed");
/* Check that server dies */
while(timeout--){
if (kill(0, pid) < 0){
DBUG_PRINT("info", ("Sleeping, timeout: %d", timeout));
break;
}
DBUG_PRINT("info", ("Sleeping, timeout: %d", timeout));
my_sleep(1);
}
/* Kill the server */
DBUG_PRINT("info", ("Killing server, pid: %d", pid));
(void)kill(9, pid);
DBUG_VOID_RETURN;
}
#if MYSQL_VERSION_ID >= 50000 #if MYSQL_VERSION_ID >= 50000
/* List of error names to error codes, available from 5.0 */ /* List of error names to error codes, available from 5.0 */
typedef struct typedef struct
...@@ -7192,8 +7309,16 @@ int main(int argc, char **argv) ...@@ -7192,8 +7309,16 @@ int main(int argc, char **argv)
command->last_argument= command->end; command->last_argument= command->end;
break; break;
case Q_PING: case Q_PING:
(void) mysql_ping(&cur_con->mysql); handle_command_error(command, mysql_ping(&cur_con->mysql));
break; break;
case Q_SHUTDOWN:
handle_command_error(command,
mysql_shutdown(&cur_con->mysql,
SHUTDOWN_DEFAULT));
break;
case Q_KILL_SERVER:
do_kill_server(command);
break;
case Q_EXEC: case Q_EXEC:
do_exec(command); do_exec(command);
command_executed++; command_executed++;
......
# Write file to make mysql-test-run.pl expect crash and restart # Write file to make mysql-test-run.pl expect crash and restart
--exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect
restart
EOF
--exec $MYSQLADMIN --defaults-file=$MYSQLTEST_VARDIR/my.cnf --shutdown-timeout=60 shutdown # Send shutdown to the connected server and give
# it 10 seconds to die before zapping it
kill_server 10;
# Call script that will poll the server waiting for it to be gone
--source include/wait_until_disconnected.inc
# Turn on reconnect # Turn on reconnect
--enable_reconnect --enable_reconnect
...@@ -13,3 +15,6 @@ ...@@ -13,3 +15,6 @@
# Call script that will poll the server waiting for it to be back online again # Call script that will poll the server waiting for it to be back online again
--source include/wait_until_connected_again.inc --source include/wait_until_connected_again.inc
# Turn off reconnect again
--disable_reconnect
...@@ -4,9 +4,13 @@ ...@@ -4,9 +4,13 @@
--disable_result_log --disable_result_log
--disable_query_log --disable_query_log
let $counter= 500; let $counter= 500;
let $mysql_errno= 9999;
while ($mysql_errno) while ($mysql_errno)
{ {
--error 0,1053,2002,2006 # Strangely enough, the server might return "Too many connections"
# while being shutdown, thus 1040 is an "allowed" error
# See BUG#36228
--error 0,1040,1053,2002,2006,2013
show status; show status;
dec $counter; dec $counter;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment