Commit Graph

91 Commits

Author SHA1 Message Date
ae43e4f0f2 MXS-2013 Remove all CHK_-macros 2018-08-15 09:28:04 +03:00
c01840ffb3 Remove unnecessary SConfig from readwritesplit
The configuration doesn't need to be contained in shared pointer as each
session holds its own version of it. This removes most of the overhead in
configuration reloading. The only thing that's left is any overhead added
by the use of thread-local storage.
2018-08-06 21:20:29 +03:00
d7a3980308 Read correct parameter for causal_reads
The configuration used the wrong parameter name. The test also did not
explicitly enable tracking of the last_gtid variable which caused it to
fail if it wasn't already on.
2018-07-31 09:41:09 +03:00
6c59da77fb Merge branch '2.2' into develop 2018-07-26 11:27:09 +03:00
2acf5f545e MXS-1066 Add query hint to route to last used server
Add new hint type and support for it in the readwritesplit router.
2018-07-13 11:11:02 +03:00
f3c84d84c7 Fix transaction migration
The transaction migration in the case of a changed master never worked as
transaction replay would only be triggered when the master fails. To cover
this case, the transaction replay just needs to be started when the need
for a transaction migration is detected.

To help diagnose the behavior, the Trx class no longer logs a message when
a transaction is closed. This is now done by readwritesplit which has more
knowledge of the context in which the transaction is closed.
2018-07-11 14:08:50 +03:00
86cdb14286 Don't process queued commands when replaying transaction
If a transaction is replayed, queued commands must not be processed. The
exception to this rule is when pending session commands are executed
before the first statement in the replayed transaction is executed.
2018-07-11 14:08:47 +03:00
0614ff4c9d Fix handling of transactions with large results
If transaction replaying was enabled and a result was returned in more
than one call to clientReply, a NULL value would be added to the statement
which in turn would trigger a debug assertion.

Similarly any following statements in the transaction would be executed
regardless of whether the result was complete.

Renamed the statement execution function to better describe what it does.

Extended the basic functional test case to cover this.
2018-07-11 14:08:47 +03:00
bd4be3a97b Use shared configurations in readwritesplit
By using a shared pointer instead of a plain object, we can replace the
router configuration without it affecting existing sessions. This is a
change that is required to enable runtime reconfiguration of
readwritesplit.
2018-07-11 14:08:45 +03:00
8d7cb27884 Remove faulty debug assertion
The debug assertion was missing the check for the queued commands.
2018-07-02 13:29:21 +03:00
9c6cc713c8 Remove unnecessary session command logging
All executed session commands were logged in the RWSplitSession
destructor. This is not really necessary and shouldn't have been placed
there in the first place.
2018-07-02 13:29:20 +03:00
12398bfc26 MXS-1549: Implement optimistic transaction execution
When the `optimistic_trx` mode is enabled, all transactions are started on
a slave server. If the client executes a query inside the transaction that
is not of a read-only nature, the transaction is rolled back and replayed
on the master.
2018-07-02 13:29:19 +03:00
d6a964304b MXS-1549: Always store previous target
Unconditionally update the previous target on each routed query. This
allows routing to the previous server in case it is needed. One example of
this is a new type of hint that allows routing to the same server where
the previous query was sent.

Also added a minor clarifying comment to the resetting of the
current_query.
2018-07-02 13:29:18 +03:00
93fdada534 Fix crash on trx replay with session command
Readwritesplit would crash with the following transaction:

    BEGIN;
    SET @a = 1; -- This is where it would crash
    COMMIT;

When a session command was a part of the transaction, empty queries
(i.e. NULL GWBUFs) would be added to the transaction. If the transaction
were to be replayed, MaxScale would crash when these NULL queries were
executed.

Once the empty responses were fixed, the replaying of the transaction
would fail with a checksum mismatch. This was caused by the wrong order of
processing in RWSplitSession::clientReply. The response processing for
session commands was done after the response processing for replayed
transactions. This would trigger a checksum comparison too early for the
transaction in question.
2018-06-30 19:26:23 +03:00
cc0299aee6 Update change date of 2.3 2018-06-25 10:07:52 +03:00
e561c3995c Use correct write in Backend::execute_session_command
Backend::execute_session_command would use the overridden write method
instead of the Backend::write method that it intended to use. This caused
session commands that did not expect a response to be in a state that
expected a result.

Also fixed RWBackend::write pass the response_type value to
Backend::write.
2018-06-22 10:37:11 +03:00
6278f27ab6 Merge branch '2.2' into develop 2018-06-20 10:26:29 +03:00
1f166482b2 Fix slave reconnection regression
The state of the backend needs to be checked before any pending session
commands are executed on it.

