Documentation cleanup for Limitations.md
Headers are now more consistent. Reordered headers. Changed wording.
This commit is contained in:
@ -1,182 +1,177 @@
|
|||||||
# Limitations and Known Issues within MariaDB MaxScale
|
# Limitations and Known Issues within MariaDB MaxScale
|
||||||
|
|
||||||
The purpose of this documentation is to provide a central location that
|
This document lists known issues and limitations in MariaDB MaxScale and its
|
||||||
will document known issues and limitations within the MariaDB MaxScale product and
|
plugins. Since limitations are related to specific plugins, this document is
|
||||||
the plugins that form part of that product. Since limitations may related
|
divided into several sections.
|
||||||
to specific plugins or to MariaDB MaxScale as a whole this document is divided
|
|
||||||
into a number of sections, the purpose of which are to isolate the
|
|
||||||
limitations to the components which illustrate them.
|
|
||||||
|
|
||||||
# Limitations in the MariaDB MaxScale core
|
## Protocol limitations
|
||||||
|
|
||||||
This section describes the limitations that are common to all
|
### Limitations with MySQL Protocol support (MySQLClient)
|
||||||
configuration of plugins with MariaDB MaxScale.
|
|
||||||
|
|
||||||
## Crash if one of several listeners for a Service fails as startup
|
Compression is not included in the MySQL server handshake.
|
||||||
|
|
||||||
If a service has multiple listeners and one of those listeners fails
|
## Authenticator limitations
|
||||||
at startup, MariaDB MaxScale will crash.
|
|
||||||
|
|
||||||
A typical reason for a listener to fail is that it has been configured
|
### Limitations in the GSSAPI authenticator
|
||||||
with a non-existing socket path or a port that MariaDB MaxScale is not allowed
|
|
||||||
to use.
|
|
||||||
|
|
||||||
Workaround: Ensure that socket paths and ports are valid.
|
Currently, MariaDB MaxScale only supports GSSAPI authentication when the backend
|
||||||
|
|
||||||
Issues [MXS-710](https://jira.mariadb.org/browse/MXS-710) and
|
|
||||||
[MXS-711](https://jira.mariadb.org/browse/MXS-711) relate to this.
|
|
||||||
|
|
||||||
# Protocol limitations
|
|
||||||
|
|
||||||
## Limitations with MySQL Protocol support (MySQLClient)
|
|
||||||
|
|
||||||
Compression is not included in MySQL server handshake
|
|
||||||
|
|
||||||
# Authenticator limitations
|
|
||||||
|
|
||||||
## Limitations in the GSSAPI authentication
|
|
||||||
|
|
||||||
Currently MaxScale only supports GSSAPI authentication when the backend
|
|
||||||
connections use GSSAPI authentication. Client side GSSAPI authentication with a
|
connections use GSSAPI authentication. Client side GSSAPI authentication with a
|
||||||
different backend authentication module is not supported.
|
different backend authentication module is not supported.
|
||||||
|
|
||||||
# Monitor limitations
|
### Limitations in the MySQL authenticator (MySQLAuth)
|
||||||
|
|
||||||
|
* MariaDB MaxScale supports authentication that uses wildcard matching in
|
||||||
|
hostnames in the `mysql.user` table of the backend database. For IP address
|
||||||
|
entries either `%` or `_`-wildcards are accepted, they should not be mixed in
|
||||||
|
the same entry. For text addresses both wildcards can be mixed.
|
||||||
|
|
||||||
|
* Wildcards in text-form hostnames are not supported.
|
||||||
|
|
||||||
|
* MySQL old style passwords are not supported. MySQL versions 4.1 and newer use a
|
||||||
|
new authentication protocol which does not support pre-4.1 style passwords.
|
||||||
|
|
||||||
|
* When users have different passwords based on the host from which they connect
|
||||||
|
MariaDB MaxScale is unable to determine which password it should use to connect
|
||||||
|
to the backend database. This results in failed connections and unusable
|
||||||
|
usernames in MariaDB MaxScale.
|
||||||
|
|
||||||
|
## Filter limitations
|
||||||
|
|
||||||
|
Filters are not guaranteed to receive complete MySQL packets if they are used
|
||||||
|
with the readconnroute router. This can be fixed by using the readwritesplit
|
||||||
|
router.
|
||||||
|
|
||||||
|
### Database Firewall limitations (dbfwfilter)
|
||||||
|
|
||||||
|
The Database Firewall filter does not support multi-statements. Using them will
|
||||||
|
result in an error being sent to the client.
|
||||||
|
|
||||||
|
## Monitor limitations
|
||||||
|
|
||||||
A server can only be monitored by one monitor. If multiple monitors monitor the
|
A server can only be monitored by one monitor. If multiple monitors monitor the
|
||||||
same server, the state of the server is non-deterministic.
|
same server, the state of the server is non-deterministic.
|
||||||
|
|
||||||
## Limitations with Galera Cluster Monitoring (galeramon)
|
### Limitations with Galera Cluster Monitoring (galeramon)
|
||||||
|
|
||||||
The default master selection is based only on MIN(wsrep_local_index). This
|
The default master selection is based only on MIN(wsrep_local_index). This
|
||||||
can be influenced with the server priority mechanic described in the
|
can be influenced with the server priority mechanic described in the
|
||||||
[Galera Monitor](../Monitors/Galera-Monitor.md) manual.
|
[Galera Monitor](../Monitors/Galera-Monitor.md) manual.
|
||||||
|
|
||||||
# Router limitations
|
## Router limitations
|
||||||
|
|
||||||
## Limitations in the connection router (readconnroute)
|
### Avrorouter limitations (avrorouter)
|
||||||
|
|
||||||
* If Master changes (ie. new Master promotion) during current connection
|
The avrorouter does not support the following data types and conversions:
|
||||||
the router cannot check the change.
|
|
||||||
|
|
||||||
* Sending of binary data with LOAD DATA LOCAL INFILE is not supported
|
* BIT
|
||||||
|
* Fields CAST from integer types to string types
|
||||||
|
|
||||||
## Limitations in the Read/Write Splitter (readwritesplit)
|
The avrorouter does not do any crash recovery. This means that the avro files
|
||||||
|
need to be truncated to valid block lengths before starting the avrorouter.
|
||||||
|
|
||||||
|
### Limitations in the connection router (readconnroute)
|
||||||
|
|
||||||
|
If Master changes (ie. new Master promotion) during current connection, the
|
||||||
|
router cannot check the change.
|
||||||
|
|
||||||
|
Sending of binary data with `LOAD DATA LOCAL INFILE` is not supported.
|
||||||
|
|
||||||
|
### Limitations in the Read/Write Splitter (readwritesplit)
|
||||||
|
|
||||||
Read queries are routed to the master server in the following situations:
|
Read queries are routed to the master server in the following situations:
|
||||||
|
|
||||||
* if they are executed inside an open transaction
|
* query is executed inside an open transaction
|
||||||
|
* query is a prepared statement
|
||||||
|
* statement includes a stored procedure or an UDF call
|
||||||
|
* if there are multiple statements inside one query e.g. `INSERT INTO ... ; SELECT
|
||||||
|
LAST_INSERT_ID();`
|
||||||
|
|
||||||
* in case of prepared statement execution
|
#### Backend write timeout handling
|
||||||
|
|
||||||
* statement includes a stored procedure, or an UDF call
|
The backend connections opened by readwritesplit will not be kept alive if they
|
||||||
|
aren't used. To keep all of the connections alive, a session command must be
|
||||||
* if there are multiple statements inside one query e.g.
|
periodically executed (for example `SET @a = 1;`).
|
||||||
`INSERT INTO ... ; SELECT LAST_INSERT_ID();`
|
|
||||||
|
|
||||||
### Backend write timeout handling
|
|
||||||
|
|
||||||
The backend connections opened by the readwritesplit will not be kept alive if
|
|
||||||
they aren't used. To keep all of the connections alive, a session command must
|
|
||||||
be periodically executed (for example `SET @a = 1;`).
|
|
||||||
|
|
||||||
If the backend server is configured with a low
|
If the backend server is configured with a low
|
||||||
[wait_timeout](https://mariadb.com/kb/en/mariadb/server-system-variables/#wait_timeout),
|
[wait_timeout](https://mariadb.com/kb/en/mariadb/server-system-variables/#wait_timeout),
|
||||||
it is possible that connections get closed during long sessions. It is
|
it is possible that connections get closed during long sessions. It is
|
||||||
recommended to set the wait_timeout to a high value and let MaxScale handle the
|
recommended to set the `wait_timeout` to a high value and let MariaDB MaxScale
|
||||||
client timeouts. This can be achieved by using the
|
handle the client timeouts. This can be achieved by using the
|
||||||
[_connection_timeout_](../Getting-Started/Configuration-Guide.md#connection_timeout)
|
[_connection_timeout_](../Getting-Started/Configuration-Guide.md#connection_timeout)
|
||||||
parameter for the service.
|
parameter for the service.
|
||||||
|
|
||||||
### Limitations in multi-statement handling
|
#### Limitations in multi-statement handling
|
||||||
|
|
||||||
When a multi-statement query is executed through the readwritesplit
|
When a multi-statement query is executed through the readwritesplit router, it
|
||||||
router, it will always be routed to the master. With the default
|
will always be routed to the master. With the default configuration, all queries
|
||||||
configuration, all queries after a multi-statement query will be routed to
|
after a multi-statement query will be routed to the master to prevent possible
|
||||||
the master to prevent possible reads of false data.
|
reads of false data.
|
||||||
|
|
||||||
You can override this behavior with the `strict_multi_stmt=false` router
|
You can override this behavior with the `strict_multi_stmt=false` router option.
|
||||||
option. In this mode, the multi-statement queries will still be routed to
|
In this mode, the multi-statement queries will still be routed to the master but
|
||||||
the master but individual statements are routed normally. If you use
|
individual statements are routed normally. If you use multi-statements and you
|
||||||
multi-statements and you know they don't modify the session state in any
|
know they don't modify the session state in any relevant way, you can disable
|
||||||
relevant way, you can disable this option for better performance.
|
this option for better performance.
|
||||||
|
|
||||||
For more information, read the
|
For more information, read the
|
||||||
[ReadWriteSplit](../Routers/ReadWriteSplit.md) router documentation.
|
[ReadWriteSplit](../Routers/ReadWriteSplit.md) router documentation.
|
||||||
|
|
||||||
### Parsing related limitations
|
#### Parsing limitations
|
||||||
|
|
||||||
Galera Cluster variables, such as @@wsrep_node_name, are not resolved by
|
Galera Cluster variables, such as `@@wsrep_node_name`, are not resolved by the
|
||||||
the embedded MariaDB parser. This usually means that the query will be
|
embedded MariaDB parser. This usually means that the query will be routed to the
|
||||||
routed to the master.
|
master.
|
||||||
|
|
||||||
### Limitations in client session handling
|
#### Limitations in client session handling
|
||||||
|
|
||||||
Some of the queries that client sends are routed to all backends instead
|
Some of the queries that a client sends are routed to all backends instead of
|
||||||
of sending them just to one of server. These queries include `USE <db
|
just to one. These queries include `USE <db name>` and `SET autocommit=0`, among
|
||||||
name>` and `SET autocommit=0` among many others. Readwritesplit sends a
|
many others. Readwritesplit sends a copy of these queries to each backend server
|
||||||
copy of these queries to each backend server and forwards the master's
|
and forwards the master's reply to the client. Below is a list of MySQL commands
|
||||||
reply to the client. Below is a list of MySQL commands which are
|
which are classified as session commands.
|
||||||
classified as session commands :
|
|
||||||
|
|
||||||
```
|
```
|
||||||
COM_INIT_DB (USE <db name> creates this)
|
COM_INIT_DB (USE <db name> creates this)
|
||||||
|
|
||||||
COM_CHANGE_USER
|
COM_CHANGE_USER
|
||||||
|
|
||||||
COM_STMT_CLOSE
|
COM_STMT_CLOSE
|
||||||
|
|
||||||
COM_STMT_SEND_LONG_DATA
|
COM_STMT_SEND_LONG_DATA
|
||||||
|
|
||||||
COM_STMT_RESET
|
COM_STMT_RESET
|
||||||
|
|
||||||
COM_STMT_PREPARE
|
COM_STMT_PREPARE
|
||||||
|
|
||||||
COM_QUIT (no response, session is closed)
|
COM_QUIT (no response, session is closed)
|
||||||
|
|
||||||
COM_REFRESH
|
COM_REFRESH
|
||||||
|
|
||||||
COM_DEBUG
|
COM_DEBUG
|
||||||
|
|
||||||
COM_PING
|
COM_PING
|
||||||
|
|
||||||
SQLCOM_CHANGE_DB (USE ... statements)
|
SQLCOM_CHANGE_DB (USE ... statements)
|
||||||
|
|
||||||
SQLCOM_DEALLOCATE_PREPARE
|
SQLCOM_DEALLOCATE_PREPARE
|
||||||
|
|
||||||
SQLCOM_PREPARE
|
SQLCOM_PREPARE
|
||||||
|
|
||||||
SQLCOM_SET_OPTION
|
SQLCOM_SET_OPTION
|
||||||
|
|
||||||
SELECT ..INTO variable|OUTFILE|DUMPFILE
|
SELECT ..INTO variable|OUTFILE|DUMPFILE
|
||||||
|
|
||||||
SET autocommit=1|0
|
SET autocommit=1|0
|
||||||
```
|
```
|
||||||
|
|
||||||
There is a possibility for misbehavior; if `USE mytable` was executed in
|
There is a possibility for misbehavior. If `USE mytable` is executed in one of
|
||||||
one of the slaves and it failed, it may be due to replication lag rather
|
the slaves and fails, it may be due to replication lag rather than the
|
||||||
than the fact it didn’t exist. Thus the same command may end up with
|
database not existing. Thus, the same command may produce different result in
|
||||||
different result among backend servers. The slaves which fail to execute a
|
different backend servers. The slaves which fail to execute a session command
|
||||||
session command will be dropped from the active list of slaves for this
|
will be dropped from the active list of slaves for this session to guarantee a
|
||||||
session to guarantee a consistent session state across all the servers
|
consistent session state across all the servers used by the session.
|
||||||
that are in use by the session.
|
|
||||||
|
|
||||||
The above-mentioned behavior can be partially controller with the
|
|
||||||
`use_sql_variables_in` configuration parameter.
|
|
||||||
|
|
||||||
|
The above-mentioned behavior can be partially controlled with the configuration
|
||||||
|
parameter `use_sql_variables_in`:
|
||||||
```
|
```
|
||||||
use_sql_variables_in=[master|all] (default: all)
|
use_sql_variables_in=[master|all] (default: all)
|
||||||
```
|
```
|
||||||
|
|
||||||
Server-side session variables are called as SQL variables. If "master" is
|
Server-side session variables are handled similar to SQL variables. If "master"
|
||||||
set, SQL variables are read and written in master only. Autocommit values
|
is set, SQL variables are read and written in master only. Autocommit values and
|
||||||
and prepared statements are routed to all nodes always.
|
prepared statements are routed to all nodes always.
|
||||||
|
|
||||||
**WARNING**
|
**WARNING**
|
||||||
|
|
||||||
If a SELECT query modifies a user variable when the `use_sql_variables_in`
|
If a SELECT query modifies a user variable when the `use_sql_variables_in`
|
||||||
parameter is set to `all`, it will not be routed and the client will receive
|
parameter is set to `all`, it will not be routed and the client will receive an
|
||||||
an error. A log message is written into the log further explaining the reason
|
error. A log message is written into the log further explaining the reason for
|
||||||
for the error. Here is an example use of a SELECT query which modifies a user
|
the error. Here is an example use of a SELECT query which modifies a user
|
||||||
variable and how MariaDB MaxScale responds to it.
|
variable and how MariaDB MaxScale responds to it.
|
||||||
|
|
||||||
```
|
```
|
||||||
@ -187,105 +182,54 @@ MySQL [(none)]> SELECT @id := @id + 1 FROM test.t1;
|
|||||||
ERROR 1064 (42000): Routing query to backend failed. See the error log for further details.
|
ERROR 1064 (42000): Routing query to backend failed. See the error log for further details.
|
||||||
```
|
```
|
||||||
|
|
||||||
You allow user variable modification in SELECT queries by setting the
|
Allow user variable modification in SELECT queries by setting the value of
|
||||||
value of `use_sql_variables_in` to `master`. This will route all queries
|
`use_sql_variables_in` to `master`. This will route all queries that use user
|
||||||
that use user variables to the master.
|
variables to the master.
|
||||||
|
|
||||||
#### Examples of session command limitations
|
#### Examples of session command limitations
|
||||||
|
|
||||||
If a new database "db" was created and client executes “USE db” and it is
|
In a situation where a new database `db` is created, immediately after which a client executes `USE db`, it is possible that the command is routed
|
||||||
routed to a slave before the CREATE DATABASE clause is replicated to all
|
to a slave before the `CREATE DATABASE` clause is replicated to all slaves. In this case a query may be executed in the wrong database. Similarly, if any response
|
||||||
slaves, there is a risk of executing a query in the wrong database. Similarly, if
|
that ReadWriteSplit sends back to the client differ from that of the master,
|
||||||
any response that RWSplit sends back to the client differ from that of the
|
there is a risk for misbehavior. To prevent this, any failures in session
|
||||||
master, there is a risk for misbehavior. To prevent this, any failures in
|
command execution are treated as fatal errors and all connections by the session
|
||||||
session command execution are treated as fatal errors and all connections
|
to that particular slave server will be closed. In addition, the server will not
|
||||||
by the session to that particular slave server will be closed. In
|
used again for routing for the duration of the session.
|
||||||
addition, the server will not used again for routing for the duration of
|
|
||||||
the session.
|
|
||||||
|
|
||||||
The most likely reasons are related to replication lag but it could be
|
The most likely reasons are related to replication lag but it could be possible
|
||||||
possible that a slave fails to execute something because of some
|
that a slave fails to execute something because of some non-fatal, temporary
|
||||||
non-fatal, temporary failure, while the execution of the same command
|
failure, while the execution of the same command succeeds in other backends.
|
||||||
succeeds in other backends.
|
|
||||||
|
|
||||||
## Schemarouter limitations (schemarouter)
|
The preparation of a prepared statement is routed to all servers. The execution
|
||||||
|
of a prepared statement is routed to the first available server or to the server
|
||||||
|
pointed by a routing hint attached to the query.
|
||||||
|
|
||||||
The schemarouter router currently has some limitations due to the nature of
|
### Schemarouter limitations (schemarouter)
|
||||||
the sharding implementation and the way the session variables are detected
|
|
||||||
and routed. Here is a list of the current limitations.
|
|
||||||
|
|
||||||
* Cross-database queries (e.g.
|
The schemarouter currently has some limitations due to the nature of the
|
||||||
`SELECT column FROM database1.table UNION select column FROM database2.table`)
|
sharding implementation and the way the session variables are detected and
|
||||||
are not supported and are routed either to the first explicit database
|
routed. Here is a list of the current limitations:
|
||||||
in the query, the current database in use or to the first available
|
|
||||||
database, if none of the previous conditions are met.
|
* Cross-database queries (e.g. `SELECT column FROM database1.table UNION select
|
||||||
|
column FROM database2.table`) are not supported and are routed either to the
|
||||||
|
first explicit database in the query, the current database in use or to the
|
||||||
|
first available database, depending on which succeeds.
|
||||||
|
|
||||||
* Without a default database, queries without explicit databases that do not
|
* Without a default database, queries without explicit databases that do not
|
||||||
modify the session state will be routed the first available server. This
|
modify the session state will be routed to the first available server. This
|
||||||
means that, for example when creating a new database, queries should
|
means that, for example when creating a new database, queries should be done
|
||||||
be done directly on the node or the router should be equipped with
|
directly on the node or the router should be equipped with the hint filter and a
|
||||||
the hint filter and a routing hint should be used. Queries that
|
routing hint should be used. Queries that modify the session state (e.g. `SET
|
||||||
modify the session state e.g. `SET autocommit=1` will be routed
|
autocommit=1`) will be routed to all servers regardless of the default database.
|
||||||
to all servers regardless of the default database.
|
|
||||||
|
|
||||||
* SELECT queries that modify session variables are not currently supported
|
* SELECT queries that modify session variables are not currently supported because
|
||||||
because uniform results can not be guaranteed. If such a query is
|
uniform results can not be guaranteed. If such a query is executed, the behavior
|
||||||
executed, the behavior of the router is undefined. To work around this
|
of the router is undefined. To work around this limitation, the query must be
|
||||||
limitation the query must be executed in separate parts.
|
executed in separate parts.
|
||||||
|
|
||||||
* If a query targets a database the schemarouter hasn't mapped to a server
|
* If a query targets a database the schemarouter hasn't mapped to a server, the
|
||||||
the query will be routed to the first available server. This possibly
|
query will be routed to the first available server. This possibly returns an
|
||||||
returns an error about database rights instead of a missing database.
|
error about database rights instead of a missing database.
|
||||||
|
|
||||||
* The preparation of a prepared statement is routed to all servers. The
|
* As text protocol prepared statements are relatively rare, prepared statements
|
||||||
execution of a prepared statement is routed to the first available server or
|
are not supported in schemarouter.
|
||||||
to the server pointed by a routing hint attached to the query. As text
|
|
||||||
protocol prepared statements are relatively rare, prepared statements can't be
|
|
||||||
considered as supported in schemarouter
|
|
||||||
|
|
||||||
## Avrorouter limitations (avrorouter)
|
|
||||||
|
|
||||||
The avrorouter does not support the following data types and conversions.
|
|
||||||
|
|
||||||
* BIT
|
|
||||||
* Fields CAST from integer types to string types
|
|
||||||
|
|
||||||
The avrorouter does not do any crash recovery. This means that the avro files
|
|
||||||
need to be truncated to valid block lengths before starting the avrorouter.
|
|
||||||
|
|
||||||
# Authenticator limitations
|
|
||||||
|
|
||||||
## MySQL Authentication Related Limitations (MySQLAuth)
|
|
||||||
|
|
||||||
* MariaDB MaxScale supports authentication that uses wildcard matching in
|
|
||||||
hostnames in the mysql.user-table of the backend database. For IP-address
|
|
||||||
entries either '%' or '_'-wildcards are accepted, they should not be mixed
|
|
||||||
in the same entry. For text addresses both wildcards can be mixed.
|
|
||||||
|
|
||||||
* When wildcards are used with text-form hostnames, MariaDB MaxScale uses
|
|
||||||
the `getnameinfo()`-function (from glibc) to perform the reverse DNS lookup.
|
|
||||||
This is a slow operation, which will stall the calling thread for an
|
|
||||||
unspecified time. The lookup is only performed if the mysql.user-table
|
|
||||||
contains a text hostname with wilcards for the client. Also, do note that
|
|
||||||
the IP and hostname seen by the backend will be those of the machine running
|
|
||||||
MariaDB MaxScale, while the username and password will be those of the
|
|
||||||
original client.
|
|
||||||
|
|
||||||
* MySQL old style passwords are not supported. MySQL versions 4.1 and newer use
|
|
||||||
a new authentication protocol which does not support pre-4.1 style passwords.
|
|
||||||
|
|
||||||
* When users have different passwords based on the host from which they connect
|
|
||||||
MariaDB MaxScale is unable to determine which password it should use to connect to the
|
|
||||||
backend database. This results in failed connections and unusable usernames
|
|
||||||
in MariaDB MaxScale.
|
|
||||||
|
|
||||||
# Filter limitations
|
|
||||||
|
|
||||||
Filters are not guaranteed to receive complete MySQL packets if they are used
|
|
||||||
with the readconnroute router. This can be fixed by using the readwritesplit
|
|
||||||
router.
|
|
||||||
|
|
||||||
## Database Firewall limitations (dbfwfilter)
|
|
||||||
|
|
||||||
The Database Firewall filter does not support multi-statements. Using them
|
|
||||||
will result in an error being sent to the client.
|
|
||||||
|
Reference in New Issue
Block a user