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++.
If a prepared statement response was collected into one buffer, it doesn't
need to be processed again. By jumping directly to the routing of the
collected result, we prevent the unnecessary splitting of buffers that
appears to happend with continuous preparations of prepared statements.
The default database can now be manipulated with a set of functions
exposed by the maxscale/protocol/mysql.h header. This removes the need to
handle the structures themselves in the modules and is a step towards
moving the dcb->data contents inside the session.
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.
Refactored the backend authentication functions so that they can be
exposed to the tee filter. This allows the tee filter to use the same
functions as the protocol modules use without having to reimplement them
inside the tee filter.
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.
Adds a server-specific parameter, "use_proxy_protocol". If enabled,
a header string is sent to the backend when a routing session connection
changes state to MXS_AUTH_STATE_CONNECTED. The string contains the real
client IP and port.
The same operations of protocol state and inspections of the buffer were
done in multiple places. Combining these into one function removes the
duplicated code.
The backend MySQL protocol can now collect prepared statement preparation
responses as well as result sets. This removes the need to parse and
collect the preparation responses at the router level.
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.
The functions used to track the resultset EOF packets now expose the
position of the end of the result set. This allows the modules that use
them to check if more results exist in the same buffer.
Added the status bits for OK and EOF packets to the mysql.h protocol
header. This can be used to check for various state changes that happen in
the session. Currently the status bits are only used to detect if more
results are expected.
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.
When batched queries are done through readwritesplit, it will now handle
them one by one. This allows batched queries to be used with
readwritesplit but it does impose a performance penalty when compared to
direct execution on the backend.
This reverts commit f3c83770903151a0a3b53593c3e05fa0af94cd5f. The
functionality was used implicitly by modules that declare the
RCAP_TYPE_CONTIGUOUS_OUTPUT capability.
The RCAP_TYPE_STMT_OUTPUT is not used in its previous form. It can be
altered to route only complete packets back to the client. This allows
routers to do safer parsing on the results.
When log messages are written with both address and port information, IPv6
addresses can cause confusion if the normal address:port formatting is
used. The RFC 3986 suggests that all IPv6 addresses are expressed as a
bracket enclosed address optionally followed by the port that is separate
from the address by a colon.
In practice, the "all interfaces" address and port number 3306 can be
written in IPv4 numbers-and-dots notation as 0.0.0.0:3306 and in IPv6
notation as [::]:3306. Using the latter format in log messages keeps the
output consistent with all types of addresses.
The details of the standard can be found at the following addresses:
https://www.ietf.org/rfc/rfc3986.txthttps://www.rfc-editor.org/std/std66.txt
The new type allows routers to send queries and get complete result sets
as a response. This allows the routers to easily send commands that create
result sets and which are parsed by the router.
Currently only the schemarouter benefits from this new capability as it
generates the database mappings by parsing the output of a SHOW DATABASES
query.
Some of the protocol modules use ssize_t instead of size_t.
Split the function that counts the number of response packets a session
command will receive into two parts. This allows it to be reused
elsewhere.
The binlogrouter error handling closed the DCB twice. This was caused by
the change in the way the DCB error handling is done.
The protocol modules now also call the error handling routine even if the
router session is NULL. This enables the binlogrouter to manage
authentication failures correctly instead of trying to reconnect again.
The readwritesplit now sends COM_PING queries to backend servers that have
been idle for too long. The option is configured with the
`connection_keepalive` parameter.