Bug #86356 please send COM_QUIT and read EOF with recv() in mysql_close().
Submitted: 17 May 2017 14:13 Modified: 16 Nov 2017 4:20
Reporter: Takanori Sejima Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: C API (client library) Severity:S4 (Feature request)
Version:5.7.18 OS:Linux
Assigned to: CPU Architecture:Any

[17 May 2017 14:13] Takanori Sejima
Description:
mysql_close() seems to close the connection as follows.

1. send COM_QUIT by setting skip_check flag with simple_command
2. mysql_socket_shutdown(, SHUT_RDWR)
3. mysql_socket_close()

Because it is sending COM_QUIT with skip_check flag enabled, there is a possibility that it becomes "Simultaneous Close Sequence" of RFC 793(Page.39,  Figure 14.). 

In fact, in my environment, there was a case where TIME_WAIT remained in both the application server using mysql_close() and mysqld.

How to repeat:
see the code.

https://github.com/mysql/mysql-server/blob/mysql-5.7.18/sql-common/client.c#L5130-L5142
https://github.com/mysql/mysql-server/blob/mysql-5.7.18/sql-common/client.c#L5140
https://github.com/mysql/mysql-server/blob/mysql-5.7.18/sql-common/client.c#L1334-L1337
https://github.com/mysql/mysql-server/blob/mysql-5.7.18/sql-common/client.c#L1588-L1598
https://github.com/mysql/mysql-server/blob/mysql-5.7.18/vio/vio.c#L160
https://github.com/mysql/mysql-server/blob/mysql-5.7.18/vio/vio.c#L393-L399
https://github.com/mysql/mysql-server/blob/mysql-5.7.18/vio/vio.c#L168
https://github.com/mysql/mysql-server/blob/mysql-5.7.18/vio/viosocket.c#L424-L426

Suggested fix:
After sending COM_QUIT, confirm that 0 is returned by recv etc (confirm EOF). Alternatively, on Linux, POLLRDHUP also allows you to confirm that mysqld has closed the connection.
[17 May 2017 15:47] Takanori Sejima
Using COM_QUIT allows sending FIN from mysqld, but it is not good that TIME_WAIT remains in the client that sent COM_QUIT.
[16 Nov 2017 4:20] MySQL Verification Team
Hello Takanori-San,

Thank you for the feature request and feedback!

Thanks,
Umesh
[6 Jul 2018 8:18] Yoshinori Matsunobu
I think the change will be as simple as the following.

@@ -6368,12 +6368,11 @@ void STDCALL mysql_close(MYSQL *mysql)
-        simple_command(mysql,COM_QUIT,(uchar*) 0,0,1);
+        simple_command(mysql,COM_QUIT,(uchar*) 0,0,0);

The change will have a side effect that closing a connection involves additional round trip, so some people may not like the change. It would make more sense to add a client option to control the behavior.