前エントリー「PHPからociでOracleデータベースへ接続する方法と注意点まとめ – TechNote」で、PHPからociでOracleデータベースに接続したときのメモを残しましたが、実際にociを使用して既存システムのデータベースに接続をするときには「セッション数」を十分に考慮しなくてはなりません。ということでセッション数を確認しながらテストした過程のメモ。
1.セッションとは
ここでいうセッションは、Webのsessionとは違います。
ユーザーがユーザープロセスを介してOracleインスタンスに接続するときの特定の接続のことです。Oracleに接続するとセッションが1つ生成されます。切断すると1つ消滅します。
Oracleでは、セッション数(最大同時接続数)を制限するパラメータがあり、その数をオーバーするような多数の同時接続があった場合、以降の新規接続が確立されなくなります。(それくらいの問題で済んだはず?だと思う。)
Oracleを使ったシステムならそのあたりは十分に検討された設計がなされているはずです。ですが今回のように、単体で動いていた既存システムのOracleDBを活用するような場合には、設計者の意図しない接続数となるわけですから、十分な注意が必要となります。
(セッションに似たような位置付けの言葉に「プロセス」がありますが、ここではセッションだけを見ていくことにして、プロセスの説明は割愛します。)
2.Oracleで最大セッション数と現在のセッション数を確認する方法
(1)sqlplusでシステム管理者としてログインする
v$sessionからセッション情報を得ることができますが、v$sessionを覗くにはまずシステム管理者としてログインする必要があります。
コマンドプロンプトを起動して以下のように打つことで管理者としてログインできます。
squplus system/manager@[接続文字列]
(2)最大セッション数の設定値を確認する
最大セッション数はv$system_parameterにて確認することができます。以下のsqlを発行します。
select name, type, value from v$system_parameter where name = 'sessions'
(3)現在のv$sessionを確認する
現在のセッション数(同時接続数)はv$sessionにて確認することができます。
単純にセッション数を知りたい場合は下記のsqlでv$sessionのレコード数をカウントするだけです。
select count(*) from v$session;
ですが今回は、phpからの接続がどのようにセッションを占有するのかをきちんと見ておきたいので、セッションの内訳を見ていくことにします。
全項目をselectすると、項目数が多すぎてコマンドプロンプトではひと目で確認できないので、selectする項目を絞る必要があります。
ちなみに観察した項目は下記です。
項目名 | 詳細 |
---|---|
SID | セッション識別子 |
SERIAL# | セッション・シリアル番号 |
USERNAME | Oracleのユーザー名 |
STATUS | 状態: ACTIVE,INACTIVE,KILLED,CACHED,SNIPED |
OSUSER | OSのユーザー名 |
PROCESS | OSのプロセスID |
MACHINE | OSのマシン名 |
TERMINAL | OSの端末名 |
PROGRAM | OSのプログラム名 |
コマンドプロンプトに結果を表示させてもなかなか追いにくいところがあるので、ファイルに出力することにします。
logに出力するには下記のように打ちます。
spool d\temp\result.log
select username,status,osuser,machine,terminal,program from v$session;
spool off
CSVとして出力するには下記のよう打ちます。
set echo off
set linesize 1000
set pagesize 0
set trimspool on
set feedback off
set colsep ','
spool d:\temp\result.csv
select username,status,osuser,machine,terminal,program from v$session;
spool off
※注意点
「status」のactice/inactiveについて。一見、inactiveだったら「もうレコードだけ残っているだけで、開放されてるってことじゃないの?」と思ってしまいがちですが、inactiveで残っているということはクライアントから接続されていて生きているコネクションということです。コネクションプーリングを行っている可能性があります。よって、単純にセッション数を知りたい場合は、active/inactive関係なくv$session全体をカウントすべきです。
3.実際セッションの増え方を観察してみた
oci接続をするWebシステムをブラウザで起動させたら、v$sessionに以下のようなレコードが追加されました。
sid | session# | terminal | program |
---|---|---|---|
41 | 37140 | testsvr | httpd.exe |
どうやらphpからの接続は、端末名はwebサーバをおいているマシン名、プログラム名は「httpd.exe」となるようです。
試しにもう一個ブラウザを起動して、v$sessionを見てみると
sid | session# | terminal | program |
---|---|---|---|
41 | 37140 | testsvr | httpd.exe |
57 | 5564 | testsvr | httpd.exe |
2つに増えます。この調子だと社内の全端末でこのwebシステムを起動すると最大接続数をすぐに超えてしまい、既存システムの動作に影響を与えてしまいそうです。(最大接続数を増やすという案はここでは考えません。)
4.とった対策
これに対してとれる対策は、一般的なことですが「不要となった接続は閉じる」こと。データベースリソースを有効に使うためには、接続を閉じる行為は常識です。
oci接続の閉じ方は下記でOKのようです。
oci_close($con);
ですが、わたしの場合CodeIgniterのアクティブレコードを使用しているため、カプセル化された部分できちんとclose処理まで書かれているはずとなので、なぜセッションが残るのかが不思議でした。close処理なんて書く必要ないはずですが、内部の処理を追っていくしかないのかなぁと思ってた矢先、すぐに答えに辿り着きました。
答えはdatabase.phpの設定値にありました。
//変更前のdatebase.php
$db['default']['hostname'] = "(DESCRIPTION =(ADDRESS_LIST =(ADDRESS = (PROTOCOL = TCP)(HOST = svord)(PORT = 1521)))(CONNECT_DATA =(SERVICE_NAME = ORCL)))";
$db['default']['username'] = "username";
$db['default']['password'] = "password";
$db['default']['database'] = "connectstring";
$db['default']['dbdriver'] = "oci8";
$db['default']['dbprefix'] = "";
$db['default']['pconnect'] = TRUE;
$db['default']['db_debug'] = TRUE;
$db['default']['cache_on'] = FALSE;
$db['default']['cachedir'] = "";
$db['default']['char_set'] = "utf8";
$db['default']['dbcollat'] = "utf8_general_ci";
初期状態ではpconnectが”TRUE”になっているので、ここを”FALSE”に変更します。
$db['default']['pconnect'] = FALSE;
pconnectを有効にするということは、oci_pconnect関数を使って接続するということで、持続的接続することを意味します。
ということで、わたしの場合のセッション占有の原因はoci_closeしていないことではなくて、pconnectを使用していたとにありました。
これを修正した結果、以降新しく接続数を増やしても(別のブラウザでいくつ開いていっても)、セッション数は一切増えることはありませんでした。
最後にこれまでのテスト過程で残留したセッションを終了させます。終了させるには以下のようなsqlを書きます。
alter system kill session '[sid],[serialNo]';
事前にv$sessionにて、終了させたいレコードのsid,serialNoを確認してから上記sqlを実行すると、該当レコードのstatusはkilledとなります。killed状態(消滅待ち状態)となったレコードがどのタイミングで消滅するのかは確認できていません。しばらくはkilled状態で残りましたが翌日には消えていました。
環境は下記でした。
- XAMPP for windows 1.8.1
- Oracle11g
絵で見てわかるOracleの仕組み (DB Magazine SELECTION)
- 作者: 小田圭二
- 出版社/メーカー: 翔泳社
- 発売日: 2006/06/21
- メディア: 単行本
- 購入: 27人 クリック: 385回
- この商品を含むブログ (48件) を見る
基礎からのOracle (DVD付) (プログラマの種シリーズ)
- 作者: 西沢夢路
- 出版社/メーカー: ソフトバンククリエイティブ
- 発売日: 2010/05/28
- メディア: 大型本
- 購入: 2人 クリック: 15回
- この商品を含むブログ (10件) を見る
1週間でORACLE MASTERの基礎が学べる本 (徹底攻略)
- 作者: 森下泰子,株式会社ソキウス・ジャパン
- 出版社/メーカー: インプレスジャパン
- 発売日: 2010/08/26
- メディア: 単行本(ソフトカバー)
- クリック: 2回
- この商品を含むブログを見る