OpenSSL 1.1 supports most of the native threading libraries, including
pthread. This means that only versions before 1.1 need the thread handling
code.
Deleting a stack allocated object will cause an immediate crash whereas
only calling the destructor will successfully complete the call with a
possibility of leaked memory or a crash later on.
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 test uses binary protocol prepared statements with cursors. The second
part of the test will not pass as the test uses parallel execution of
prepared statements.
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.
The mxs_mysql_extract_ps_response function extracts the binary protocol
prepared statement components and stores them in a common structure.
The mxs_mysql_get_command extracts the command byte from a GWBUF object
containing a complete MySQL packet.
The firewall uses a bitmask for representing what operations a
particular rule should be applied to. Consquently it cannot use
the query classifier qc_query_op_t enumerator values as such,
as they are consecutive numbers.
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.
The default sql mode must now be provided explicitly when the query
classifier is setup. This is in preparation for "sql_mode" becoming
a global configuration parameter of MaxScale.
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 current sql mode will be tracked in that variable. Since one
thread will handle multiple sessions, we need to track the sql mode
of a session, so that the sql mode of the query classifier can be
set whenever we handle a request of a particular session.
As the sql-mode will be managed by the client protocol, the data
can be private to it as well.
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.