はじめに
ある時、Oracleのローカル接続時にプロセスがどうなっているのか、
ふと気になったので調べてみました。環境はRHEL7.2です。
専有サーバ接続の場合、サーバプロセスとクライアントプロセスが1:1になるので、
下図のような構成図になっています。
ローカル接続をした状態でpstree -pコマンドを実行すると、下図のような
親子関係が確認できました。
つまり、プロセスID 4713 のクライアントプロセス(sqlplus)が、プロセスID 4714 の
Oracle サーバプロセス(oracle)を fork しているように見えます。
実際、sqlplusコマンドをstraceで見てみると、こんな感じで親子が execve を実行していました↓。
-f は子プロセスのシステムコールも出力するオプションです。
[oracle@ホスト名 ~]$ strace -f -e execve sqlplus / as sysdba
execve("/oracle/product/11.2.0/dbhome_1/bin/sqlplus", ["sqlplus", "/", "as", "sysdba"], [/* 25 vars */]) = 0
SQL*Plus: Release 11.2.0.4.0 Production on Fri Aug 2 21:28:56 2024
Copyright (c) 1982, 2013, Oracle. All rights reserved.
Process 4714 attached
[pid 4714] execve("/oracle/product/11.2.0/dbhome_1/bin/oracle", ["oracle[SID]", "(DESCRIPTION=(LOCAL=YES)(ADDRESS"...], [/* 26 vars */]) = 0
↑ 子プロセス(4714)がoracleを実行しているのが分かります。
(略)
環境変数について
ローカル接続をする際は、通常 ORACLE_SID と ORACLE_HOME を環境変数に
設定したうえで接続しますが、ログインシェルで設定したこれらの環境変数が
確かに子プロセスに引き継がれていることを確認してみました。
[oracle@ホスト名 ~]$ cat /proc/4714/environ
(略)
ORACLE_SID=~~
(略)
ORACLE_HOME=/oracle/product/11.2.0/dbhome_1
(略)
[oracle@ホスト名 ~]
確かに引き継がれてますね。
これらの環境変数をexecveがどのように使用しているのかについて、strace結果を
読み込んでより詳細に理解したかったのですが、よく分かりませんでした。
少なくとも、環境変数ORACLE_HOMEに関しては$ORACLE_HOME/lib配下にある
共有ライブラリ(libclntsh.soとか、libnsl.soとか)をロードするためなどに
使っているみたいです。
ちなみに、リモート接続の場合もクライアントプロセスが接続要求をして
サーバプロセスが生成されるので親子関係がありそうな気がしましたが、
実際にはそのような親子関係は確認できませんでした。
おわりに
当たり前のことなのかもしれませんが、調べてみて少しだけローカル接続の理解が
深まったような気がします。
・追記(20240729)
ローカル接続時に、効率化のために、環境変数を記述したsetup.shのようなファイルを
/home/oracle に配置して実行することが多いですが、この投稿を書いた後、この記事を
読んだところで、なぜ./setup.shではなく. ./setup.sh(もしくはsource ./setup.sh)を
実行すべきなのか改めて理解できました。
#!/bin/bash
export ORACLE_BASE=/oracle
export ORACLE_SID=[SID]
export ORACLE_HOME=/oracle/product/11.2.0/dbhome_1
export PATH=$PATH:$ORACLE_HOME/bin:$ORACLE_HOME/OPatch