Mac De Oracle なんですが、Windows(32bit)でのOracleな話 #4 Tweet
久々のオラクルネタですがWindows版のOracleネタです。随分前にこんなこと書いてました。
で、それ以後、見た目にはどんなエラーがでるの? とか、最近の検索フレーズ/ワードに、"Windows oracle 最大 session数"のようなフレーズを多く目にするようになったので、超簡単な再現例を一つ。
尚、Windows 32ビット環境で同時接続可能なセッション数(processes、sessions初期化パラメータに設定している値を超えた場合を除く。)は、SGAのサイズや各セッションのPGAサイズ、それに専用サーバーであるか、共有サーバーであるかという点にも影響される。お使いのシステムで、どの程度まで同時に接続できるかはその環境でしか確認できないということを付け加えておく。
また、必要最小限のPGAサイズ(単に接続しているだけなので)でどれだけ同時に接続できるのかを試している点にもご注意願いたい。(ストアドやDML文を実行する際に必要なPGAサイズはもっと大きくなる場合がほとんどなので実際に同時接続できるセッション数はもっと少なくなることの方が多い。)
●準備
この例ではすぐに接続数の上限に達するようSGAサイズはOracle10g R2 EE for Windows(32bit)が起動できる限界付近のサイズまで増加させた。
注)この方法でテストするのであれば、変更前のspfileをpfileへ退避して置く事をおすすめします。SGAサイズを大きくし過ぎてOracleを起動できなくなった場合でもpfileを使って起動することで元に戻せますから。
接続は専用サーバー接続で行い、目的のエラーを発生させる以前にprocess数やsession数の上限を超えないようにprocesses初期化パラメータを調整してある。
(SGA_TARGET及び、SGA_MAX_SIZE初期化パラメータは、私の環境でOracle10g EEが起動できる最大サイズに近い値に設定してある。ここまでSGAサイズを大きくすると、SQL*Plusを複数起動して接続するという力技でも目的のエラーを再現できる。その他初期化パラメータは以下を参照のこと。)
SYS>
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.2.0 - Prod
PL/SQL Release 10.2.0.2.0 - Production
CORE 10.2.0.2.0 Production
TNS for 32-bit Windows: Version 10.2.0.2.0 - Production
NLSRTL Version 10.2.0.2.0 - Production
SYS> show parameter sga_
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
sga_max_size big integer 1760M
sga_target big integer 1760M
SYS>
SYS> show parameter pga
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
pga_aggregate_target big integer 60M
SYS>
SYS> show parameter sessions
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
・・・・中略・・・・
sessions integer 555
・・・・中略・・・・
SYS>
SYS>
SYS> show parameter processes
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
・・・・中略・・・・
processes integer 500
SYS>
SYS> select sum(value) from v$sga;
SUM(VALUE)
----------
1845493760
SYS>
SYS> select count(*) from v$session;
COUNT(*)
----------
16
前述の状態で、ひたすら(と言っても400までだが)Oracleへ接続するだけのjava programを実行すると。。。oracle.exeのVMサイズが2GBを超えた為に、あたらなスレッドを作れないことが原因で、ORA-12518というエラーが発生する。
●以下、JDeveloper10gで試してるスナップショット
/System/Library/Frameworks/JavaVM.framework/Versions/1.5.0/Home/bin/java -server -classpath /Users/discus/jdevhome/mywork/MaxConnection/
MaxConnection/classes:/Volumes/ExtraDisk/Application/JDeveloper.app/Contents/Resources/jdev/jdbc/lib/ojdbc14dms.jar:/Volumes/ExtraDisk/
Application/JDeveloper.app/Contents/Resources/jdev/jdbc/lib/orai18n.jar:/Volumes/ExtraDisk/Application/JDeveloper.app/Contents/Resources/jdev/
jdbc/lib/ocrs12.jar:/Volumes/ExtraDisk/Application/JDeveloper.app/Contents/Resources/jdev/diagnostics/lib/ojdl.jar:/
Volumes/ExtraDisk/Application/JDeveloper.app/Contents/Resources/jdev/lib/dms.jar maxconnection.MaxConnection
コネクション数:21
java.sql.SQLException: Listener refused the connection with the following error:
ORA-12518, TNS:listener could not hand off client connection
The Connection descriptor used by the client was:
(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(PORT=1521)(HOST=192.168.1.2))(CONNECT_DATA=(SERVICE_NAME=catfish.macdeoracle.info)))
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:138)
at oracle.jdbc.driver.DatabaseError.throwSqlException(DatabaseError.java:293)
at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:328)
at oracle.jdbc.driver.PhysicalConnection.(PhysicalConnection.java:430)
at oracle.jdbc.driver.T4CConnection.(T4CConnection.java:151)
at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:32)
at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:608)
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:218)
at oracle.jdbc.pool.OracleDataSource.getConnection(OracleDataSource.java:159)
at maxconnection.MaxConnection.(MaxConnection.java:26)
at maxconnection.MaxConnection.main(MaxConnection.java:41)
●21セッション増えたことの確認!
SYS> r
1* select count(*) from v$session
COUNT(*)
----------
37
SYS>
SGAサイズをOracleが起動可能な最大値に近づけたため、たった22セッションでoracle.exeのVMサイズが2GBを超えORA-12518が発生した。
ハッキリ言って、ORA-12518 : TNS:listener could not hand off client connection というエラーメッセージを見て32ビット版Windowsの上で実行されているoracle.exeが2GBの制限を超えたため新たなスレッドを作ることができなかったエラーであると、直感的に理解出来る人は少ないんじゃないかと思う。
(他の原因でこのエラーが発生する場合もあるのかもしれないが、私がこのエラーを目にしたのはWindows環境でoracle.exeが利用できるメモリサイズを超過したため新たに専用サーバーのスレッドを作れなかった場合だけだった。
2007/11/29追記:共有サーバーモードでも試してみるか!。またWindowsでOracleを使う事もあるだろうから。。ー>TODO)
不幸にしてORA-12518に遭遇した場合は、まず最初にoracle.exeのVMサイズが2GBを超えていないか確認したほうがいいだろう。(尚、本番システムやテスト環境で発生する場合は、SGAと新たに必要とするされるPGAサイズの関係で、oracle.exeのVMサイズが1.5GBから1.6GB程度でも発生する場合もある。)
●以下、マニュアルからの引用
ORA-12518: TNS: リスナーはクライアント接続をハンドオフできませんでした
原因: クライアント接続を別のプロセスにハンドオフするプロセスが失敗しました。
処置: トレースをオンにして、失敗した操作を再実行してください。
リスナーおよびデータベース・インスタンスが、
ダイレクト・ハンドオフに対して正しく構成されていることを確認してください。
問題が解決されない場合は、オラクル社カスタマ・サポート・センターに連絡して
ください。
●以下、テストに利用したjavaのソース。
package jp.macdeoracle.maxconnection;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import oracle.jdbc.pool.OracleDataSource;
public class MaxConnection
{
public MaxConnection()
{
OracleDataSource ods;
ArrayList connList = new ArrayList();
try
{
ods = new OracleDataSource();
ods.setServerName( "192.168.1.2" );
ods.setServiceName( "catfish.macdeoracle.info" );
ods.setPortNumber( 1521 );
ods.setDriverType( "thin" );
ods.setUser( "scott" );
ods.setPassword( "tiger" );
for (int i=0;i<400;i++){
connList.add( ods.getConnection() );
}
} catch (SQLException e)
{
e.printStackTrace();
} finally
{
System.out.println("コネクション数:"+connList.size());
}
}
public static void main(String[] args)
{
MaxConnection maxConnection = new MaxConnection();
try
{
Thread.sleep(60000L); //sleep 60sec
}
catch (InterruptedException e)
{
// TODO
}
}
}
おまけ。
ORA-12518が発生した際、Pslist.exeを実行して取得したoracle.exeのVMサイズとスレッド一覧の例)
VMサイズ(赤字)が2GBに近い。
Thread detail for CATFISH:
Name Pid VM WS Priv Priv Pk Faults NonP Page
oracle 972 2074972 324688 1918700 1922024 123716 59 165
oracle 972:
Tid Pri Cswtch State User Time Kernel Time Elapsed Time
2832 9 314 Wait:Executive 0:00:00.000 0:00:00.250 0:37:03.156
2228 9 97 Wait:UserReq 0:00:00.000 0:00:00.031 0:37:01.281
2236 9 327 Wait:UserReq 0:00:00.000 0:00:00.015 0:37:01.265
2376 10 1082 Wait:UserReq 0:00:00.000 0:00:00.046 0:36:57.718
2380 8 1363 Wait:UserReq 0:00:00.015 0:00:00.000 0:36:57.687
2384 8 999 Wait:UserReq 0:00:00.375 0:00:00.015 0:36:57.671
・・・・中略・・・・
2484 10 45 Wait:UserReq 0:00:00.000 0:00:00.015 0:00:02.359
1512 10 48 Wait:UserReq 0:00:00.031 0:00:00.015 0:00:02.312
2316 10 45 Wait:UserReq 0:00:00.015 0:00:00.015 0:00:02.250
| 固定リンク | 0
コメント