- PR -

Tomcat の DB コネクション プールをクリアしたいです

1
投稿者投稿内容
べう
会議室デビュー日: 2004/01/23
投稿数: 17
投稿日時: 2006-07-14 19:23
RHEL4 の Tomcat 5.5.16 上でデータベース MySQL 5.0.18 に繋ぐ WEB アプリケーションを作成しています。

データベースはリモートのマシン上にあり、レプリケーション機能で更に別スレーブ マシンにバックアップをとる形にしています。マスタのトラブルなどに対処するために、DNS に db.hogehoge.lan などの名前を定義して、WEB アプリからはこの名前を通してアクセスしています。故障を検知するとこの db.hogehoge.lan をスレーブのアドレスに定義し直してアクセス先を切り替える形をとっています。
かつ、WEB アプリでは、Tomcat のコネクション プールを使用してデータベースにアクセスして性能を稼いでいます。
ここで、マスタが故障した場合は特に問題なくスレーブに切り替えができるのですが、更にマスタが復旧し直してきたときに問題が発生します。db.hogehoge.lan はスレーブ側を指しているのですが、WEB アプリが復旧したマスタ側に勝手にアクセスしに行くことがあるのです。

おそらく、プールされたコネクションにマシンのアドレスなどを保持しているのだと思うのですが、これらを一旦クリアする方法はないでしょうか?

ちなみに、WEB アプリからのデータベースアクセスは、必要時に

InitialContext initialContext = new InitialContext();
DataSource dataSource = (DataSource)initialContext.lookup(...);
Connection connection = dataSource.getConnection();
...
connection.close();

の形でしています。
また、Tomcat Administration Tool で「アイドル状態の最大接続数」を 0 にしたり -1 にもしてみましたが、変化はありませんでした。

よろしくお願いします。
はしもと
大ベテラン
会議室デビュー日: 2003/02/05
投稿数: 182
投稿日時: 2006-07-16 21:27
引用:
べうさんの書き込み (2006-07-14 19:23) より:
おそらく、プールされたコネクションにマシンのアドレスなどを保持しているのだと思うのですが、これらを一旦クリアする方法はないでしょうか?



Commons DBCP は JDBC URL 以外のアドレスをキャッシュしてないと思います。

マスタが停止した時点でプール中の Connection のソケットは
全て切断されているはずです。
ここからスレーブにスムーズに移行するという事は、
再接続するための何らかの設定または処理をしていると
思いますが、どんな事をしていますか ?
べう
会議室デビュー日: 2004/01/23
投稿数: 17
投稿日時: 2006-07-20 14:43
ご返答ありがとうございます。

>再接続するための何らかの設定または処理をしていると
>思いますが、どんな事をしていますか ?

単に、送信時にエラーだった場合に、コネクションをクローズして DataSource#getConnection() で取得し再送することを複数回試みるのみです。

切断されるはずですか。切断されるということは、次に getConnection() したときにエラーになるかもしくはその後の送信処理などでエラーになるはず、ということですよね?

少し詳しくログを採るようにして、動作を明らかにしてみます。

ちなみに、プーリングを使用しないようにしたら、性能が一気に 1/10 になってしまいました (;_;)
uk
ぬし
会議室デビュー日: 2003/05/20
投稿数: 1155
お住まい・勤務地: 東京都
投稿日時: 2006-07-20 16:20
引用:

切断されるはずですか。切断されるということは、次に getConnection() したときにエラーになるかもしくはその後の送信処理などでエラーになるはず、ということですよね?


validationQueryプロパティを設定していれば、コネクションが有効かどうかを検証し、
切断されていたら自動的に再接続してくれます。そのような動作をしてほしくないので
あれば、validationQueryプロパティを設定しないようにしてはどうでしょうか。
はしもと
大ベテラン
会議室デビュー日: 2003/02/05
投稿数: 182
投稿日時: 2006-07-20 19:51
引用:
べうさんの書き込み (2006-07-20 14:43) より:
切断されるはずですか。切断されるということは、次に getConnection() したときにエラーになるかもしくはその後の送信処理などでエラーになるはず、ということですよね?



getConnection() は正常に出来ます。
しかしこの Connection が内部に保持している Socket は
切断されているのでクエリーを送信する様なメソッドを
実行すると SQLException が throw されます。

ただし testOnBorrow=true かつ validationQuery を指定して
いる場合は異なりますが。

私は MySQL の JDBC ドライバの autoReconnect パラメータを
疑ってました。これが true の時の処理内容はまったく知らないので。
1

スキルアップ/キャリアアップ(JOB@IT)