mysql/postgresqlでユーザごとの同時/最大接続数制限

共有サーバでは真面目に考えたほうが良くね?という話になったので調べた。

mysql

各バージョンのmysql見てると、ユーザ個別の値を設定できるのは5.0以降ぽい。

全ユーザ共通のグローバルな設定
  • /etc/my.cnf
max_user_connections = 10

rootユーザもこの制限にひっかかる。

ユーザごとの設定

grant文でmax_users_connectionsを指定。

新規にユーザ作成

mysql> GRANT ALL ON customer.* TO 'francis'@'localhost'
   ->     IDENTIFIED BY 'frank'
   ->     WITH MAX_QUERIES_PER_HOUR 20
   ->          MAX_UPDATES_PER_HOUR 10
   ->          MAX_CONNECTIONS_PER_HOUR 5
   ->          MAX_USER_CONNECTIONS 2;
  • MAX_QUERIES_PER_HOUR
    • 時間単位の全クエリ数: 1ユーザが実行できるクエリ
  • MAX_UPDATES_PER_HOUR
    • 時間単位の全更新数: テーブルまたはデータベースを変更するクエリ
  • MAX_CONNECTIONS_PER_HOUR
    • 時間単位の接続数: 1時間で新しく開ける接続
  • MAX_USER_CONNECTIONS
    • 同時接続数: これが使えるのはver 5.0以上?

それぞれmysql.userテーブルのmax_questions、max_updates、max_connections、max_user_connectionsに保存されてる。

変更
GRANT USAGEで。

mysql> GRANT USAGE ON *.* TO 'francis'@'localhost'
    ->     WITH MAX_QUERIES_PER_HOUR 100;

もしくはmysql.userの該当のカラムを直接updateして、flush privilegesするか。

postgresql

最近のversionはユーザ作成時のcreateuserのオプションで指定できる。8.0では出来なかったけど、8.2では出来た。8.1は調べてないので不明。

ユーザ作成
$ createuser user -c 20
確認
psql> \du;
変更

それらしい管理コマンドが見つからなかったので、pg_rolesのrolconnlimitを更新しちゃえ。と思ったらviewだから出来なかった。pg_authidが実テーブルなのでこっちを更新してみた。
他にまともなやり方がありそう。

psql> update pg_roles set rolconnlimit = 2 where rolname = 'testuser';
ERROR:  cannot update a view
HINT:  You need an unconditional ON UPDATE DO INSTEAD rule.
psql> \d pg_roles;
### viewの実態がpg_authid.rolconnlimitだと確認
psql> update pg_authid set rolconnlimit = 2 where rolname = 'testuser';