この記事は MySQL - Qiita Advent Calendar 2025 の21日目の記事です。
昨日は @meijik さんの MedianやPercentile_%が欲しい連合会(Firebird/MySQL) でした。
ふと MySQL RouterのRead-Write Splittingの設定 を見ていたら、前提条件として connection_sharing: must be set to 1. と書いてあって、俺が使っていた8.0の頃のRouterと比べて増えたなあと思って調べてみた。
MySQL :: MySQL Router 8.4 :: 3.4 Connection Sharing and Reuse
MySQL Router enables server connections to be pooled and shared
ってことなので、MySQLとMySQL Routerの間のコネクションを、MySQL Routerとアプリケーションの間で使い回させられるような感じになるはず。
折角なので(?) 最新のMySQL Router(Innovation Release)にしてみる(8.4でもできたんだけどなんか勘違いして最新版を入れてしまったのでそれでやる)
$ sudo dnf install mysql-router --disablerepo="*" --enablerepo="mysql-tools-innovation*"
..
=======================================================================================================================================
Package Architecture Version Repository Size
=======================================================================================================================================
Upgrading:
mysql-router-community x86_64 9.5.0-1.el8 mysql-tools-innovation-community 61 M
..
mysqlrouter.conf を昔取った杵柄でテキトーにいじってみる。
$ sudo vim /etc/mysqlrouter/mysqlrouter.conf
..
[connection_pool]
idle_timeout= 3600
max_idle_server_connections= 10
[routing:test_connection_sharing]
bind_address= 127.0.0.1
bind_port= 49825
destinations= 127.0.0.1:64080
routing_strategy= first-available
connection_sharing= 1
client_ssl_mode = disabled
$ sudo systemctl start mysqlrouter
$ sudo less /var/log/mysqlrouter/mysqlrouter.log
2025-12-21 13:25:24 main SYSTEM [7f938e74b580] Starting 'MySQL Router', version: 9.5.0 (MySQL Community - GPL)
2025-12-21 13:25:24 io INFO [7f938e74b580] starting 8 io-threads, using backend 'linux_epoll'
2025-12-21 13:25:24 keepalive INFO [7f93817fa700] keepalive started with interval 60
2025-12-21 13:25:24 keepalive INFO [7f93817fa700] keepalive
2025-12-21 13:25:24 routing INFO [7f9380ff9700] [routing:test_connection_sharing] started: routing strategy = first-available
2025-12-21 13:25:24 routing INFO [7f9380ff9700] Start accepting connections for routing routing:test_connection_sharing listening on '127.0.0.1:49825'
max_idle_server_connections と idle_timeout は [connection_pool] セクションなので [routing:*] セクションに書いても読んでくれない。
ともあれこれで
$ mysql -h127.0.0.1 -P49825 -uyoku0825 -sse "SELECT CONNECTION_ID()"
35467
$ mysql -h127.0.0.1 -P49825 -uyoku0825 -sse "SELECT CONNECTION_ID()"
35467
$ mysql -h127.0.0.1 -P49825 -uyoku0825 -sse "SELECT CONNECTION_ID()"
35467>
$ mysql -h127.0.0.1 -P49825 -uyoku0825 -sse "SELECT CONNECTION_ID()"
35467
うん、クライアントを切断しても CONNECTION_ID() の結果が変わらないのでプーリング(シェアリング)できてるっぽい。
で、ここからが本題。
3.4 Connection Sharing and Reuse を読むと、
Unsupported SQL Features
The following statements and functions are not supported when connection sharing is active, except inside a transaction.
..
- LAST_INSERT_ID()
と、コネクションシェアリングでは使えないらしい関数が示されている。
$ mysql -h127.0.0.1 -P49825 -uyoku0825
mysql> SELECT LAST_INSERT_ID();
ERROR 3566 (HY000): Access to native function is rejected when connection sharing is enabled
確かにエラーになる。
$ ./runtime_output_directory/perror 3566
MySQL error code MY-003566 (ER_NO_ACCESS_TO_NATIVE_FCT): Access to native function '%.64s' is rejected.
MySQLサーバー側のperrorでもちゃんと返ってきたけれど、なんかよく見るとエラーメッセージがしっくり来ていない ( %.64s と is rejected と shwn connection sharing is enabled が綺麗に対応していない )
あと、 performance_schema.events_errors_summary_global_by_error に記録されてないのでこれはMySQLサーバから来てるんじゃなくてMySQL Routerがエラーパケット作ってるっぽい。
mysql80 35513> SELECT * FROM events_errors_summary_global_by_error WHERE error_number = 3566;
+--------------+----------------------------+-----------+------------------+-------------------+------------+-----------+
| ERROR_NUMBER | ERROR_NAME | SQL_STATE | SUM_ERROR_RAISED | SUM_ERROR_HANDLED | FIRST_SEEN | LAST_SEEN |
+--------------+----------------------------+-----------+------------------+-------------------+------------+-----------+
| 3566 | ER_NO_ACCESS_TO_NATIVE_FCT | HY000 | 0 | 0 | NULL | NULL |
+--------------+----------------------------+-----------+------------------+-------------------+------------+-----------+
1 row in set (0.00 sec)
さて。
こんなこと ( = MySQL Routerが中を通るSQLに応じて勝手にエラーパケットを返す ) ができるということは、つまりMySQL Routerは 流れてくるSQLをパースしているわけで 、そうすると Limitations に書かれている Connection sharing is not supported in PASSTHROUGH mode or if server-ssl-mode=AS_CLIENT and client-ssl-mode=PREFERRED. も、mysqlrouterが終端しない形でSSL/TLSを使ってしまうと流れてくるSQLが読めなくなるからなわけであって、てことはコネクションシェアリングを前提にしているRead-Write SplittingというのはMySQL RouterがSQLをパースしてソースに投げるかレプリカに投げるのかを打ち分けているということで…。
MySQL Proxyの rw-splitting.lua とか思い出して見てみたら、弾いてる関数とかが似ていて、繰り返す歴史を感じたという感じでした。
明日は @tmtms さんです!
0 件のコメント :
コメントを投稿