208 Commits

Author SHA1 Message Date
Markus Mäkelä
c5581faae7 Always collect contiguous results for COM_CHANGE_USER
The response to the COM_CHANGE_USER should always be turned into a
contiguous buffer of complete packets. This guarantees that the code that
processes it functions properly.
2017-08-29 22:24:00 +03:00
Markus Mäkelä
866a15dafa Skip COM_CHANGE_USER for COM_QUIT
As COM_QUIT would terminate the connection, there's no need to initiate
the session reset process. Also make sure all buffers are empty before
putting the DCB into the pool.

Added extra debug assertions for parts of the code that are related to the
COM_CHANGE_USER processing.
2017-08-29 11:15:06 +03:00
Markus Mäkelä
13f7015e7b Fix EOF packet calculation for large rows
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.
2017-08-25 17:00:42 +03:00
Johan Wikman
9c25e6d995 MXS-1376 All zombie related code removed
As dcbs are now closed when dcb_close() is called and there is
no zombie queue, the zombie state can also be removed.
2017-08-25 14:48:16 +03:00
Markus Mäkelä
bc889b1b41 MXS-1375: Fix double response to COM_CHANGE_USER
When a persistent connection is reused, a COM_CHANGE_USER command is
executed to reset the session state. If the reused connection was closed
before the response to the COM_CHANGE_USER was received and taken into use
by another connection, another COM_CHANGE_USER would be sent to, again,
reset the session state. Due to the fact that the first response is still
on its way, it will appear as if two responses are generated for a single
COM_CHANGE_USER.

The way to fix this is to avoid putting connections that haven't been
successfully reset into the connection pool.
2017-08-24 09:30:08 +03:00
Markus Mäkelä
5b1f8afcd9 MXS-1366: Validate closed connections before pooling them
When a session is being closed in a controlled manner, i.e. a COM_QUIT is
received from the client, it is possible to deduce from this fact that the
backend connections are very likely to be idle. This can be used as an
additional qualification that must be met by all connections before they
can be candidates for connection pooling.

This assumption will not hold with batched and asynchronous queries. In
this case it is possible that the COM_QUIT is received from the client
before even the first result from the backend is read. For this to work,
the protocol module would need to track the number and state of expected
responses.
2017-08-21 10:31:07 +03:00
Markus Mäkelä
55c704a3dd Ignore repeated errors
Only the first error for each DCB should invoke the error handler
routine. All other errors for the same DCB should be ignored.

