MySQLを運用していて、too many connections
というエラーに遭遇したことがある方は多いかもしれません。このエラーに出くわした際は、max_connectionsの設定を変更したり、詰まってしまったSQLを調査してKILLすることで対処する場合が多いかと思います。
MySQL 8.0.14から新たに追加されたサーバーシステム変数admin_address, admin_portというものがあります。これは管理者用のネットワークインターフェイスになります。今回はこのadmin_address, admin_portについて見ていきます。
なお、今回検証に利用しているMySQLのバージョンは8.0.28になります。また、今回は検証のためにroot@127.0.0.1
というアカウントを作成してroot@localhost
と同等の権限を与えて利用しています。
admin_address, admin_port
admin_address, admin_portはバージョン8.0.14で追加されたサーバーシステム変数で、管理者用の設定になります。これを設定することで、max_connectionsの数だけ接続されて、これ以上接続できないようなMySQLに対しても、admin_address、admin_portを介して接続することが可能になります。
つまり、Too many connections
が出た場合等に監視しながらSHOW PROCESSLISTやKILLコマンドを実行できたり、複数人で障害対応を実施する場合に発揮するオプションということです。デフォルトではadmin_portは33062が設定されていますが、admin_addressは設定されていないため、利用する場合は、接続するadmin_address(host)を設定する必要があります。
また、このオプションを有効にするには再起動が必要であるため、設定する場合はメンテナンスの時や新規MySQLを構築する時に設定するのが良いかもしれません。
実際にadmin_address, admin_portを設定して、max_connections=1の状態にしてToo many connectionsを発生させて検証してみます。ポート3306はエラーとなりましたが、ポート33062は接続することができました。
$ mysql -uroot -h127.0.0.1 -P3306 -p
Enter password:
ERROR 1040 (HY000): Too many connections
$ mysql -uroot -h127.0.0.1 -P33062 -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 16
Server version: 8.0.28 MySQL Community Server - GPL
> show variables like 'admin_%';
+------------------------+-----------------+
| Variable_name | Value |
+------------------------+-----------------+
| admin_address | 127.0.0.1 |
| admin_port | 33062 |
| admin_ssl_ca | |
〈省略〉
利用したいhost、portを設定することで接続可能になりますが、このポートの利用にはSERVICE_CONNECTION_ADMIN権限を付与されたユーザーにのみ許可されているため、通常ユーザーで接続しようとした場合はAccess deniedで接続拒否されます。
mysql -ufukamachi -h127.0.0.1 -P33062 -p
Enter password:
ERROR 1227 (42000): Access denied; you need (at least one of) the SERVICE_CONNECTION_ADMIN privilege(s) for this operation
バージョン8.0.21ではadmin_sslやadmin_ssl_capath, admin_ssl_certなども追加されており、暗号化された接続に対する管理者用のネットワークインターフェイスの設定も可能となっております。
設定
デフォルトでは33062のポートが設定されますが、他のポート番号を設定する場合は少し注意が必要です。他のアプリケーション等で利用しているポートはもちろん利用できません。
また、33062の近辺のポートして33060はXプロトコルのデフォルトポート、33061はグループレプリケーションの推奨ポートとなっているので注意してください。
mysqlxとadmin_portがかぶった設定をした場合
2022-01-25T02:34:31.788017+09:00 0 [ERROR] [MY-010262] [Server] Can't start server: Bind on TCP/IP port: Address already in use
2022-01-25T02:34:31.792247+09:00 0 [ERROR] [MY-010257] [Server] Do you already have another mysqld server running on port: 33060 ?
2022-01-25T02:34:31.800548+09:00 0 [ERROR] [MY-010119] [Server] Aborting
その他MySQLで利用されるポート一覧については、MySQL Port Reference :: 3 MySQL Port Reference Tables を参照ください。
admin_addressは複数設定することはできない
MySQL 8.0.13以降ではbind_addressはカンマ区切りで複数設定することができるようになっていますが、admin_addressは複数設定はできず、単一の値のみ設定することになります。
create_admin_listener_thread
create_admin_listener_threadというオプションもバージョン8.0.14で追加されました。これは、管理者用のリスナースレッドを作成するかどうかを設定しますす。ONにすることで、短時間に接続が集中してポート3306用のリスナースレッドが詰まっても、接続を受けられるようになります。デフォルトではOFFとなっています。
Percona Server for MySQLのextra_port
ここまでの話を聞いた人の中には、Percona Server for MySQLのextra_port の設定を思い出した方もいるかも知れません。以前のPercona Serverでは、extra_portという設定をすることでMySQLがLISTENするポートを追加することができました。しかし、Percona Serverではバージョン8.0.14でこのオプションは廃止され、admin_portを利用することになっています。
まとめ
今回はadmin_addressとadmin_portの設定について紹介しました。これらの設定は、いざというときの接続口として準備しておくと良いかもしれません。ただし、実際に障害が起きたときに使えるように設定した場合は、事前に接続して利用できることを確認しておきましょう。