仕事でMaxscaleを利用しているのだが、Limitation and Knownを読んでなかったので読むことにした。
そんなに文章量も無いので、以下重要そうなトコだけ抜粋して記述していく。
MySQL Serverのハンドシェイクに圧縮は含まれない
Compression is not included in MySQL server handshake
Galera Cluster Monitorではデフォルトのマスターは「wsrep_local_index」が最も低いノードが対象となる
The default master selection is based only on MIN(wsrep_local_index). This
can be influenced with the server priority mechanic described in the
Galera Monitor manual.
これはMaxscale+ Galera Clusterの組み合わせでいじってるとスグ気がつく部分だと思う。
マスターを優先順位を付けて指定したい場合は、こちらの内容を元に対応すると良いだろう。
Connection Router では接続中のマスターの変化を認識出来ない
If Master changes (ie. new Master promotion) during current connection the router cannot check the change.
つまり、Read Write Splittingじゃないと、マスターの切り替えには対応出来ないということなのだろうか。
Connection Router ではLONGBLOBデータの送信はサポートされない
Sending of LONGBLOB data is not supported
Read Write Splittingでは、特定条件のSQLは全てマスターノードに振り分けられる
Read queries are routed to the master server in the following situations:
- if they are executed inside an open transaction
- in case of prepared statement execution
- 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();
これについては、Galera Cluster + Maxscaleを利用している人は要注意だ。
自分も会社で利用していた際に引っかかった所なのだけど、以下の場合だとSQLの内容がSELECTだろうがINSERTだろうが全てマスターノードに寄ってしまうので、処理が分散されない事になる。
- オープントランザクションで処理を実行する場合
- Prepared Statement(プリペアドステートメント)を利用する場合
- ストアド・プロシージャで値の代入やUDFを呼び出している場合
- 一つのクエリの中で複数のSQL文がある場合(;で区切っていくつもSQL文を実行している場合)
Go言語でいうと、例えばGenmaiとか使ってると、全てのSQLがマスターノードで処理されてしまうということになる。
マルチマスタなのに負荷分散されないという、なかなか意味のないクラスタとなるので注意が必要。
一つのクエリ内で複数のSQLを処理している場合
When a multi-statement query is executed through the readwritesplit router, it will always be routed to the master. With the default configuration, all queries after a multi-statement query will be routed to the master to prevent possible reads of false data.
You can override this behavior with the strict_multi_stmt=false router option. In this mode, the multi-statement queries will still be routed to the master but individual statements are routed normally. If you use multi-statements and you know they don't modify the session state in any relevant way, you can disable this option for better performance.
For more information, read the ReadWriteSplit router documentation.
一つのクエリ内で複数のSQLを処理している場合、その処理がreadwritesplitrouterを経由している場合、全てマスターノードに振り分けられる事になる。
これを解消するには、readwritesplitrouterの設定にオプションとして「strict_multi_stmt=false」を設定する必要があるようだ。この設定を追加することで、複数処理を記述したSQLはマスターにも割り振られるものの、スレーブノード側にもちゃんと割り振ってくれるようになるらしい。
クライアントセッションの処理における制限
Some of the queries that client sends are routed to all backends instead of sending them just to one of server.
These queries include USEand SET autocommit=0 among many others. Readwritesplit sends a copy of these queries to each backend server and forwards the master's reply to the client.
一部のクエリ(USE <DB名>など)については、1サーバではなくバックグラウンドの全てのサーバにルーティングされるようだ。
Server-side session variables are called as SQL variables. If "master" is set, SQL variables are read and written in master only. Autocommit values and prepared statements are routed to all nodes always.
サーバ側のセッション変数はSQL変数として読み込まれ、もしバックグラウンド側にマスターがいるようであれば、SQL変数はマスターでのみ読み書きされる(マスターだけで処理される)。オートコミット値及びプリペアステートメントについては、全てのノードにルーティングされる。
つまり、プリペアドステートメントを使っている場合、クエリ自体は全てのノードに送られるが、実際の処理はマスターでのみ行われる(処理が偏る)ということになる。
If a SELECT query modifies a user variable when the se_sql_variables_in parameter is set to all, it will not be routed and the client will receive an error.
A log message is written into the log further explaining the reason for the error.
「use_sql_variables_in = all」が設定されている場合、SELECTクエリがユーザー変数を変更した場合、ルーティングされずエラーが返ってくるとのこと。
これを解消するには、「use_sql_variables_in = master」を設定するとのこと。
Maxscaleの認証関係の制限
- MaxScale can not manage authentication that uses wildcard matching in hostnames in the mysql.user table of the backend database. The only wildcards that can be used are in IP address entries.
- 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 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 MaxScale.
- MaxScaleでは、MySQLでホスト名にワイルドカードマッチングを使用して認証を管理することはできない。
(IPアドレスでのワイルドカードは利用可能) - MySQLバージョン4.1以前のパスワードは対応していない。
- 接続しにいくノードのユーザ名とパスワードは、全て同一である必要がある(ノードごとに異なるパスワードは設定出来ない)。
Schemarouterの制限について
The schemarouter router currently has some limitations due to the nature of 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.
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, if none of the previous conditions are met.- Without a default database, queries without explicit databases that do not modify the session state will be routed the first available server. This means that, for example when creating a new database, queries should be done directly on the node or the router should be equipped with the hint filter and a routing hint should be used. Queries that modify the session state e.g.
SET autocommit=1
will be routed to all servers regardless of the default database.- SELECT queries that modify session variables are not currently supported because uniform results can not be guaranteed. If such a query is executed, the behavior of the router is undefined. To work around this limitation the query must be executed in separate parts.
- If a query targets a database the schemarouter hasn't mapped to a server the query will be routed to the first available server. This possibly returns an error about database rights instead of a missing database.
Schemarouterでは、以下のような制限があるらしい。
- クロスデータベースクエリはサポートしていない。
2つ目以降のデータベース指定は全て最初に指定したデータベースにルーティングされる。 - デフォルトデータベースがないと、明示的なデータベース指定の無い、セッション状態を変更しないクエリは、最初に使用可能なサーバへルーティングされる。
- 均一な結果を保証できないため、セッション変数を変更するようなSELECTクエリは現在サポートされていない。
- schemarouterは、クエリがデータベースをターゲットにしている場合はクエリが最初に使用可能なサーバーにマッピングされていません。
大体合ってるだろうか。
基本、Maxscaleを利用している場合の大半はReadWriteSplittingを用いる事が多いだろうと思う(個人的な感想)ので、その辺りの制限についてはちゃんと読んでおいた方が良さそうだ。