Commit a195ad5e authored by unknown's avatar unknown

Bug#22943 syscall pruning in libmysql

 - Set the timeout values only where needed


sql/mysql_priv.h:
  Add new functions for setting read and write timeout on "net"
sql/mysqld.cc:
  - Move the setting of "read_timeout" to the value of "connect_timeout" to
    just before 'check_connection' which is the function where we want
    to use the different timeout
  - With the new functions to set timeout on "net", there is no need to
    specifically set the default wait_timeout on windows.
sql/net_serv.cc:
  Add new functions for setting read and write timeout of "net, when
  server is compiled not to use alarms it will set the write/read timeout
  directly on connection using 'vio_timeout'(using setsockopt if socket)
sql/repl_failsafe.cc:
  Put unused code within "#if NOT_USED"
sql/set_var.cc:
  Use 'net_set_*_timeout' when adjusting timeout value
  on the current connection
sql/slave.cc:
  The read timeout used when connecting to master server is set
  using 'mysql_options' in 'connect_to_master' function
sql/sql_parse.cc:
  - Set read and write timeout values to "connect_timeout" during
  connect phase
  - Use "read_timeout" value during sslaccept phase, since this is during
  connect phase it implies "connect-timeout"
  - Set read and write timeout value back to default after connect phase
  - Set "read_timeout" to "wait_timeout" while waiting for client.
sql/sql_repl.cc:
  Set "read_timeout" to "wait_timeout" while ask other mysqld to send file
sql-common/client.c:
  Call 'vio_timeout' to set up the read and write timeout's for the
  newly created connection. It only need to be done once at connect time.
vio/vio.c:
  Use 'vio_timeout' for setting timeout also on an SSL connection
  since they both use sockets
vio/viossl.c:
  Remove 'vio_ssl_timeout' function