Added debug assertions to catch invalid use of the status functions of
closed backends.
2018-06-18 14:25:05 +03:00
2005164222 Fix slave reconnection logic
Allowing calls to select_connect_backend_servers even when all slaves are
connected solves the debug assertion in select_connect_backend_servers
that happens when the execution of a queued query causes a new connection
to be created.
2018-06-15 16:16:53 +03:00
3ed6411741 Fix debug assert on reconnection with session commands
When a query was routed to a server that must first be connected to, the
expected response count was not updated for the executed session commands.
2018-06-15 16:16:53 +03:00
0d73530ff3 Merge branch '2.2' into develop 2018-06-08 11:30:55 +03:00
445eece95b MXS-1507: Fix replaying of empty transactions
If the starting of a transaction was interrupted by a server failure, the
query needs to be retried. This needs to be done as a transaction replay
to keep the routing logic consistent and simple.

When a non-autocommit transaction is interrupted, there will be no query
in progress and no replaying is needed. To handle this case, the replay
initialization logic needed to be altered to treat truly empty
transactions as a success case.
2018-06-04 19:26:36 +03:00
4a3216d483 Merge branch '2.2' into develop 2018-06-04 16:00:19 +03:00
2bbf1271c9 Fix large packet execution
The number of expected responses was not correctly tracked for large
packets.
2018-05-28 13:51:05 +03:00
a33f09ad06 Fix test failures and add debug logging
Fixed test failures, increased some of the timeouts, added extra info
level logging into rwsplit to help debug the test failures.
2018-05-22 17:46:27 +03:00
730fd9f30d MXS-1778: Rename variables and change default values
The causal read timeout now has a default value of 120 seconds. Removed
the redundant `enable` part from the names of the member variables.
2018-05-22 17:46:26 +03:00
4ba0ac434b MXS-1778: Add support for MariaDB GTID tracking
The MariaDB implementation allows the last GTID to be tracked with the
`last_gtid` variable. To do this, the configuration option
`session_track_system_variables=last_gtid` must be used or it must be
enabled at runtime.
2018-05-22 17:46:26 +03:00
91cc5b1e89 MXS-1828: Simplify LOAD DATA LOCAL INFILE handling
By relying on the server to tell us that it is requesting the loading of a
local infile, we can remove one state from the state machine that governs
the loading of local files. It also removes the need to handle error and
success cases separately.

A side-effect of this change is that execution of multi-statement LOAD
DATA LOCAL INFILE no longer hangs. This is done by checking whether the
completion of one command initiates a new load.

The current code recursively checks the reply state and clones the
buffers. Neither of these are required nor should they be done but
refactoring the code is to be done in a separate commit.

Added two helper functions that are used to detect requests for local
infiles and to extract the total packet length from a non-contiguous
GWBUF.
2018-05-18 09:46:07 +03:00
d6c44aaf52 MXS-1804: Allow large session commands
Session commands that span multiple packets are now allowed and will
work. However, if one is executed the session command history is disabled
as no interface for appending to session commands exists.

The backend protocol modules now also correctly track the current
command. This was a pre-requisite for large session commands as they
needed to be gathered into a single buffer and to do this the current
command had to be accurate.

Updated tests to expect success instead of failure for large prepared
statements.
2018-05-03 09:46:47 +03:00
ff8a7c8b93 MXS-1507: Add transaction replay statistics
Added a simple counter for the number of replayed transactions.
2018-05-03 09:46:46 +03:00
5d010ff712 Cleanup SERVER struct
Removed one unused field. Rearranged others, clarified comments.
2018-04-27 10:48:56 +03:00
c97d2c94eb MXS-1825: Fix PS output parameter tracking for MySQL variants
The resultset processing for MySQL requires some extra work as it lacks
the proper SERVER_MORE_RESULTS_EXIST flag in the last EOF packet. Instead,
the first EOF packet has the SERVER_PS_OUT_PARAMS flag which needs to be
interpreted as a SERVER_MORE_RESULTS_EXIST flag for the second EOF packet.

Also corrected the EOF packet handling to do the flag checks in the code
that deals with the EOF packets.

As the modutil_state parameter is now used for more than large packet
tracking, the correct solution is to store this state object in the
readwritesplit session instead of interpreting it to a boolean value.
2018-04-26 16:02:09 +03:00
0df326d581 MXS-1824: Track only the opening of cursors
Whether a cursor is open or not does not matter as long as the attempt to
open a cursor is detected.
2018-04-26 16:02:09 +03:00
092532745d MXS-1507: Add transaction size limit
Added the `transaction_replay_max_size` parameter that controls the
maximum size of a transaction that can be replayed. If the limit is
exceeded, the stored statements are released thus preventing the
transaction from being replayed.

