The hangup and error handlers now have unique messages. Although the
behavior in the handlers is practically the same in both cases, the cause
of the error is not the same.
If a socket error is present, it is added to the error message. If an
error is present, it should clearly show the reason why the TCP socket was
closed.
The is_fake_event boolean helps distinguish fake events from real
ones. This makes figuring out the real source of hangup events easier.
The client count was incremented before authentication was complete, and
should be decremented if it fails. Otherwise service connection limit can
be easily reached.
If a query returned multiple resultsets and the connection was broken
between the resultsets, the backend would not know that parts of the
response were already sent. This is caused by the cyclic nature of the
state machine when multi-result responses are being processed.
To fix the problem, the result size is tracked to know how many bytes have
been sent to the client. This is a backport of the
MySQLProtocol::Result::size from 2.5(develop).
The backend DCBs do not have to send hangups in the close protocol API
method. If the conditions for the hangup were true, the session was
already stopping meaning that the client DCB was already closed.
If an error is generated while a COM_CHANGE_USER is being done, it would
always use the sequence number 1. To properly handle this case and send
the correct sequence number, the COM_CHANGE_USER progress needs to be
tracked at the session level.
The information needs to be shared between the backend and client
protocols as the final OK to the COM_CHANGE_USER, with the sequence number
3, is the one that the backend server returns. Only after this response
has been received and routed to the client can the COM_CHANGE_USER
processing stop.
As is explained in MDEV-19893:
Client reads from socket, gets the packet from 1. with seqno=0, which
it does not expect, since seqno is supposed to be incremented. Client
complains, throws tantrums and exceptions.
To cater for clients that do not expect out-of-bound messages
(i.e. server-initiated packets with seqno 0), all messages generated by
MaxScale should use at least sequence number 1.
Deep-copying prevents subsequent modifications done by the caller from
affecting the data that can be potentially stored in the write queue of
the backend's DCB.
mxs::Buffer::iterator is not a random-access iterator and hence will have
linear cost. This is too costly to do on every packet with even moderately
sized resultsets.
RWBackend did not expect that a resultset and an unexpected ERR packet
could be stored in the same buffer. This can happen for example if a
server shuts down immediately after the resultset is sent.
If a packet with a KILL query was followed with another packet in the same
network buffer, the code wouldn't work as it expected to receive only one
packet at a time.