If the client sends data before authentication is complete, it must not be
discarded and it needs to be processed like as if it was sent in a
separate network packet.
The enums exposed by the connector are not intended to be used by the
users of the library. The fact that the protocol, and other, modules used
it was in violation of how the library is intended to be used.
Adding an internal mapping into MaxScale also removes some of the
dependencies that the core has on the connector.
Cleaned up the MaxScale version of the mysql.h header by removing all
unused includes. This revealed a large amount of dependencies on these
removed includes in other files which needed to be fixed.
Also sorted all includes in changed files by type and alphabetical
order. Removed explicit revision history from modified files.
When a session is being closed in a controlled manner, i.e. a COM_QUIT is
received from the client, it is possible to deduce from this fact that the
backend connections are very likely to be idle. This can be used as an
additional qualification that must be met by all connections before they
can be candidates for connection pooling.
This assumption will not hold with batched and asynchronous queries. In
this case it is possible that the COM_QUIT is received from the client
before even the first result from the backend is read. For this to work,
the protocol module would need to track the number and state of expected
responses.
When a LOAD DATA LOCAL INFILE is done, the last packet is an empty packet
which does not contain the command byte. Some parts of the MySQL protocol
modules expected that a command is always present. The proper way to
handle this is to use the mxs_mysql_get_command function which does bounds
checking.
If a connection has not been fully established (i.e. authentication has
been completed) then it should not be considered as a connection pool
candidate.
The initial setting of sql_mode affects how MaxScale initially
behaves with respect to autocommit.
When 'set sql_mode=[default|oracle];" is encountered, the query
classifier and autocommit modes are adjusted accordingly.
That's where it belongs as it is only the mysql client protocol that
will use it. It's a bit unfortunate that the qc test program compare
now needs to include a file from a protocol module directory, but
the fact is that the query classifier implementation and the test
programs should actually be *under* the mysql client protocol module.
The parser is needed not only by mysql_client but also by the test
program of the qc-plugins, so it need to be available someplace
common.
Not that nice that both a qc-component and mysql_client will include
stuff from server/core/maxscale, but at least temporarily ok.
SetSqlModeParser is a custom parser for detecting "SET SQL_MODE=..."
statements. It will be used in mysql_client and the result will be
used for updating the sql_mode of a session (that is to be added).
Thereafter, whenever a statement arrives, the value of that sql_mode
will be used for setting the mode of the query_classifier.
A custom parser for detecting "set sql_mode=ORACLE" is needed
and writing that is C++ is more convenient than writing it in
C. Consequently, so as to be able to use that parser, mysql_client
must be compiled as C++.
With this change, it is no longer possible that the server version
is deallocated at the very moment it is read. There is still a race,
but it's mostly harmless.
The template class wraps a HashMap such that only a few operations
are allowed. Usage requires specializing a RegistryTraits class
template for each entry type.
If a connection has not been fully established (i.e. authentication has
been completed) then it should not be considered as a connection pool
candidate.
This was originally removed, since it was checking the same word
twice. However, the parsing is clearer with it and the cost is only
paid when the KILL is detected, which is very rare.
Also, fix some incorrect parsing.
The text-version of "KILL CONNECTION" command is now supported. To keep the
overhead low, only minimal parsing is done on the query. The query
needs to start in the beginning of the mysql-packet, have no comments
and have limited whitespace as the total length of the query is limited.
Both "KILL 123" and "KILL CONNECTION 123" are accepted.
"KILL QUERY 123" is also accepted but not acted on, as it requires larger
changes.
The server internal session id may be larger than 4 bytes (MariaDB uses 8)
but only 4 are sent in the handshake. The full value can be queried
from the server, but this query is not supported by MaxScale yet. In any
case, both the protocol and MXS_SESSION now have 64 bit counters. Only the
low 32 bits are sent in the handshake, similar to server.
Various small changes to part2, as suggested by comments and otherwise.
Mostly renaming, working logic should not change.
Exception: session id changed to 64bit in the container and associated
functions. Another commit will change it to 64bit in the session itself.
MySQL sessions are added to a hasmap when created, removed when closed.
MYSQL_COM_PROCESS_KILL is now detected, the thread_id is read and the kill
command sent to all worker threads to find the correct session. If found, a
fake hangup even is created for the client dcb.
As is, this function is of little use since the client could just disconnect
itself instead. Later on, additional commands of this nature will be added.
The `user`, `password`, `version_string` and `weightby` values should be
allocated as a part of the service structure. This allows them to be
modified at runtime without having to worry about memory allocation
problems.
Although this removes the problem of reallocation, it still does not make
the updating of the strings thread-safe. This can cause invalid values to
be read from the service strings.
Preparation for adding KILL syntax support.
Session id changed to uint32 everywhere. Added atomic op.
Session id can be acquired before session_alloc().
Added session_alloc_with_id(), which is given a session id number.
Worker object has a session_id->SESSION* mapping, not used yet.
Removed pthread_self calls from the backend modules. This makes the debug
logging easier to parse when the messages aren't prefixed with the verbose
thread ID.
When statement based routing was used, it was possible that the current
statement being executed wasn't properly updated. Readwritesplit requires
it to track whether a command will create a response.
The static capabilities declared in getCapabilities allows certain
capabilities to be queried before instances are created. The intended use
of this capability is to remove the need for the `is_internal_service`
function.
Transaction boundaries can now be detected using regexes.
All else being equal, it gives a 10% performance improvement
compared to qc-based detection.
In a subsequent change, mysql_client.c will be modified to use
qc_get_trx_type_mask() instead of qc_get_type_mask().
Currently the use of regex matching is turned on using an
environment variable. That will change.
The core now provides a simple function to close a session. This removes
the need for the modules to directly call the API entry points when the
session should be closed. It is also in line with the style that other
objects, namely the DCBs, use. This makes the new session_close very
similar to dcb_close.
The client protocol module can resolve whether a password was used based
on the information the authenticators gather before authentication is
done. It uses the authentication token length as the basis on which it
makes the decision.
Currently the only situation where a user needs to be authenticated after
the initial authentication is when a COM_CHANGE_USER is being
executed. This was previously handled by directly calling a function in
the MySQLAuth authenticator.
The new entry in the API of the authenticators is very specific to MySQL
and should be reviewed once other protocols are added.
Refactored common code into a reusable function. Now all of the backend
error handling uses the same function.
Moved responsibility of the DCB error handling tracking to the backend
protocol. The routers no longer need to manage the
`dcb->dcb_errhandle_called` variable of the failed DCB.
Removed calls to handleError with client DCBs as parameters. All of the
routers close the DCB given to handleError if it is a client DCB. The only
time the error handler would be called is when the routeQuery function
fails. The handleError call is redundant as the router already knows that
the session should be closed when it returns from routeQuery.