On the Rock

今回はオラクルのパラメータprocessesの値について。 processesはざっくりいうとデータベースに接続できるセッションの上限値を決めるパラメータである。
この上限値を決める際にドキュメント記載のルールだけでは不十分であったため備忘録として残す。
結論から言うと、processesの値を変更する際には、自動メモリ管理の場合はMEMORY_TARGETの値の変更も必要になり、とどのつまりOSの共有メモリのサイズを考慮する必要がある。

概要


オラクルデータベースにはprocessesというパラメータがある(詳細)。
ここに指定された値は、データベースに同時に接続できる最大の数を示す。
この値はどのくらいにすべきかといった点については議論の余地があるが、小さく設定するとOSのリソースを持て余すことになりあまり良いとは言えない。
たとえば急に大規模トラフィックが来た時に、実際は受けきれた量がこの値で制限がかかっていたためにセッションを受けきれないなんて事態が起き得る。
「なんでもっと大きくしなかったの?」って言われたら返す言葉もない。そこでこのパラメータの上限値を調べることにした。

さて、processesパラメータの値は、以下の式を満たす必要があるが

8.3.4 セマフォ・パラメータの設定に関するガイドライン

sum (process parameters of all database instances on the system) + overhead for oracle background processes + system and other application requirements

実際にはこの式を満たすだけでは上限を設定することができなかった。 ネックとなったのはMEMORY_TARGETに関わる共有メモリのサイズであった。

環境


  • Linux : Red Hat Enterprise Linux Server release 6.5 (Santiago)
  • oracle 12c ( Single Instance )

各種パラメータの確認


processesパラメータの値は以下の方法で確認ができる。

-- 簡易コマンド:show parameterによる確認
SQL> show parameter processes

NAME				     TYPE       VALUE
------------------------------------
...
processes			   integer     300
SQL>

また、カーネルパラメータの値は以下のコマンドで確認できる(参考)。

root# /sbin/sysctl -a

processesの上限値の算出


公式ドキュメントによると、processesは以下の式を満たす必要があると書かれている。

8.3.4 セマフォ・パラメータの設定に関するガイドライン

sum (process parameters of all database instances on the system) + overhead for oracle background processes + system and other application requirements

それでは現在のカーネルの値からprocessesの上限値を算出する。

[root@test1 ~]# /sbin/sysctl -a | grep sem
kernel.sem = 250	32000	100	128
# --> 各値は左から順に semmsl、semmns、semopm、semmni

上記の結果から、processesの値は以下の式を満たせば良い。

32000 > processes + overhead

適当に30,000を上限としても良いが、プロセス数ができることを考慮しnprocの最大数も確認してみる( 参考)。

# nprocの値確認
[root@test1 ~]# cat /etc/security/limits.conf | grep nproc
#        - nproc - max number of processes
oracle   soft   nproc    2047
oracle   hard   nproc    16384
[root@test1 ~]#

上記の結果から、processesの値を16,384に設定してDBインスタンスを再起動する。
processesは静的パラメータのため、値の反映にはインスタンスの再起動が必要 )

SQL> alter system set processes=16384 scope=spfile;

システムが変更されました。

SQL> shutdown immediate;
データベースがクローズされました。
データベースがディスマウントされました。
ORACLEインスタンスがシャットダウンされました。
SQL>
SQL> startup;
ORA-00838: Specified value of MEMORY_TARGET is too small, needs to be at least 5088M
SQL>

起動せず。。。
エラーメッセージの通りパラメータMEMORY_TARGETの値を5,088Mに変更し再度、起動を試みる。

-- pfileの作成
SQL> create pfile='/tmp/20181024.ora' from spfile;

ファイルが作成されました。

SQL> exit
# パラメータファイルの修正
[oracle@test1 tmp]$ vi 20181024.ora
--> memory_targetの値を変更

[oracle@test1 tmp]$ cat 20181024.ora | grep memory_tar
*.memory_target=5088m

さて、再起動。

SQL> startup pfile='/tmp/20181024.ora';
ORA-00845: MEMORY_TARGET not supported on this system
SQL>

起動せず。エラー内容が変わったため、MEMORY_TARGETの値は元の1,580Mに戻し
さきほどのORA-00838が出ないようなprocessesの値を探すことにする。

以下に二分法で調べた結果を記す。

-- 16384/2=8192
SQL> startup pfile='/tmp/20181024.ora';
ORA-00838: Specified value of MEMORY_TARGET is too small, needs to be at least 4816M
ORA-01078: システム・パラメータの処理に失敗しました
SQL>

--> ダメ


-- 8192/2=4096
SQL> startup pfile='/tmp/20181024.ora';
ORA-00838: Specified value of MEMORY_TARGET is too small, needs to be at least 2528M
ORA-01078: システム・パラメータの処理に失敗しました
SQL>

--> ダメ


-- 4096/2=2056
SQL> startup pfile='/tmp/20181024.ora';
ORACLEインスタンスが起動しました。

Total System Global Area 1660944384 bytes
Fixed Size		    2925072 bytes
Variable Size		 1442844144 bytes
Database Buffers	  201326592 bytes
Redo Buffers		   13848576 bytes
データベースがマウントされました。
データベースがオープンされました。
SQL>

--> 成功

したがって、processesの上限は2,056から4,096の間であることが分かる。
って当初の想定と比べると全然低い。。。

考察


processesの上限値を設定する際には単にセマフォの値から算出するだけでは不十分でありMEMORY_TARGETの値も考慮する必要があった。
processesの上限値を決めるとそれだけメモリ領域も必要になるからと考えられる。

また、MEMORY_TARGETの上限値についてはドキュメントに以下の記載がある。

自動メモリー管理

Oracle Database 11g以降、自動メモリー管理機能は、より多くの共有メモリー(/dev/shm)とファイル記述子が必要になります。共有メモリーのサイズは、コンピュータ上のOracleインスタンスごとにMEMORY_MAX_TARGETおよびMEMORY_TARGETのサイズより大きい必要があります。MEMORY_MAX_TARGETパラメータまたはMEMORY_TARGETパラメータがゼロでない値に設定されており、共有メモリーのサイズが正しく割り当てられていない場合、起動時にORA-00845エラーが発生します。Linuxシステムで、オペレーティング・システムの/dev/shmマウント・サイズが、Oracleシステム・グローバル領域(SGA)およびプログラム・グローバル領域(PGA)に対して小さすぎる場合、ORA-00845エラーが生じます。

共有メモリを確認するとなるほどたしかにMEMORY_TARGETの値と同じ値が使用されている。

[oracle@test1 ~]$  df -h /dev/shm/
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           2.0G  1.4G  601M  70% /dev/shm
[oracle@test1 ~]$

このことから、processesMEMORY_TARGETにも依存し、MEMORY_TARGETは共有メモリに依存していることが見てとれる。

まとめ


processesの値はセマフォだけでなく、共有メモリとも深く関わっていることが分かった。 processesに上限値を設定したい場合にはこれらを確認すると良い。

参考資料


パラメータ:processes
カーネル・パラメータ値の変更
セマフォ・パラメータの設定に関するガイドライン
LIMITING MAXIMUM NUMBER OF PROCESSES AVAILABLE FOR THE ORACLE USER
自動メモリー管理