WL#14166: xproto: notify on connection close
Motivation
When a client sees a connection close from the server, it may have several reasons:
- server shutdown
- server crash
- network loss
- connection idled too long
- connection kill
In case of a idling connection or killed connection, the server is still running and the client just can reconnect to it.
In the other cases, a client may want to connect to other servers.
Goal
Allow an xprotocol client to distinguish
- a recoverable connection loss from a
- a server failure.
Functional requirements
- F1
- Server MUST send a global-notice with information about reason for disconnection when it actively closes the connection in case of server shutdown, or connection kill.
- F2
- User should be able to check how many global notices were sent by server
- F3
- Notices MUST ONLY be sent after successful authentication.
Implementation
Notice for idling connection was added under: WL#9267 - Mysqlx connection timeout.
It was designed as Notice
of type Warning
, which allows the client application
to display the warning message directly to the user.
Idle connection close - current behavior
X Plugin sends following "Warning" notice for idle connections, where the error code is set to "ER_IO_READ_ERROR", and "global" scope:
Mysqlx.Notice.Frame {
type: 1
payload: "Mysqlx.Notice.Warning { level: ERROR code: ER_IO_READ_ERROR msg: \"IO Read error: read_timeout exceeded\" }"
}
in case when client doesn't send data for time specified by: Mysqlx_read_timeout
or Mysqlx_wait_timeout
:
client->server: Request-1
client<-server: Response-1
...client is idle for at last `Mysqlx_wait_timeout` seconds...
client<-server: Notice(scope=Global, Warning{code:ER_IO_READ_ERROR, msg:...})
client<-server: TCP(RST,FIN)
or
client->server: Request-1
client<-server: Response-1
client->server: Request-2-first_part_of_two
...client is idle for at last `Mysqlx_read_timeout` seconds...
client<-server: Notice(scope=Global, Warning{code:ER_IO_READ_ERROR, msg:...})
client<-server: TCP(RST,FIN)
Clean server shutdown - new behavior
On a clean server shutdown the X Plugin sends 'Warning' notice on all open xprotocol connections, where the error code is set to "ER_SERVER_SHUTDOWN", and "global" scope:
client<-server: Notice(scope=Global, Warning{code:ER_SERVER_SHUTDOWN, msg:...})
followed by:
- shutdown(send)
- close()
Where the whole flow is going to contain two notices:
client->server: Request-1
client<-server: Response-1
...server is shutting down ...
client<-server: Notice(scope=Global, Warning{code:ER_SERVER_SHUTDOWN, msg:...})
client<-server: TCP(RST,FIN)
Client killed - new behavior
Server sends a "Warning" notice in case when a session was killed (from another session). The notice is not needed in case when session was killed in middle of SQL execution and server already send a fatal error followed by disconnection:
client->server: Request-1
...connection was killed from other client...
client<-server: Error(severity:Fatal, code:ER_QUERY_INTERRUPTED...)
client<-server: TCP(RST,FIN)
in other case, the notice is needed:
client->server: Request-1
client<-server: Response-1
...connection was killed from other client...
client<-server: Notice(scope=Global, Warning{code:ER_SESSION_WAS_KILLED, msg:...})
client<-server: TCP(RST,FIN)
Instrumentation
Server sends the reason of connection closure in a notice, with scope set to "global" and type is set to "warning", thus server must also increment following status-variables when sending those:
- Mysqlx_notice_warning_sent
Property | Value |
---|---|
Variable Name | Mysqlx_notice_warning_sent |
Type | integer |
Scope | GLOBAL, SESSION |
Default | 0 |
* Mysqlx_notice_global_sent
Property | Value |
---|---|
Variable Name | Mysqlx_notice_global_sent |
Type | integer |
Scope | GLOBAL, SESSION |
Default | 0 |
* Mysqlx_messages_sent
Property | Value |
---|---|
Variable Name | Mysqlx_messages_sent |
Type | integer |
Scope | GLOBAL, SESSION |
Default | 0 |
Client side
Client may consider displaying all "Warning" notices to the user, without analyzing its payload. If there is need of analyzing why client got disconnected from the server, it may depend on error codes present in "Warning" notice.
The current list of error codes that are used in "Warning" notices is following:
- ER_IO_READ_ERROR (code: 1810)
- ER_SERVER_SHUTDOWN (code: 1053)
- ER_SESSION_WAS_KILLED (code: 3169)
Where error messages for those error codes are already defined by the server.