In practice this appears to happen when epoll return two different types
of error events for the same DCB.
2017-08-18 10:27:28 +03:00
Markus Mäkelä
6c5ae24dff Fix out-of-bounds reads with LOAD DATA LOCAL INFILE
When a LOAD DATA LOCAL INFILE is done, the last packet is an empty packet
which does not contain the command byte. Some parts of the MySQL protocol
modules expected that a command is always present. The proper way to
handle this is to use the mxs_mysql_get_command function which does bounds
checking.
2017-08-18 10:27:28 +03:00
Esa Korhonen
7ba0533cc8 Authenticator API extract-entrypoint returns bool
Extraction either succeeds or fails, it does not need to return
defined integer values.
2017-08-09 17:28:58 +03:00
Markus Mäkelä
35de0c392f Only store established connections in the pool
If a connection has not been fully established (i.e. authentication has
been completed) then it should not be considered as a connection pool
candidate.
2017-08-09 09:22:57 +03:00
Esa Korhonen
8e9c943d48 Proxy protocol setting error detection + documentation
The setting parsing is now similar to the other server settings.
The header is printed if log_info is on.
Changed the setting name to simply "proxy_protocol".
Updated documentation.
2017-08-04 11:43:29 +03:00
Markus Mäkelä
782b8db2aa Fix readwritesplit handling of unexpected responses
The backend server can send a response even if the client hasn't sent a
request. One case where this occurs is when the server is shutting
down. The internal logic of readwritesplit can't handle unexpected states
gracefully so the safest thing to do is to just ignore them and send the
responses to the client.
2017-08-02 11:51:26 +03:00
Markus Mäkelä
25fd5a8a93 Fix crash on session allocation failure
The the return value was used before it was checked.
2017-06-30 11:07:18 +03:00
Markus Mäkelä
16201592a2 MXS-852: Fix execution of COM_STMT_FETCH
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.
2017-06-29 15:53:50 +03:00
Markus Mäkelä
52b7fb9340 MXS-852: Handle one-way session commands
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.
2017-06-29 15:53:50 +03:00
Markus Mäkelä
3c4e1e3b4b MXS-852: Use stored query type for COM_STMT_EXECUTE
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.
2017-06-29 15:53:49 +03:00
Markus Mäkelä
77f78c4b20 MXS-852: Map client PS handle to internal ID
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.
2017-06-29 15:53:49 +03:00
Markus Mäkelä
dd90ad01b6 MXS-852: Add PS response and command extraction functions
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.
2017-06-29 15:53:49 +03:00
Johan Wikman
6cd6ded3d8 Merge branch '2.1-oracle-compat' into develop-new-merge-oracle 2017-06-29 09:39:55 +02:00
Johan Wikman
bea551092d MXS-1278: Change modes when 'set sql_mode=' is encountered.
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.
2017-06-28 21:36:08 +02:00
Johan Wikman
057ba4156d MXS-1278: Turn on ORCALE mode dynamically
If statement input is required for a session, we check the input
for "SET SQL_MODE..." statements and adjust the query classifier
accordingly.
2017-06-28 21:36:08 +02:00
Johan Wikman
12a291919a MXS-1275: SetSqlModeParser moved under MySQLClient
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.
2017-06-28 21:36:08 +02:00
Johan Wikman
b385e862b0 MXS-1275: Move SetSqlModeParser to .../server/core/maxscale
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.
2017-06-28 21:36:08 +02:00
Johan Wikman
4bf2b27b3e MXS-1275: Accept @@[SESSION|GLOBAL].sql_mode = ... 2017-06-28 21:36:08 +02:00
Johan Wikman
21c1845798 MXS-1275: Accept LOCAL as a synonum for SESSION 2017-06-28 21:36:08 +02:00
Johan Wikman
2483f95be2 MXS-1275: Test comment handling 2017-06-28 21:36:08 +02:00
Johan Wikman
1c6c19d6ae MXS-1275: Inherit TrxBoundaryParser from CustomParser 2017-06-28 21:36:08 +02:00
Johan Wikman
9386143437 MXS-1275: Test also using non-contiguous statements 2017-06-28 21:33:04 +02:00
Johan Wikman
ee27efd62e MXS-1275: Add custom parser for "SET SQL_MODE=..."
SetSqlModeParser is a custom parser for detecting "SET SQL_MODE=..."
statements. It will be used in mysql_client and the result will be
used for updating the sql_mode of a session (that is to be added).

Thereafter, whenever a statement arrives, the value of that sql_mode
will be used for setting the mode of the query_classifier.
2017-06-28 21:33:04 +02:00
Johan Wikman
cd1e3f26cf MXS-1275: Compile mysql_client as C++
A custom parser for detecting "set sql_mode=ORACLE" is needed
and writing that is C++ is more convenient than writing it in
C. Consequently, so as to be able to use that parser, mysql_client
must be compiled as C++.
2017-06-28 21:33:04 +02:00
Markus Mäkelä
705d29ea41 MXS-852: Fix prepared statement collection
If a prepared statement response was collected into one buffer, it doesn't
need to be processed again. By jumping directly to the routing of the
collected result, we prevent the unnecessary splitting of buffers that
appears to happend with continuous preparations of prepared statements.
2017-06-22 10:40:19 +03:00
Markus Mäkelä
bd7a26d830 Abstract the session default database
The default database can now be manipulated with a set of functions
exposed by the maxscale/protocol/mysql.h header. This removes the need to
handle the structures themselves in the modules and is a step towards
moving the dcb->data contents inside the session.
2017-06-22 10:40:16 +03:00
Johan Wikman
4696c7e662 MXS-1249: Set the server version for qc 2017-06-21 13:28:59 +03:00
Johan Wikman
3e39ec906e Change server version from char pointer to char array
With this change, it is no longer possible that the server version
is deallocated at the very moment it is read. There is still a race,
but it's mostly harmless.
2017-06-19 14:05:26 +03:00
Markus Mäkelä
d59e98e238 MXS-1267: Remove DCB cloning
The DCB cloning is no longer needed as the tee filter now does the session
branching by simulating a local client connection.
2017-06-02 13:07:02 +03:00
Markus Mäkelä
e43cdcf741 MXS-1267: Expose MySQL backend authentication
Refactored the backend authentication functions so that they can be
exposed to the tee filter. This allows the tee filter to use the same
functions as the protocol modules use without having to reimplement them
inside the tee filter.
2017-06-02 13:07:02 +03:00
Johan Wikman
f546a17e77 Update change date of 2.2 2017-06-01 10:24:20 +03:00
Esa Korhonen
dbfd631fed Change session registry to a template class
The template class wraps a HashMap such that only a few operations
are allowed. Usage requires specializing a RegistryTraits class
template for each entry type.
2017-05-19 10:16:37 +03:00
Markus Mäkelä
17ba824d9f Only close valid sessions
When a session is being closed, the state needs to be checked. If the
session creation failed, the session need to be only freed.
2017-05-16 11:39:57 +03:00
Markus Mäkelä
4117dcf410 Only store established connections in the pool
If a connection has not been fully established (i.e. authentication has
been completed) then it should not be considered as a connection pool
candidate.
2017-05-15 19:32:02 +03:00
Esa Korhonen
39da11763b Add test for parse_kill_query() 2017-05-11 12:41:13 +03:00
Esa Korhonen
4add7a14fc parse_kill_query() now also expects the "KILL"
This was originally removed, since it was checking the same word
twice. However, the parsing is clearer with it and the cost is only
paid when the KILL is detected, which is very rare.