This limitation prevents accidental misuse of the transaction replaying
system when autocommit is disabled. It also allows the user to control the
amount of memory that MaxScale will use.
2018-04-26 13:44:26 +03:00
7de7e7b2fe MXS-1507: Replay read-only transaction
Read-only transactions are now replayed if the node in question fails.
2018-04-26 13:44:25 +03:00
2848f96945 MXS-1507: Make transaction replay configurable
The transaction retrying behavior is now configurable and documented. The
`transaction_replay` parameter implicitly enables the required
functionality in the router that it needs.
2018-04-26 13:44:25 +03:00
c1c942a058 MXS-1507: Retry interrupted queries in transactions
As the current query was added to the transaction log before it finished,
the m_current_query contained a duplicate of the latest transaction log
entry. To correctly log only successful transactions, the statement should
be added only after it has successfully completed. This change also
removed the unnecessary cloning that took place when the statement was
added to the log before it finished.

With the fixed transaction logging, the value of m_current_query can be
stashed for later retrying while the replay process is happening. If the
replay completes successfully and the checksums match, the interrupted
query is retried.

Also added a clarifying comment to can_retry_query to explain why a query
inside a transaction cannot be retried.
2018-04-26 13:44:25 +03:00
01bf5cc8b0 MXS-1507: Add initial implementation of transaction replay
Added the initial implementation of transaction replay. Transactions are
only replayed if the master fails when no statement is being executed.

The validity of the replayed transaction is done by verifying that the
checksums of the returned results are equal.

Added a close function into the Trx class to make resetting its state
easier. Also changed the return type of the pop_stmt to GWBUF* as the
places where it is used expect a raw GWBUF pointer.
2018-04-26 13:44:25 +03:00
daecb6980b MXS-1507: Use same mechanism for all delayed routing
Passing the delay to the retry_query function allows the same function to
be used in all cases. This removes duplicate code.
2018-04-26 13:44:25 +03:00
050af8fb52 MXS-1810: Create Trx class
The class encapsulates the relevant information of a transaction.
2018-04-26 13:44:24 +03:00
94038933d8 MXS-1810: Store transaction contents
The queries that make up the transaction are now stored in the router
session while the transaction is in progress. For the time being, the
queries are only used to log extra information about the transaction
contents.
2018-04-26 13:44:24 +03:00
53a5685dc2 MXS-1810: Add transaction checksums
Readwritesplit now calculates checksums for all successful and failed
transactions. This checksum is not of any practical use until the
transaction replaying is implemented.
2018-04-26 13:44:23 +03:00
7d97bf76ea MXS-1625 Remove duplicate function
Correct test in remaining function.
2018-04-17 10:09:37 +03:00
ec33fcf87d Merge branch '2.2' into develop 2018-04-13 14:53:00 +03:00
da03c73373 MXS-1776: Fix COM_STMT_EXECUTE flag extraction
The code extracted the statement id, not the flags.
2018-04-12 10:25:10 +03:00
fab8477c05 MXS-1776: Fix utility functions
The COM_STMT_FETCH command will create a response. This was a
readwritesplit-specific interpretation of the command and it was wrong.

Also record the currently executed command event for session commands.
2018-04-12 09:44:28 +03:00
ad5458f0e7 MXS-1776: Initialize RWBackend::m_command
The variable was not initialized which caused COM_CHANGE_USER to produce
unexpected behavior.
2018-04-12 09:43:38 +03:00
311adf817f MXS-1776: Handle recursive COM_STMT_EXECUTE commands
Readwritesplit would not handle multiple overlapping COM_STMT_EXECUTE
commands properly if they opened cursors. This was due to the fact that
the result would not be marked as complete and COM_STMT_FETCH commands
were executed as if they did not return results.

The correct implementation is to consider a COM_STMT_EXECUTE that opens a
cursor complete only when the first EOF packet is read (that is, when the
resultset header is read). This allows subsequent COM_STMT_FETCH commands
to be handled separately.

The separate COM_STMT_FETCH handling must count the number of packets that
are being fetched. This allows correct tracking of the state of a
COM_STMT_FETCH by checking that the number of packets is correct or the
second EOF/ERR packet is read.
2018-04-11 15:26:37 +03:00
1da33c4423 MXS-1625 Remove RWS RouteInfo
Now uses the one in QueryClassifier directly.
2018-04-10 17:41:59 +03:00
9be98df41c MXS-1625 Move RouteInfo to QueryClassifier 2018-04-10 17:41:59 +03:00