MySQLとLinuxThreadsとFreeBSD
何らかの処理を同時に並行して行う(マルチタスク処理をする)には、「マルチプロセス」と「マルチスレッド」の2つの方法があります。
マルチプロセスは、アプリケーションを同時にいくつも起動し(起動して実行されているアプリケーションを「プロセス」という)、並行して処理を行う方法です。一方、マルチスレッドは、実行されているアプリケーション(プロセス)は1つですが、その中に「スレッド」という小さな処理を複数作成し、それらのスレッドが並行して同時に処理を行うものです。
例えば、Apacheは基本的にマルチプロセスで動作します。「ps -ax」コマンドを実行すれば、複数の「httpd」プロセスが起動しているのが分かるでしょう。1接続につき1つのhttpdプロセスが同時に並行して処理を行っているのです。
一方、MySQLはマルチスレッドで動作します。複数のクライアントがMySQLに接続しても、mysqldプロセスは増えません。1つのプロセスの中で複数のスレッドが動き、複数の接続を同時並行して処理しています。
マルチプロセスの利点は、個々のプロセスが独立して動き、メモリなどのリソースもプロセスごとに独立して利用できる点です。そのため、あるプロセスがフリーズしても、他のプロセスには影響を及ぼしません。このため安定した運用が可能となります。欠点としては、プロセス起動までに時間がかかること、プロセスごとにメモリなどのリソースが必要なのでリソース消費量が多くなりやすいこと、があげられます。
マルチスレッドの利点は、プロセスの中で動く小さな処理なため起動レスポンスが速いこと、各スレッドはメモリなど互いのリソースを一部共有するため、少ないリソースで動作すること、があげられます。欠点としては、スレッドはプロセスに依存するため、プロセスがフリーズするとすべてのスレッドがフリーズしてしまうこと、スレッド同士がリソースを共有しているため、適切にリソースを管理しないとデータに矛盾が生じてしまうこと、があげられます。
マルチスレッドでは、各スレッドがリソースを共有しているため、例えばスレッド1がデータを読み込むと同時にスレッド2がそのデータを上書きした場合、スレッド1は期待したデータを取得できない場合がありえます。そのため、マルチスレッドでは各スレッド間で矛盾なくデータの読み書きが出来なければなりません。この状態を「スレッドセーフ」といいます。マルチスレッドアプリケーションでは、スレッドセーフな状態が保証されていることが、バグのないアプリケーションの必須条件となります。
そして、スレッドセーフな状態は、個々のアプリケーションだけでなくOSにも求められます。むしろアプリケーションはOSに備わったスレッド機能(スレッドライブラリ)を利用しているため、まずOSのスレッドライブラリがスレッドセーフでなければなりません。
しかしながら、FreeBSDはスレッドライブラリの出来があまりよくないため、一部でスレッドセーフでない状態があるのです。
MySQLは、その出来の悪いスレッドライブラリにひっかかり、一部の動作がスレッドセーフでない状態で実行されてしまいます。
そこで、FreeBSDに備わったスレッドライブラリの代わりに「LinuxThreads」というスレッドライブラリを使うことで、スレッドセーフでない状態をある程度回避することができます。
「LinuxThreads」とは、Linux上で動作するスレッドライブラリです(なお、最新のLinuxにはOS標準のスレッドライブラリ(NPTL)が備わっていますので、どちらが使われるかはアプリケーションによります)。
Linuxで動くMySQLは、スレッドシステムにLinuxThreadsを使っています(参考資料)。
LinuxThreadsの動きは特徴的で、スレッドを作る代わりにプロセスを作ります。そして各プロセスはメモリなどのリソースを共有して動作します。そのため、LinuxThreadsを使ったMySQLは、複数個のmysqldプロセスで動作します(「ps -ax」で見ると分かるでしょう)。プロセスを複数個使った擬似マルチスレッドといった感じです。
これにより、完璧ではないもののMySQLはスレッドセーフな環境で動作することが出来ます。どうしても完璧なスレッドセーフ環境がよければ、LinuxまたはSolarisを使います(参考)。FreeBSDでもバージョン5ならばスレッドライブラリが改善されているためスレッドセーフで動きますが、まだOS自体がしっかり安定したとはいいがたいので推奨できません。