The schemarouter should always use Backend::write for communication with
the backend servers. This keeps the backends in the correct state.
This fix solves some of the random test failures in the `sharding` test.
The feedback system wasn't used and was starting to cause problems on
Debian 9 where the libcurl required different version of OpenSSL than what
MaxScale was linked against.
The schemarouter can now resolve database mapping conflicts in a
deterministic manner. This will fix the problem of central databases which
are replicated shards being assigned in a non-deterministic manner.
When the current database is implicitly used in a query that also uses an
explicit database, it must be routed to the shard which has the current
database.
As cross-shard joins are not supported, the safest, and possibly the most
expected course of action to take, is to route it to the so-called default
shard. The default shard is the shard that contains the database that is
currently set as the active database with a COM_INIT_DB, a text protocol
USE <database> query or it was set at connection time.
The schemarouter info level logging treated all queries as something that
contain SQL statements. This, for somewhat obvious reasons, cannot be
expected.
The avrorouter failed to detect ALTER TABLE statements which caused a
regression. Extended the alter table tests to parse the JSON for more
strict validation of test results.
The avrorouter failed to detect ALTER TABLE statements which caused a
regression. Extended the alter table tests to parse the JSON for more
strict validation of test results.
Added FAKE_ROTATE event info log.
Changed: log of Request file and pos only if the binlog_name is not
empty (it can be empty when setting the GTID value before CHANGE MASTER
TO)
A call to strcpy was made in blr_file_create where the function was given
the same pointer as both parameters. To avoid this, the file name is now
copied to a local variable before the router variables are modified.
The EVP_CIPHER_CTX is now created inside a wrapper function to add support
for OpenSSL 1.1. Also fixed improper use of the EVP_CIPHER_CTX internals
in binlogrouter.
The EVP_CIPHER_CTX is now created inside a wrapper function to add support
for OpenSSL 1.1. Also fixed improper use of the EVP_CIPHER_CTX internals
in binlogrouter.
When the router session is locked to the master, the storage of prepared
statements is not necessary as no other server can be used. The ID sent by
the client can be used without modification as it will always be the same
on the master.
The column information does not contain the used tables and the correct
function to use is qc_get_table_names.
Added a utility function for iterating over the set of tables. This
removes the need to have the same table iteration code in multiple places
and makes the code easier to comprehend.
The return value of the comparison was misinterpreted so that the
selection process preferred the new candidate over the current one if both
were equal. This was not an intended change and only a better candidate
should be chosen over the current candidate.
As readwritesplit queues queries, it needs to extract the command from the
buffer when the queued queries are routed. It cannot rely on the client
protocol command when the rerouting is taking place.
Cleaned up some of the comments and documentation for the
functions. Renamed some variables and moved parts of the error handling
logging into a subfunction.
The routing information is now gathered into a struct before the routing
process is started. This allows the requirements of the query to be
gathered before the actual target is selected.
The common readwritesplit header was split into three distinct parts; the
instance, session and prepared statement headers. The definitions of any
members were moved to .cc files away from the headers.
The RWSplitSession, with its RWBackend class, is declared in the
rwsplitsession.hh header with all relevant definitions in
rwsplitsession.cc.
The PSManager class and all prepared statement related functions are now
located in the rwsplit_ps.hh header.
The old readwritesplit.hh header now contains the instance level
structures and all common classes used by the router. The
rwsplit_internal.hh header could be absorbed into the three newly created
headers with new headers for distinct parts of the router.
Changed the ROUTER_INSTANCE struct to a class and added functions for
common operations.
Renamed configuration and statistics structures and added constructors.
Moved objects around in readwritesplit.hh to be ready for a split into
multiple headers.
The COM_STMT_FETCH queries are always executed when the result has not
been fully read. This means that the statement queuing code needs to allow
COM_STMT_FETCH commands to pass if a statement is being executed but the
command queue is empty.
The COM_STMT_EXECUTE targets are now tracked per statement ID. This should
theoretically allow parallel execution of COM_STMT_EXECUTE commands that
use cursors but the current implementation of the reply state processing
does not yet allow it.
Tracking of the node where the last COM_STMT_EXECUTE was sent allows
routing of all following COM_STMT_FETCH to the same node. This is required
for cursors to work.
MariaDB/MySQL does not support multiple active cursors so the
COM_STMT_FETCH will always refer to the latest COM_STMT_EXECUTE and using
a different ID goes against the protocol. If/when the support for multiple
active cursors is added, the tracking should be done for each
COM_STMT_EXECUTE statement. This should be relatively easily to achieve
but currently it is unnecessary.
Session commands that will not return a response can be completed
immediately. This requires some special code in the readwritesplit Backend
class implementation as well as a small addition to the Backend class
itself.
Since not all commands expect a response from the server, the queued query
routing function needs some adjustment. The routing of queued queries
should be attempted until a command which expects a response is found or
the queue is empty.
By properly handling these types of session commands, the router can
enable the execution of COM_STMT_CLOSE and COM_STMT_RESET on all
servers. This will prevent resource leakages in the server and allow
proper handling of COM_STMT type command.
If the internal ID is stored in the buffer when it is moving inside the
readwritesplit router, the RWBackend can manage the execution of all
commands with a statement ID by replacing the stored ID with the correct
value.
When a COM_STMT_EXECUTE or a COM_STMT_SEND_LONG_DATA command is executed,
the query type of the prepared statement is used. This allows read-only
prepared statements to be load balanced across slaves.
Mapping the handles returned to the client to a session command ID allows
the mapping of client handle to the backend specific handle. Currently,
the mapping is used for diagnostic output only.
The class manages both text and binary protocol prepared statement ID to
type mapping. The text protocol statements are mapped by their plaintext
name and the binary protocol statements are mapped by the session command
ID of the prepared statement.
By mapping the binary protocol prepared statement type to the session
command identifier, we can store the types for both styles of prepared
statements in a very similar manner. When the prepared statement handle is
received from the backend and is sent to the client, the client handle to
session command ID mapping can be done. This allows the mapping of both
client and backend PS handles to internal session command IDs.
The readwritesplit Backend implementation maps the returned PS handles to
session command identifiers. This allows the handles to be retrieven later
on when the prepared statements are executed.