[MDEV-14113] MS: Add linger option on TCP sockets Created: 2017-10-24 Updated: 2020-12-08 Resolved: 2017-12-21 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Server |
| Fix Version/s: | 10.3.3 |
| Type: | Task | Priority: | Major |
| Reporter: | Sergey Vojtovich | Assignee: | Vladislav Vaintroub |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | contribution, foundation | ||
| Sprint: | 10.3.3-1 |
| Description |
|
|
| Comments |
| Comment by Sergey Vojtovich [ 2017-10-24 ] |
|
The idea is generally fine, but I think we can have it always enabled. That is DISABLE_TCP_LINGER and cmake changes should not be needed. Also we should not need tcp_linger variable. tcp_linger_timeout alone should be enough. I'd avoid define TCP_LINGER_TIMEOUT. Just put default timeout directly into sys_var. |
| Comment by Vladislav Vaintroub [ 2017-10-25 ] |
|
https://www.nybek.com/blog/2015/03/05/cross-platform-testing-of-so_linger/ actually does not recommend setting SO_LINGER to {on,timeout > 0} cross-platform. However, according to the same article , call to shutdown() before closesocket() on Windows would make closesocket() to return immediately, and connection closed in background, as if setsockopt(SO_LINGER) was not called. I checked our code, and we do shutdown() before closesocket() ( this does not make much sense, but we have this since long time already). So, the questions are :
|
| Comment by Sepherosa Ziehau [ 2017-11-14 ] |
|
It's not only waiting for the sent data to be acknowledged, but also waiting for the connection's FIN being ACKed. I don't know about how Windows handling shutdown(2) then close(2), but on all other systems, close(2) will obey the SO_LINGER settings, no matter whether the shutdown(2) was called or not. As about shutdown(2) before close(2), I don't think the shutdown(2) immediately before the close(2) is necessary; removing it would save some syscall cost. I'd suggest to remove it, no matter whether this patch could be in or not. Generally speaking, I think SO_LINGER option is fine (the compile time option is unnecessary; all systems have this option). But it will put the close(2) into sleep, so I'd suggest to default off for this option. And don't call setsockopt(2), if this option is off, which introduces unnecessary syscall cost. Thanks, |
| Comment by Vladislav Vaintroub [ 2017-11-14 ] |
|
Sepherosa Ziehau, thanks for commenting. Is this your patch?
The nybeck.com seems to have done quite a lot of research on the option, which if I summarize here, would be : except Windows, where things work as expected, the SO_LINGER setting is really only useful either with timeout 0, or when sender wants to wait for specific time to ensure receiver gets the data, before closing connection. timeout >= 0 on Windows and timeout = 0 on Unixes can be used to abort connection, so there are no connections in TIME_WAIT, so for that we can have the tcp_linger option, which I'd propose to make an "int" variable, in the {-1, 65535} range , -1 meaning default "off". With that, 0 linger is allowed and can actually be used on Unixes, where other timeout does not make much sense. Speaking of our client-server protocol, the connection closure is normally initiated by the client, who sends COM_QUIT packet, closes the socket, and then server closes the socket as well. In other cases, server is the first to close socket. I think there is at least one legitimate case, where server should abort the connection, rather than orderly close. That is, when server sends a large result set to the client, but the client is reading much slower than server is writing, so that socket buffers fill up, and server's send() runs into timeout. Do you think we should abort the connection via SO_LINGER= {on,0}in this case? Can you give your thoughts on following:
|
| Comment by Sepherosa Ziehau [ 2017-11-15 ] |
|
> is this correct, that, outside of Windows, linger timeout > 0 does not make much sense, because it does not abort connection via RST? This is correct. > should the server abort connection if send() runs into timeout, disregarding tcp_linger settings. This is correct too. However, the retransmission timeout could be quite lengthy. I am not the author. I talked to the author about the background and the intention yesterday. We lean toward TCP keepalive based solution instead of this one at the moment. We will keep you updated on these. |
| Comment by Vladislav Vaintroub [ 2017-11-15 ] |
|
>> should the server abort connection if send() runs into timeout, disregarding tcp_linger settings. >This is correct too. However, the retransmission timeout could be quite lengthy. If server cannot send a packet within net_write_timeout seconds, connection is closed (should really be aborted as we just discussed) |
| Comment by Vladislav Vaintroub [ 2017-11-15 ] |
|
speaking if TCP keepalive, we have an upcoming patch for it as well |
| Comment by Sepherosa Ziehau [ 2017-11-16 ] |
|
As for the userland send timeout. It's kinda different, an example: Thanks, |
| Comment by Vladislav Vaintroub [ 2017-12-05 ] |
|
Sepherosa Ziehau It would use abortive close, (no linger), if connection ran into timeout. I think this is going to the most frequent cases, where server close connection first (usually client does it). In this case, server does not care about TCP retransmission (as discussed, this would happen when writing large result sets and client application reads at slower pace than server writes) There are some other cases where server would close the socket before client does it, e.g during connection on failed authentication. But then, server sends an error message, and it does somewhat care that the client receives it. The patch also cleans up socket timeout handling, so that Windows is consistent with another platforms (using nonblocking socket IO + waiting in poll/select on single socket, rather than setsockopt). This makes identifying timeouts easier. I also removed the superficial shutdown() before closesocket() in places where it was used, because it reportedly breaks SO_LINGER on Windows. |
| Comment by Sepherosa Ziehau [ 2017-12-06 ] |
|
This is definitely a step forward to the right direction! The diff looks good. Thank you very much! |
| Comment by Vladislav Vaintroub [ 2017-12-12 ] |
|
I pushed the mentioned patch into 10.3. Please let us know if there is anything else we should do WRT lingering. |