Also, fix some incorrect parsing.
2017-05-11 12:06:42 +03:00
Esa Korhonen
a0cd067a03 KILL [CONNECTION | QUERY] support, part3
The text-version of "KILL CONNECTION" command is now supported. To keep the
overhead low, only minimal parsing is done on the query. The query
needs to start in the beginning of the mysql-packet, have no comments
and have limited whitespace as the total length of the query is limited.
Both "KILL 123" and "KILL CONNECTION 123" are accepted.

"KILL QUERY 123" is also accepted but not acted on, as it requires larger
changes.
2017-05-10 13:43:28 +03:00
Esa Korhonen
aebe839990 Change session id to 64bit
The server internal session id may be larger than 4 bytes (MariaDB uses 8)
but only 4 are sent in the handshake. The full value can be queried
from the server, but this query is not supported by MaxScale yet. In any
case, both the protocol and MXS_SESSION now have 64 bit counters. Only the
low 32 bits are sent in the handshake, similar to server.
2017-05-10 13:26:25 +03:00
Esa Korhonen
ee20191645 KILL [CONNECTION | QUERY] support, part2B
Various small changes to part2, as suggested by comments and otherwise.
Mostly renaming, working logic should not change.

Exception: session id changed to 64bit in the container and associated
functions. Another commit will change it to 64bit in the session itself.
2017-05-08 09:58:02 +03:00
Esa Korhonen
17f6e94cba KILL [CONNECTION | QUERY] support, part2
MySQL sessions are added to a hasmap when created, removed when closed.
MYSQL_COM_PROCESS_KILL is now detected, the thread_id is read and the kill
command sent to all worker threads to find the correct session. If found, a
fake hangup even is created for the client dcb.

As is, this function is of little use since the client could just disconnect
itself instead. Later on, additional commands of this nature will be  added.
2017-05-08 09:51:07 +03:00
Markus Mäkelä
e62be5034a Use constant sized arrays for some service strings
The `user`, `password`, `version_string` and `weightby` values should be
allocated as a part of the service structure. This allows them to be
modified at runtime without having to worry about memory allocation
problems.

Although this removes the problem of reallocation, it still does not make
the updating of the strings thread-safe. This can cause invalid values to
be read from the service strings.
2017-05-04 09:17:48 +03:00
Esa Korhonen
bfd94c2b31 KILL [CONNECTION | QUERY] support, part1
Preparation for adding KILL syntax support.
Session id changed to uint32 everywhere. Added atomic op.
Session id can be acquired before session_alloc().
Added session_alloc_with_id(), which is given a session id number.
Worker object has a session_id->SESSION* mapping, not used yet.
2017-05-02 10:29:55 +03:00
Esa Korhonen
8f50269338 Add proxy protocol support
Adds a server-specific parameter, "use_proxy_protocol". If enabled,
a header string is sent to the backend when a routing session connection
changes state to MXS_AUTH_STATE_CONNECTED. The string contains the real
client IP and port.
2017-04-27 12:29:46 +03:00
Markus Mäkelä
36d06960bf Combine query preparation into one function
The same operations of protocol state and inspections of the buffer were
done in multiple places. Combining these into one function removes the
duplicated code.
2017-04-20 14:22:55 +03:00