Before the transaction migration is implemented, the connection must be
closed if a transaction is open and the connection to the master is
lost. Doing this retains the same transactionality as a direct connection
to the server would.
When a non-connected target is chosed as the target server and the session
command history is not empty, the query needs to be placed into the query
queue and routed only after the session commands have been executed.
Enabling the session command history but limiting it to a history of 50
commands allows reconnections for sessions that don't change the state too
often.
As pooled connections will exceed this limit quite fast, they are not able
to reconnect to servers once connections are lost. To solve this problem,
the session command history needs a compaction process that removes
redundant history.
The `master_reconnection` parameter now controls both the reconnection of
the master server as well as the migration of the master server to another
server. Although these two cases appear to be different, the end result
from readwritesplit's point of view is the same and are thus controlled
with the same parameter.
The RWBackend class now resets its internal state when it is closed. This
allows readwritesplit to handle the case when a result was expected from
the master but the master died before the result was returned. The same
code should also handle slave connection failures mid-result, allowing
Backend reuse.
Added a test case that verifies the new functionality when combined with
`master_failure_mode=error_on_write`.
Moved session command execution into the Backend class itself as the
session commands are defined as a related part of it. This allows all
connections to execute session commands if some are available.
Removed explicit SERVER_REF usage in the readwritesplit connection
creation code and replaced it with SRWBackend. This allows the removal of
the get_root_master_backend function which duplicated the functionality in
get_root_master.
Disabled the reconnection in clientReply prior to moving the connection
creation code into routeQuery. This allows new connections to be made when
they are needed.
Provides a clearer separation between what deals with query
classification and what deals with query routing.
Functions have only been moved. No other cleanup has been
done.
When a multi-statement query consisting completely of UPDATE statements is
received, the packets can be received in two separate buffers. To cope
with this situation, the state change into REPLY_STATE_RSET_COLDEF must
only be done if the buffer contains more than a single packet.
By making it conditional, we prevent the problems that arise when the
replication protocol is used in combination with the session state change
tracking. In addition to this, it prevents unnecessary work for routers
and filters that don't need it.
If the connection to the backend where a read-only transaction is being
performed fails, the Backend object should be closed for it. This fixes a
debug assertion in readwritesplit.cc:check_and_log_backend_state which
asserts that the failed connection must not be in use after the error
handling is done.
Also reordered the failing assertion and the accompanying error message so
that the error is logged first.
With the `allow_master_change` parameter enabled, sessions can start using
a different master node if one is available. This will not prevent
sessions from closing if a write query is received while no master
replacement is available.
When readwritesplit receives a reply from a backend, an info level log
message is now logged. This allows easier debugging of situations where
replies aren't properly returned by the router.
Removed false error message about failed session commands. An error in
response to a session command is a perfectly valid result.
Also added the explicit commands that the master and slave return to the
warning that is logged when the results differ.
* MXS-199: Support Causal Read in Read Write Splitting
* move most causal read logic into rwsplit router and get server type from monitor
* misc fix: remove new line
* refactor, move config to right place, replace ltrim with gwbuf_consume
* refacter a little for previous commit
* fix code style
The default value for strict_multi_stmt prevents compound statements and
atomic multi-statement commands from being executed without completely
disabling load balancing. As the new default value will have no practical
effect on all correct uses of readwritesplit, this is a relatively safe
thing to change.
When binary data was processed, it was possible that the values were
misinterpreted as OK packets which caused debug assertions to trigger.
In addition to this, readwritesplit did not handle the case when all
packets were routed individually.
A multi-statements can return multiple resultsets in one response. To
accommodate for this, both the readwritesplit and modutil code must be
altered.
By ignoring complete resultsets in readwritesplit, the code can deduce
whether a result is complete or not.
Returning the results of a query as a set of packets is currently more
efficient. This is mainly due to the fact that each individual packet for
single packet routing is allocated from the heap which causes a
significant loss in performance.
Took the new capability into use in readwritesplit and modified the
reply_is_complete function to work with non-contiguous results.
The multi-statement detection did not check for the existence of
semicolons before doing the heavier processing.
Calculcate the packet length only once for the result state management.
Replace the original version of the function with the reference version
and use it everywhere. Added runtime assertions to check that an invalid
DCB is never processed.
As the DCB passed as the clientReply parameter is guaranteed to match one
of the DCBs in the RWBackends. By using a reference, the need to copy a
shared_ptr is removed (along with the atomic operation that it implies)
thus reducing the overhead in the clientReply and the functions it uses.
The result collection did not reset properly when a non-resultset was
returned for a request. As collected result need to be distinguishable
from single packet responses, a new buffer type was added.
The new buffer type is used by readwritesplit which uses result collection
for preparation of prepared statements.
Moved the current command tracking to the RWBackend class as the command
tracked by the protocol is can change before a response to the executed
command is received.
Removed a false debug assertion in the mxs_mysql_extract_ps_response
function that was triggered when a very large prepared statement response
was processed in multiple parts.
Inlined the getter/setter type functions that are often used. Profiling
shows that inlining the RWBackend get/set functions for the reply state
manipulation reduces the relative cost of the function to acceptable
levels. Inlining the Backend state function did not have as large an
effect but it appears contribute a slight performance boost.
The result processing code did unnecessary work to confirm that the result
buffers are contiguous. The code also assumed that multiple packets can be
routed at the same time when in fact only one contiguous result packet is
returned at a time.
By assuming that the buffers are contiguous and contain only one packet,
most of the copying and buffer manipulation can be avoided.
When readwritesplit is routing any queued queries, the currently executed
command of the protocol modules needs to be adjusted by
readwritesplit. This is not a true fix but more of a workaround to fix the
problems of queued query execution.
The correct solution would be to move the queued query handling into the
client protocol module so that all components see the same state.
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.
The EOF packet calculation function in modutil.cc didn't handle the case
where the payload exceeded maximum packet size and could mistake binary
data for a ERR packet.
The state of a multi-packet payload is now exposed by the
modutil_count_signal_packets function. This allows proper handling of
large multi-packet payloads.
Added minor improvements to mxs1110_16mb to handle testing of this change.
The connections for a router session can now be done without a constructed
router session. This simplifies the creation of new router session by
removing the need to handle memory allocations.
Readwritesplit router sessions are now created in the static `create`
function which handles the actual creation of the connections and
allocation of the session itself.