MaxscaleでルーティングするSQLクエリの書き換えを行う

Maxscaleについて調べていたところ、中継するSQLクエリを正規表現で書き換えてDB側に伝える機能(Regex Filter)があるようだったので、少し触ってみる事にした。
※Maxscale 1.3.0以降で利用可能になったらしい。

書き換えルールについては、Maxscaleの設定ファイルに事前に書いておく必要があるので、以前書いたこちらの記事の設定を元にして記述していく。

●/etc/maxscale.cnf(Before)

[maxscale]
threads=4 # 同時処理数
log_messages=1
log_trace=1
logdir=/var/log/maxscale

[Splitter Service]
type=service
router=readwritesplit
servers=BS-PUB-GALERA-01,BS-PUB-GALERA-02,BS-PUB-GALERA-03
max_slave_connections=100%
user=maxscale
passwd=パスワード
localhost_match_wildcard_host=true
enable_root_user=true

[Splitter Listener]
type=listener
service=Splitter Service
protocol=MySQLClient
port=3306

[Galera Monitor]
type=monitor
module=galeramon
servers=BS-PUB-GALERA-01,BS-PUB-GALERA-02,BS-PUB-GALERA-03
user=maxscale
passwd=パスワード
monitor_interval=3000
use_priority=true

[CLI]
type=service
router=cli

[CLI Listener]
type=listener
service=CLI
protocol=maxscaled
address=127.0.0.1
port=6603

[BS-PUB-GALERA-01]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=1

[BS-PUB-GALERA-02]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=2

[BS-PUB-GALERA-03]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=3

●/etc/maxscale.cnf(After)

[maxscale]
threads=4 # 同時処理数
log_messages=1
log_trace=1
logdir=/var/log/maxscale

[regex]
type=filter
module=regexfilter
match=tset # "tset"という文字列があった場合
replace=test "test"という文字列に直す

[Splitter Service]
type=service
router=readwritesplit
servers=BS-PUB-GALERA-01,BS-PUB-GALERA-02,BS-PUB-GALERA-03
max_slave_connections=100%
user=maxscale
passwd=パスワード
localhost_match_wildcard_host=true
enable_root_user=true
filters=regex

[Splitter Listener]
type=listener
service=Splitter Service
protocol=MySQLClient
port=3306

[Galera Monitor]
type=monitor
module=galeramon
servers=BS-PUB-GALERA-01,BS-PUB-GALERA-02,BS-PUB-GALERA-03
user=maxscale
passwd=パスワード
monitor_interval=3000
use_priority=true

[CLI]
type=service
router=cli

[CLI Listener]
type=listener
service=CLI
protocol=maxscaled
address=127.0.0.1
port=6603

[BS-PUB-GALERA-01]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=1

[BS-PUB-GALERA-02]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=2

[BS-PUB-GALERA-03]
type=server
address=IPアドレス
port=3306
protocol=MySQLBackend
priority=3

とりあえず、この例では「tset」という文字列があった場合、「test」として置換してSQLを流すようにしている。
さて、それでは実際にSQLを流してみよう。

[root@BS-PUB-GFRONT-01 ~]# mysql -u test test -ppassword -h 127.0.0.1 -e 'SELECT * FROM test'
+------+------+
| id   | name |
+------+------+
|    1 | test |
|    2 | test |
|    3 | test |
+------+------+
[root@BS-PUB-GFRONT-01 ~]# mysql -u test test -ppassword -h 127.0.0.1 -e 'SELECT * FROM tset'
ERROR 1146 (42S02) at line 1: Table 'test.tset' doesn't exist
[root@BS-PUB-GFRONT-01 ~]#
[root@BS-PUB-GFRONT-01 ~]# # ファイルを編集
[root@BS-PUB-GFRONT-01 ~]# vim /etc/maxscale.cnf
[root@BS-PUB-GFRONT-01 ~]# service maxscale restart
Restarting maxscale (via systemctl):                       [  OK  ]
[root@BS-PUB-GFRONT-01 ~]# mysql -u test test -ppassword -h 127.0.0.1 -e 'SELECT * FROM test'
+------+------+
| id   | name |
+------+------+
|    1 | test |
|    2 | test |
|    3 | test |
+------+------+
[root@BS-PUB-GFRONT-01 ~]# mysql -u test test -ppassword -h 127.0.0.1 -e 'SELECT * FROM tset'
+------+------+
| id   | name |
+------+------+
|    1 | test |
|    2 | test |
|    3 | test |
+------+------+
[root@BS-PUB-GFRONT-01 ~]# mysql -u test test -ppassword -h 127.0.0.1 -e 'INSERT INTO test(ID,NAME) VALUES(4,"tset");'
[root@BS-PUB-GFRONT-01 ~]# mysql -u test test -ppassword -h 127.0.0.1 -e 'SELECT * FROM tset'
+------+------+
| id   | name |
+------+------+
|    1 | test |
|    2 | test |
|    3 | test |
|    4 | test |
+------+------+

ううむ、確かにSQLが置換されている事がわかる。
ある程度オーバーヘッドがありそうな気もするけど、そこまで大きくはなさそうだ。

オプションを見ていると、特定のホストやユーザーの場合だけ置換をさせるように指定することも出来そうなので、使いドコロによっては面白そうだ。