Worker is now the base class of all workers. It has a message
queue and can be run in a thread of its own, or in the calling
thread. Worker can not be used as such, but a concrete worker
class must be derived from it. Currently there is only one
concrete class RoutingWorker.
There is some overlapping in functionality between Worker and
RoutingWorker, as there is e.g. a need for broadcasting a
message to all routing workers, but not to other workers.
Currently other workers can not be created as the array for
holding the pointers to the workers is exactly as large as
there will be RoutingWorkers. That will be changed so that
the maximum number of threads is hardwired to some ridiculous
value such as 128. That's the first step in the path towards
a situation where the number of worker threads can be changed
at runtime.
A new class mxs::Worker will be introduced and mxs::RoutingWorker
will be inherited from that. mxs::Worker will basically only be a
thread with a message-loop.
Once available, all current non-worker threads (but the one
implicitly created by microhttpd) can be creating by inheriting
from that; in practice that means the housekeeping thread, all
monitor threads and possibly the logging thread.
The benefit of this arrangement is that there then will be a general
mechanism for cross thread communication without having to use any
shared data structures.
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.
The old hkheartbeat variable was changed to the mxs_clock() function that
simply wraps an atomic load of the variable. This allows it to be
correctly read by MaxScale as well as opening up the possibility of
converting the value load to a relaxed memory order read.
Renamed the header and associated macros. Removed inclusion of the
heartbeat header from the housekeeper header and added it to the files
that were missing it.
The current command needs to be updated before the queries are actually
routed. This allows the KILL command detection and processing to correctly
work.
Moved the RWBackend class implementation into its own file. Made some of
the command type functions a part of the <maxscale/protocol/mysql.h>
header to make it reusable.
With the configuration entry
dump_last_statements=[never|on_close|on_error]
you can now specify when and if to dump the last statements
of of a session.
With the configuration entry
retain_last_statements=<unsigned>
or the debug flag '--debug=retain-last-statements=<unsigned>',
MaxScale will store the specified number of last statements
for each session. By calling
session_dump_statements(session);
MaxScale will dump the last statements as NOTICE messages.
For debugging purposes.
The DCB pointer in the MySQLProtocol struct doesn't appear to be updated
in all cases which causes it to be an unreliable source. As the session
itself is always available and it always has the service pointer properly
set, it should be used instead.
Also removed the dead protocol compression code and replaced the
parameters with the service capability bits.
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.
With the changes in this commit it is possible to add and remove
MaxScale specific user variables. A MaxScale specific user variable
is a user variable that is interpreted by MaxScale and that
potentially changes the behaviour of MaxScale.
MaxScale specific user variables are of the format "@maxscale.x.y"
where "@maxscale" is a mandatory prefix, x a scope identifying the
component that handles the variable and y the component specific
variable. So, a variable might be called e.g. "@maxscale.cache.enabled".
The scope "core" is reserved (although not enforced yet) to MaxScale
itself.
The idea is that although MaxScale catches these, they are passed
through to the server. The benefit of this is that we do not need to
detect e.g. "SELECT @maxscale.cache.enabled", but can let the result
be returned from the server.
The interpretation of a provided value is handled by the component that
adds the variable. In a subsequent commit, it will be possible for a
component to reject a value, which will then cause an error to be
returned to the client.
There are 3 new functions:
- session_add_variable() using which a variable is added,
- session_remove_variable() using which a variable is removed, and
- session_set_variable_value().
The two former ones are to be called by components, the last one by
the protocol that catches the "set @maxscale..." statements.
Given the value in a statement like "SET SQL_MODE=..." this parser
is capable of deducing whether SQL_MODE is set to DEFAULT or ORACLE
or something else.
SetParser is capable of returning the exact variable and value
of a "SET X=Y" statement, in the cases where X is of a specific
set of variables; currently "SQL_MODE" and "@MAXSCALE...".
The actual value of the SET statement also needs to be parsed in
the case of SQL_MODE, but it becomes unnecessary convoluted if that
information somehow should conditionally be expressable in a return
value.
So, the value will be parsed separately.
When backend SSL connections were created, the connection creation was
done twice. This was due to the lacking detection of an already
established SSL connection.
If a DCB is closed before a response to the handshake packet is received,
the DCB's session will point to the dummy session. In this case no error
should be written to the DCB.
This is a cherry-pick of commit f53e112bf49766f1cc55516c2d7ee571461d483f
from the 2.2 branch.
The tests are now built by default. This should make it easier for users
to verify that they have a working MaxScale.
Also made the building of test_parse_kill conditional like the rest of the
tests.
* 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
By always starting the session shutdown process by stopping the client
DCB, the manipulation of the session state can be removed from the backend
protocol modules and replaced with a fake hangup event.
Delivering this event via the core allows the actual dcb_close call on the
client DCB to be done only when the client DCB is being handled by a
worker.
Directly closing the client DCB in the backend protocol modules is not
correct anymore as the state of the session doesn't change when the client
DCB is closed. By propagating the shutdown of the session with a fake
hangup to the client DCB, the closing of the DCB is done only once.
Added debug assertions that make sure all DCBs are closed only
once. Removed redundant code in the backend protocol error handling code.
If a DCB is closed before a response to the handshake packet is received,
the DCB's session will point to the dummy session. In this case no error
should be written to the DCB.
Length-encoded strings should be consumed with the correct
functions. Doing pointer arithmetic with the same pointer as a parameter
appears to fail only on CentOS 6 whereas on newer systems it performs as
expected.