+N Connection for root
これまで何度か、、「max_connectionsに達してしまったら、rootユーザ(DBAによる手動)によるログインもできないんでしょうか?」という質問を受け、その度に「mysqlでは無理っす」と答えていたのだけれども、、、、、、← 間違い
これを解消するパッチが登場し、MySQL本家がそれを取り込んだようです。
reserved_connectionsというシステム変数を新しく追加し、一般ユーザは"max_connections"まで、rootユーザは"max_connections + reserved_connections"に達するまで接続が可能となる。
バグではないのだけれども、パッチ取り込みの便宜上作られたバグレポート
http://bugs.mysql.com/bug.php?id=24826
Bitkeeperのcommitログ
http://lists.mysql.com/commits/19048
patchコードを見ると、普通にシステム変数を追加し、max_connections判定部分をいじっているだけのようだ。
ChangeSet@1.2359とのことだけど、まだmysql.bkbits.net上では見えない(のでたぶんbkから落としても入手はできない)。
しかしver5.0系に入ったようなので、次のリリースくらいから使えるようになるの鴨。朗報ですね♪
# なんか良く見ると+1だったのを+Nにするパッチみたいだな。+1の変更はいつはいったんだろ。。
結論:ずっと前からみたい
bkbitsでソースみたけど、ver4.0系まで遡ってもchangesetが1.1のものしかない。orz...
で、ついでなのでソースを追ってみた。
mysqld.ccのcreate_new_thread関数でmax_connectionsのチェックをしているようにも見えるのだけれども、、、
static void create_new_thread(THD *thd) { ...(中略)... /* don't allow too many connections */ if (thread_count - delayed_insert_threads >= max_connections+1 || abort_loop) { DBUG_PRINT("error",("Too many connections")); close_connection(thd, ER_CON_COUNT_ERROR, 1); delete thd; DBUG_VOID_RETURN; } ...(中略)... }
実はこのifブロックに入るのはSUPERユーザでmax_connections+2に接続数が達する場合だけ。ちなみにthread_countってのは作成済み接続数。
ではSUPERではないユーザはどこで"Too many connectoins"と弾かれるのかというと、sql_parse.ccのcheck_user関数。
int check_user(THD *thd, enum enum_server_command command, const char *passwd, uint passwd_len, const char *db, bool check_count) { ...(中略:ユーザ認証など)... if (check_count) { VOID(pthread_mutex_lock(&LOCK_thread_count)); bool count_ok= thread_count <= max_connections + delayed_insert_threads || (thd->main_security_ctx.master_access & SUPER_ACL); VOID(pthread_mutex_unlock(&LOCK_thread_count)); if (!count_ok) { // too many connections net_send_error(thd, ER_CON_COUNT_ERROR); DBUG_RETURN(-1); } } ...(中略)... }
ここで、SUPER_ACL、すなわちSUPER権限がないとmax_connectionsにより弾かれる。
このときのbacktraceはこんな感じ。
#0 check_user (thd=0x8acd5a8, command=COM_CONNECT, passwd=0x8acea76 "", passwd_len=0, db=0x0, check_count=true) at sql_parse.cc:290 #1 0x081e5a6d in check_connection (thd=0x8acd5a8) at sql_parse.cc:1052 #2 0x081e5bfb in handle_one_connection (arg=0x8acd5a8) at sql_parse.cc:1142 #3 0xa7f53240 in start_thread () from /lib/tls/i686/cmov/libpthread.so.0 #4 0xa7bb832e in clone () from /lib/tls/i686/cmov/libc.so.6