2009-09-21 15 views
19

私たちは、私たちがデータに対してどのように動作するかを見たいところで、MySQLの小さなベンチマークを行っています。複数のスレッドから同時にMySQLにアクセスする方法

このテストの一部は、複数の同時スレッドがさまざまなクエリを使用してサーバーをハマるときの動作を確認することです。

MySQL documentation(5.0)は、マルチスレッドクライアントについてはっきりしていません。私はプリペアドステートメントを使用して、読み取り(SELECT)及び(DELETE、UPDATE、INSERT)を書き込みの両方を行うよ(libmysqlclient_r.so)私は、スレッドセーフライブラリに対してリンクを行うことを

を指摘しなければなりません。

  • スレッドごとに1つの接続を開く必要がありますか?もしそうなら:どうすればいいのですか?mysql_real_connect()は、私がmysql_init()と呼んだときに元のDBハンドルを返すようです。
  • もしそうなら:代わりにmysql_affected_rowsのような結果とメソッドが正しい値を返すようにします他のスレッドの呼び出しと衝突する(ミューテックス/ロックが機能する可能性がありますが、間違っていると感じます)

答えて

25

MySQLを複数のスレッドから呼び出すかなり大きなCアプリケーションのメンテナーとして、私は各スレッドで単に新しい接続を作成するだけで問題はなかったと言えます。

  • 編集:私が遭遇してきたいくつかの注意点、この弾丸が唯一のバージョン< 5.5に適用されるようです。 this page for your appropriate versionを参照してください。あなたがすでにやっているように、libmysqlclient_rとリンクしてください。
  • mysql_library_init()(1回、main())を呼び出します。なぜそれが必要なのかを知るために、マルチスレッド環境での使用についてのドキュメントを読んでください。
  • MYSQL構造を各スレッドにmysql_init()を使用して作成します。これにはmysql_thread_init()を呼び出す副作用があります。 mysql_real_connect()各スレッドの内部ではいつものように、スレッド固有のMYSQL構造体を持っています。
  • 多くのスレッドを作成/破棄している場合は、各スレッドの最後にmysql_thread_end()を使用します(末尾にmysql_library_end()、末尾にmain())。それはとにかく良い練習です。基本的には

は、その構造体(すなわちMYSQL_STMT S)に固有の作成MYSQL構造体や何かを共有しないと、あなたが期待するとして、それは動作します。

これは、私に接続プールを作るよりも少ない仕事のようです。

+1

これはちょうど私が必要とした答えの種類でした。私は各スレッドでmysql_initを呼び出さなければならないことに気づいていませんでした。私はmain()で一度だけ実行しました。ありがとうございます –

+1

@chazomaticus、あなたは通常どのくらいのスレッドを使用していて、いくつの接続を開いていますか?これは、多数のスレッド/接続に拡張されますか? (100〜1000)のスレッドをたくさん持っていて、1000の接続を開くのに必要なオーバーヘッド(max_connectionsのデフォルト値は通常100に設定されているため、アクセス許可を得られない可能性があります)を必要としない場合は、あなたがスレッドの数が少ない場合、あなたのアプローチはうまくいくでしょう。コード例を表示するために私から+1。 – Glen

+1

Isakは可能な限り多くのスレッドをDBにストレスしようとしています。私は〜1000の問題なしで実行しました(すべてのスレッドが問題クエリである場合、ほとんどの時間は 'poll()'でアイドル状態になります)、チャンクを食べることはできますが、CPU集約的ではありませんのメモリ)。 max_connectionsについては、デフォルトで100に設定されているので、最大限のストレスになるように、必要に応じて上限を設定してください。 – chazomaticus

6

接続プールを作成できます。接続が必要な各スレッドはプールから空きのスレッドを要求できます。利用可能な接続がない場合は、新しい接続を追加することによってプールをブロックするか、プールを拡大します。

(これは、Javaベースのですが)接続プールのプロのと短所を説明した記事here

編集

あります:ここではSOの質問/についてconnection pools in C

EDIT2に答えるのです。ここではサンプルへのリンクですConnection Pool for MySQLはC++で書かれています。 (あなたがあなた自身を実装する場合は、おそらくのgoto文を無視すべきである。)

+0

良い答えです。ありがとうございます。しかし、私はまだ1つ以上の接続を開いても問題があります。リンクしたサンプルにはそのコードがありません。私はあなたに+1を与えましたが、私はそれを受け入れたくありません。複数の接続を開く際の問題 –

+0

しかし、実際に記事を共有してくれてありがとう〜 – yaobin

-1

MySQL Threaded Clients in C

それはにmysql_real_connect()はデフォルトではスレッドセーフではありませんと述べています。クライアントライブラリは、スレッドアクセスのためにコンパイルする必要があります。

+0

私はlibmysqlclient_rライブラリを使用していますので、コンパイルされたすべてのスレッドセーフなものがあると仮定します。スレッドを産み出す前にそれが役立つかどうかを確認してください –

1

特定のMYSQL構造体がスレッドで難なく使用できることがわかりました - 同じ MYSQL構造体を異なるスレッドで同時に使用すると、状態が保存されるときに非常に予測できない結果が得られますMYSQL接続内で実行します。

上記のように、スレッドごとに接続を作成するか、または接続プールを使用し、何らかのミューテックスを使用してそのプールへのアクセスを保護する(つまり、接続を予約または解放する)。

+0

これは私が疑ったことです。複数の接続を作成する方法を理解する必要があります。今すぐ動作させることができません。 –

+0

これに問題はありませんでしたが、これらのライブラリを使用してください。 MYSQL構造体とinitを別々に割り当て、それぞれを接続できるはずです。 – Elemental

関連する問題