スレッド数のサイジング

出典: MySQL Practice Wiki


MySQLはシングルプロセス&マルチスレッドなプログラムで、比較的多くのスレッドを必要とする。内部的にはpthreadライブラリが使用されていて、接続要求があるたびにptrehad_create()が呼び出されている。システムが十分なスレッドを提供できないとランタイムエラーが発生してしまう。最も顕著なのはある一定以上の接続が出来なくなるというエラーだ。例えばWebアプリケーションでこれが発生してしまうと、ユーザ側にはInternal Server Error等に見えてしまう。そのような事態を避けるためには、システムを運用に乗せる前、サイジングの段階できっちりとスレッド数に関する設定をしてやる必要がある。

必要なスレッド数の見積もり

MySQLサーバが内部的に必要とするスレッド数に関するオプションを以下に列挙する。

用途関連オプション初期値
コネクションスレッドmax_connections100
MyISAM INSERT DELAYED用スレッドdelayed_insert_limit100
InnoDB I/Oスレッドinnodb_file_io_threads4 (UNIX系システムでは変更不可)
Slaveスレッド(レプリケーションスレーブのみ)N/A2
その他管理用スレッド(サーバシャットダウンなど)N/A1

これらのスレッドの合計値以上のスレッドを1プロセスあたり作成できるようにする必要がある。

設定方法

作成可能なスレッド数とその調整方法は、OSの種類によって異なる。

Linux (2.6、2.4系)
以下のいずれかの方法にてthreads-maxカーネルパラメータを調節する。
  • /etc/sysctl.confにてkernel.threads-maxを設定。
  • /proc/sys/kernel/threads-maxに対して値を書き込む。
Windows
UNIX互換のpthread_create()を実装しているが、裏でCreateThread Win32 APIを呼び出しているのでそちらの上限を受ける。Windowsはデフォルトでは1MBという巨大なスタックをスレッドに割り当てるため、2GBメモリの制限がある場合には2048までのスレッドしか作成することが出来ない。MySQLではスレッドのスタックサイズがデフォルトでは192KBなので、それよりは多少多くのスレッドを作成できるものと思われる。
Solaris
スレッド数自体に制限はないが、スレッドを処理するLWPの最大数に制限される。LWPの最大数はそのスタック領域はsegkpに作成される。そのため、segkpを使い果たしたときがLWPの最大数となる。segkpのサイズを大きくするには/etc/systemにおいてsegkpsizeを設定すれば良い。
HP-UX
以下の2つのカーネルパラメータを設定する必要がある。
これらはプロセスの上限値を規定するものであるが、HP-UXでは恐らくスレッドがプロセスのように(まるでNPTLのない古いLinuxのようだが)実装されているのだろう。
FreeBSD
以下の2つのカーネルパラメータを設定する。
kern.threads.max_groups_per_proc
kern.threads.max_threads_per_proc
さらに必要に応じてスタックの上限サイズを調整する。
kern.maxssiz
kern.dflssiz
個人用ツール