parent b95f1073
...@@ -1881,11 +1881,17 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, ...@@ -1881,11 +1881,17 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user,
goto error; goto error;
} }
vio_keepalive(net->vio,TRUE); vio_keepalive(net->vio,TRUE);
/* Override local client variables */
/* If user set read_timeout, let it override the default */
if (mysql->options.read_timeout) if (mysql->options.read_timeout)
net->read_timeout= mysql->options.read_timeout; net->read_timeout= mysql->options.read_timeout;
vio_timeout(net->vio, 0, net->read_timeout);
/* If user set write_timeout, let it override the default */
if (mysql->options.write_timeout) if (mysql->options.write_timeout)
net->write_timeout= mysql->options.write_timeout; net->write_timeout= mysql->options.write_timeout;
vio_timeout(net->vio, 1, net->write_timeout);
if (mysql->options.max_allowed_packet) if (mysql->options.max_allowed_packet)
net->max_packet_size= mysql->options.max_allowed_packet; net->max_packet_size= mysql->options.max_allowed_packet;
......
...@@ -59,6 +59,8 @@ void kill_one_thread(THD *thd, ulong id); ...@@ -59,6 +59,8 @@ void kill_one_thread(THD *thd, ulong id);
bool net_request_file(NET* net, const char* fname); bool net_request_file(NET* net, const char* fname);
char* query_table_status(THD *thd,const char *db,const char *table_name); char* query_table_status(THD *thd,const char *db,const char *table_name);
void net_set_write_timeout(NET *net, uint timeout);
void net_set_read_timeout(NET *net, uint timeout);
#define x_free(A) { my_free((gptr) (A),MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR)); } #define x_free(A) { my_free((gptr) (A),MYF(MY_WME | MY_FAE | MY_ALLOW_ZERO_PTR)); }
#define safeFree(x) { if(x) { my_free((gptr) x,MYF(0)); x = NULL; } } #define safeFree(x) { if(x) { my_free((gptr) x,MYF(0)); x = NULL; } }
......
...@@ -3601,10 +3601,9 @@ static bool read_init_file(char *file_name) ...@@ -3601,10 +3601,9 @@ static bool read_init_file(char *file_name)
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
static void create_new_thread(THD *thd) static void create_new_thread(THD *thd)
{ {
NET *net=&thd->net;
DBUG_ENTER("create_new_thread"); DBUG_ENTER("create_new_thread");
NET *net=&thd->net; // For easy ref
net->read_timeout = (uint) connect_timeout;
if (protocol_version > 9) if (protocol_version > 9)
net->return_errno=1; net->return_errno=1;
...@@ -3899,12 +3898,7 @@ extern "C" pthread_handler_decl(handle_connections_sockets, ...@@ -3899,12 +3898,7 @@ extern "C" pthread_handler_decl(handle_connections_sockets,
} }
if (sock == unix_sock) if (sock == unix_sock)
thd->host=(char*) my_localhost; thd->host=(char*) my_localhost;
#ifdef __WIN__
/* Set default wait_timeout */
ulong wait_timeout= global_system_variables.net_wait_timeout * 1000;
(void) setsockopt(new_sock, SOL_SOCKET, SO_RCVTIMEO, (char*)&wait_timeout,
sizeof(wait_timeout));
#endif
create_new_thread(thd); create_new_thread(thd);
} }
......
...@@ -491,7 +491,7 @@ net_real_write(NET *net,const char *packet,ulong len) ...@@ -491,7 +491,7 @@ net_real_write(NET *net,const char *packet,ulong len)
thr_alarm(&alarmed,(uint) net->write_timeout,&alarm_buff); thr_alarm(&alarmed,(uint) net->write_timeout,&alarm_buff);
#else #else
alarmed=0; alarmed=0;
vio_timeout(net->vio, 1, net->write_timeout); /* Write timeout is set in net_set_write_timeout */
#endif /* NO_ALARM */ #endif /* NO_ALARM */
pos=(char*) packet; end=pos+len; pos=(char*) packet; end=pos+len;
...@@ -684,7 +684,7 @@ my_real_read(NET *net, ulong *complen) ...@@ -684,7 +684,7 @@ my_real_read(NET *net, ulong *complen)
if (net_blocking) if (net_blocking)
thr_alarm(&alarmed,net->read_timeout,&alarm_buff); thr_alarm(&alarmed,net->read_timeout,&alarm_buff);
#else #else
vio_timeout(net->vio, 0, net->read_timeout); /* Read timeout is set in net_set_read_timeout */
#endif /* NO_ALARM */ #endif /* NO_ALARM */
pos = net->buff + net->where_b; /* net->packet -4 */ pos = net->buff + net->where_b; /* net->packet -4 */
...@@ -995,3 +995,26 @@ my_net_read(NET *net) ...@@ -995,3 +995,26 @@ my_net_read(NET *net)
return len; return len;
} }
void net_set_read_timeout(NET *net, uint timeout)
{
DBUG_ENTER("net_set_read_timeout");
DBUG_PRINT("enter", ("timeout: %d", timeout));
net->read_timeout= timeout;
#ifdef NO_ALARM
vio_timeout(net->vio, 0, timeout);
#endif
DBUG_VOID_RETURN;
}
void net_set_write_timeout(NET *net, uint timeout)
{
DBUG_ENTER("net_set_write_timeout");
DBUG_PRINT("enter", ("timeout: %d", timeout));
net->write_timeout= timeout;
#ifdef NO_ALARM
vio_timeout(net->vio, 1, timeout);
#endif
DBUG_VOID_RETURN;
}
...@@ -57,6 +57,7 @@ static Slave_log_event* find_slave_event(IO_CACHE* log, ...@@ -57,6 +57,7 @@ static Slave_log_event* find_slave_event(IO_CACHE* log,
functions like register_slave()) are working. functions like register_slave()) are working.
*/ */
#if NOT_USED
static int init_failsafe_rpl_thread(THD* thd) static int init_failsafe_rpl_thread(THD* thd)
{ {
DBUG_ENTER("init_failsafe_rpl_thread"); DBUG_ENTER("init_failsafe_rpl_thread");
...@@ -99,7 +100,7 @@ static int init_failsafe_rpl_thread(THD* thd) ...@@ -99,7 +100,7 @@ static int init_failsafe_rpl_thread(THD* thd)
thd->set_time(); thd->set_time();
DBUG_RETURN(0); DBUG_RETURN(0);
} }
#endif
void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status) void change_rpl_status(RPL_STATUS from_status, RPL_STATUS to_status)
{ {
...@@ -573,12 +574,14 @@ err: ...@@ -573,12 +574,14 @@ err:
} }
#if NOT_USED
int find_recovery_captain(THD* thd, MYSQL* mysql) int find_recovery_captain(THD* thd, MYSQL* mysql)
{ {
return 0; return 0;
} }
#endif
#if NOT_USED
pthread_handler_decl(handle_failsafe_rpl,arg) pthread_handler_decl(handle_failsafe_rpl,arg)
{ {
DBUG_ENTER("handle_failsafe_rpl"); DBUG_ENTER("handle_failsafe_rpl");
...@@ -626,7 +629,7 @@ err: ...@@ -626,7 +629,7 @@ err:
pthread_exit(0); pthread_exit(0);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
#endif
int show_slave_hosts(THD* thd) int show_slave_hosts(THD* thd)
{ {
......
...@@ -1128,14 +1128,14 @@ static void fix_tx_isolation(THD *thd, enum_var_type type) ...@@ -1128,14 +1128,14 @@ static void fix_tx_isolation(THD *thd, enum_var_type type)
static void fix_net_read_timeout(THD *thd, enum_var_type type) static void fix_net_read_timeout(THD *thd, enum_var_type type)
{ {
if (type != OPT_GLOBAL) if (type != OPT_GLOBAL)
thd->net.read_timeout=thd->variables.net_read_timeout; net_set_read_timeout(&thd->net, thd->variables.net_read_timeout);
} }
static void fix_net_write_timeout(THD *thd, enum_var_type type) static void fix_net_write_timeout(THD *thd, enum_var_type type)
{ {
if (type != OPT_GLOBAL) if (type != OPT_GLOBAL)
thd->net.write_timeout=thd->variables.net_write_timeout; net_set_write_timeout(&thd->net, thd->variables.net_write_timeout);
} }
static void fix_net_retry_count(THD *thd, enum_var_type type) static void fix_net_retry_count(THD *thd, enum_var_type type)
......
...@@ -2625,7 +2625,6 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type) ...@@ -2625,7 +2625,6 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type)
*/ */
thd->variables.max_allowed_packet= global_system_variables.max_allowed_packet thd->variables.max_allowed_packet= global_system_variables.max_allowed_packet
+ MAX_LOG_EVENT_HEADER; /* note, incr over the global not session var */ + MAX_LOG_EVENT_HEADER; /* note, incr over the global not session var */
thd->net.read_timeout = slave_net_timeout;
thd->master_access= ~(ulong)0; thd->master_access= ~(ulong)0;
thd->priv_user = 0; thd->priv_user = 0;
thd->slave_thread = 1; thd->slave_thread = 1;
......
...@@ -867,7 +867,7 @@ static int check_connection(THD *thd) ...@@ -867,7 +867,7 @@ static int check_connection(THD *thd)
return(ER_HANDSHAKE_ERROR); return(ER_HANDSHAKE_ERROR);
} }
DBUG_PRINT("info", ("IO layer change in progress...")); DBUG_PRINT("info", ("IO layer change in progress..."));
if (sslaccept(ssl_acceptor_fd, net->vio, thd->variables.net_wait_timeout)) if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout))
{ {
DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)", DBUG_PRINT("error", ("Failed to read user information (pkt_len= %lu)",
pkt_len)); pkt_len));
...@@ -897,7 +897,6 @@ static int check_connection(THD *thd) ...@@ -897,7 +897,6 @@ static int check_connection(THD *thd)
if ((thd->client_capabilities & CLIENT_TRANSACTIONS) && if ((thd->client_capabilities & CLIENT_TRANSACTIONS) &&
opt_using_transactions) opt_using_transactions)
net->return_status= &thd->server_status; net->return_status= &thd->server_status;
net->read_timeout=(uint) thd->variables.net_read_timeout;
char *user= end; char *user= end;
char *passwd= strend(user)+1; char *passwd= strend(user)+1;
...@@ -1029,6 +1028,10 @@ pthread_handler_decl(handle_one_connection,arg) ...@@ -1029,6 +1028,10 @@ pthread_handler_decl(handle_one_connection,arg)
NET *net= &thd->net; NET *net= &thd->net;
thd->thread_stack= (char*) &thd; thd->thread_stack= (char*) &thd;
/* Use "connect_timeout" value during connection phase */
net_set_read_timeout(net, connect_timeout);
net_set_write_timeout(net, connect_timeout);
if ((error=check_connection(thd))) if ((error=check_connection(thd)))
{ // Wrong permissions { // Wrong permissions
if (error > 0) if (error > 0)
...@@ -1058,6 +1061,11 @@ pthread_handler_decl(handle_one_connection,arg) ...@@ -1058,6 +1061,11 @@ pthread_handler_decl(handle_one_connection,arg)
if (thd->query_error) if (thd->query_error)
thd->killed= 1; thd->killed= 1;
} }
/* Connect completed, set read/write timeouts back to tdefault */
net_set_read_timeout(net, thd->variables.net_read_timeout);
net_set_write_timeout(net, thd->variables.net_write_timeout);
while (!net->error && net->vio != 0 && !thd->killed) while (!net->error && net->vio != 0 && !thd->killed)
{ {
if (do_command(thd)) if (do_command(thd))
...@@ -1261,7 +1269,7 @@ err: ...@@ -1261,7 +1269,7 @@ err:
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
/* /*
Read one command from socket and execute it (query or simple command). Read one command from connection and execute it (query or simple command).
This function is called in loop from thread function. This function is called in loop from thread function.
SYNOPSIS SYNOPSIS
do_command() do_command()
...@@ -1272,24 +1280,26 @@ err: ...@@ -1272,24 +1280,26 @@ err:
bool do_command(THD *thd) bool do_command(THD *thd)
{ {
char *packet; char *packet= 0;
uint old_timeout;
ulong packet_length; ulong packet_length;
NET *net; NET *net= &thd->net;
enum enum_server_command command; enum enum_server_command command;
DBUG_ENTER("do_command"); DBUG_ENTER("do_command");
net= &thd->net;
/* /*
indicator of uninitialized lex => normal flow of errors handling indicator of uninitialized lex => normal flow of errors handling
(see my_message_sql) (see my_message_sql)
*/ */
thd->lex->current_select= 0; thd->lex->current_select= 0;
packet=0; /*
old_timeout=net->read_timeout; This thread will do a blocking read from the client which
// Wait max for 8 hours will be interrupted when the next command is received from
net->read_timeout=(uint) thd->variables.net_wait_timeout; the client, the connection is closed or "net_wait_timeout"
number of seconds has passed
*/
net_set_read_timeout(net, thd->variables.net_wait_timeout);
thd->clear_error(); // Clear error message thd->clear_error(); // Clear error message
net_new_transaction(net); net_new_transaction(net);
...@@ -1318,7 +1328,10 @@ bool do_command(THD *thd) ...@@ -1318,7 +1328,10 @@ bool do_command(THD *thd)
vio_description(net->vio), command, vio_description(net->vio), command,
command_name[command])); command_name[command]));
} }
net->read_timeout=old_timeout; // restore it
/* Restore read timeout value */
net_set_read_timeout(net, thd->variables.net_read_timeout);
/* /*
packet_length contains length of data, as it was stored in packet packet_length contains length of data, as it was stored in packet
header. In case of malformed header, packet_length can be zero. header. In case of malformed header, packet_length can be zero.
......
...@@ -89,8 +89,8 @@ static int send_file(THD *thd) ...@@ -89,8 +89,8 @@ static int send_file(THD *thd)
The client might be slow loading the data, give him wait_timeout to do The client might be slow loading the data, give him wait_timeout to do
the job the job
*/ */
old_timeout = thd->net.read_timeout; old_timeout= net->read_timeout;
thd->net.read_timeout = thd->variables.net_wait_timeout; net_set_read_timeout(net, thd->variables.net_wait_timeout);
/* /*
We need net_flush here because the client will not know it needs to send We need net_flush here because the client will not know it needs to send
...@@ -134,7 +134,7 @@ static int send_file(THD *thd) ...@@ -134,7 +134,7 @@ static int send_file(THD *thd)
error = 0; error = 0;
err: err:
thd->net.read_timeout = old_timeout; net_set_read_timeout(net, old_timeout);
if (fd >= 0) if (fd >= 0)
(void) my_close(fd, MYF(0)); (void) my_close(fd, MYF(0));
if (errmsg) if (errmsg)
......
...@@ -96,7 +96,7 @@ void vio_reset(Vio* vio, enum enum_vio_type type, ...@@ -96,7 +96,7 @@ void vio_reset(Vio* vio, enum enum_vio_type type,
vio->in_addr =vio_ssl_in_addr; vio->in_addr =vio_ssl_in_addr;
vio->vioblocking =vio_ssl_blocking; vio->vioblocking =vio_ssl_blocking;
vio->is_blocking =vio_is_blocking; vio->is_blocking =vio_is_blocking;
vio->timeout =vio_ssl_timeout; vio->timeout =vio_timeout;
} }
else /* default is VIO_TYPE_TCPIP */ else /* default is VIO_TYPE_TCPIP */
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
......
...@@ -416,15 +416,4 @@ int vio_ssl_blocking(Vio * vio __attribute__((unused)), ...@@ -416,15 +416,4 @@ int vio_ssl_blocking(Vio * vio __attribute__((unused)),
} }
void vio_ssl_timeout(Vio *vio __attribute__((unused)),
uint which __attribute__((unused)),
uint timeout __attribute__((unused)))
{
#ifdef __WIN__
ulong wait_timeout= (ulong) timeout * 1000;
(void) setsockopt(vio->sd, SOL_SOCKET,
which ? SO_SNDTIMEO : SO_RCVTIMEO, (char*) &wait_timeout,
sizeof(wait_timeout));
#endif /* __WIN__ */
}
#endif /* HAVE_OPENSSL */ #endif /* HAVE_OPENSSL */
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