Bug #65956 | client and libmysqlclient VIO drops connection if signal received during read() | ||
---|---|---|---|
Submitted: | 20 Jul 2012 6:45 | Modified: | 10 Jan 2013 11:07 |
Reporter: | David Basden | Email Updates: | |
Status: | Won't fix | Impact on me: | |
Category: | MySQL Server: C API (client library) | Severity: | S3 (Non-critical) |
Version: | 5.5.25a, 5.5.27 | OS: | Linux (Likely any POSIX.1-2001) |
Assigned to: | CPU Architecture: | Any | |
Tags: | regression |
[20 Jul 2012 6:45]
David Basden
[23 Jul 2012 16:54]
Vojtech Kurka
Maybe a duplicate of http://bugs.mysql.com/bug.php?id=62578
[23 Jul 2012 19:10]
Sveta Smirnova
Thank you for the report. Verified as described. Versions 5.0 and 5.7 are not affected.
[25 Jul 2012 14:14]
Davi Arnaut
The retry logic is at a higher level. If you take a look at my_real_read(), there is a check for the case when read is interrupted due to a signal: 831│ if ((length= vio_read(net->vio, pos, remain)) <= 0L) 832│ { 833├> my_bool interrupted = vio_should_retry(net->vio); 834│ If the read() was interrupted with a signal, the read is retried but only up to a certain amount: 877├> if (retry_count++ < net->retry_count) 878│ continue; This was done on purpose to allow client applications to interrupt threads waiting on socket used by the MySQL client library. If you do not wish to have this behavior, please increase the retry_count from it's default of 1.
[25 Jul 2012 14:17]
Davi Arnaut
Also, the patch is wrong. It is going to retry any read interrupted by a signal, even when used in the context of the server. In the server, such interruptions are used, for example, to implement killing threads that are waiting to read from a client.
[25 Jul 2012 14:42]
Davi Arnaut
Also, this behavior was changed in MySQL 5.6 and up. For the client library, interrupted I/O operations are now always retried.
[10 Jan 2013 11:07]
Erlend Dahl
From the internal analysis: 5.6 has an implementation where read is done indefinitely in case of socket interrupts(func: net_should_retry in net_serv.cc). Backporting this logic to 5.5 (in my_real_read(NET *net, size_t *complen)) might create some other issues including removing the possibility of developer to react to signals. As this bug is neither a security issue nor a customer bug, it is suggested that it is better not fixed.
[16 Jan 2013 6:50]
xiaobin lin
Davi , you are right, in 5.6, SA_RESTART makes the system call "recv " locks like blocking. We occur this problem too, and I find that what makes 5.5 (libmysqlclient.so.18.0.0) different from 5.1(libmysqlclient.so.16.0.0), is that client api in 5.1 , the THREAD_SAFE_CLIENT is defined, so #if defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) if (vio_errno(net->vio) == SOCKET_EINTR) { DBUG_PRINT("warning",("Interrupted write. Retrying...")); continue; } #endif /* defined(THREAD_SAFE_CLIENT) && !defined(MYSQL_SERVER) */ makes the client retry, so it is not limited by the net->retry_count. But in 5.5, defined(THREAD_SAFE_CLIENT) is *ALWARYS* false, so error comes out. ******** Can anybody tell me how to enable THREAD_SAFE_CLIENT in 5.5? I tried -DENABLED_THREAD_SAFE_CLIENT=ON, but THREAD_SAFE_CLIENT is not defined yet. Do I miss anything, or it is a bug in cmake process? Thanks
[6 Jul 2013 7:21]
Clint Byrum
Found and tracked in Debian here: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=715065
[11 Jul 2016 12:21]
Laurynas Biveinis
See also http://bugs.mysql.com/bug.php?id=82019