外部プロシージャで extproc.ora の変更がいつ反映されるか確認してみた

環境

設定する

  • 共有ライブラリを作成する
-bash-3.00$ cd /home/oracle/lib
-bash-3.00$ vi foo.c
#include <stdlib.h>
#include <stdio.h>
char *foo(void) {
    char *lang;
    lang = getenv("LANG");
    return lang;
}
-bash-3.00$ cc -m64 -o foo.so -G -K pic foo.c 
-bash-3.00$ vi $ORACLE_HOME/hs/admin/extproc.ora
SET EXTPROC_DLLS=/home/oracle/lib/foo.so
SET LANG=ja_JP.UTF8
  • ライブラリを作成する。
-bash-3.00$ sqlplus scott/tiger
SQL> create or replace library foo_lib as
  '/home/oracle/lib/foo.so';
/
  • 外部ファンクションとして登録する。
SQL> create or replace function foo_func
 return char as external
   library foo_lib
   name "foo"
   language c;
 /

使ってみる

  • 外部プロシージャを実行する。
SQL> set serveroutput on
SQL> exec dbms_output.put_line(foo_func());
ja_JP.UTF8

PL/SQL procedure successfully completed.
  • extproc.ora を変更してみる。
SQL> !vi $ORACLE_HOME/hs/admin/extproc.ora
SET LANG=ja_JP.EUC
SQL> !tail -2 $ORACLE_HOME/hs/admin/extproc.ora

SET LANG=ja_JP.EUC
  • 外部プロシージャを再度実行してみる。
SQL> exec dbms_output.put_line(foo_func());
ja_JP.UTF8

PL/SQL procedure successfully completed.

あれ、変わらない。

  • 一度、切断して再度サーバプロセスを起動してみる。
SQL> exit
$ sqlplus scott/tiger
SQL> set serveroutput on
SQL> exec dbms_output.put_line(foo_func());
ja_JP.EUC

PL/SQL procedure successfully completed.

変わった。

  • サーバー・プロセスのPID を調べる。
SQL> !ptree $PPID
532   /usr/lib/ssh/sshd
  21386 /usr/lib/ssh/sshd
    21387 /usr/lib/ssh/sshd
      21393 -bash
        21894 /usr/local/bin/rlwrap sqlplus scott/tiger
          21896 sqlplus scott/tiger
            21897 oraclepleco (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq)))
            22076 ptree 21896
  • サーバー・プロセスが使用しているパイプを調べる。
SQL> !pfiles 21897|grep FIFO
   9: S_IFIFO mode:0000 dev:330,0 ino:10767 uid:501 gid:501 size:0
  11: S_IFIFO mode:0000 dev:330,0 ino:10769 uid:501 gid:501 size:0
  12: S_IFIFO mode:0000 dev:330,0 ino:10768 uid:501 gid:501 size:0
  13: S_IFIFO mode:0000 dev:330,0 ino:10770 uid:501 gid:501 size:0
  • 外部プロシージャのプロセスの PID を調べる。
SQL> !ps -ef|grep [e]xtproc
  oracle 21899     1   0 14:36:59 ?           0:00 extprocpleco (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=BEQ)))
  • 外部プロシージャのプロセスが使用しているパイプを調べる。↑のサーバー・プロセスと同じパイプを使用している。
SQL> !pfiles `pgrep extproc`|grep FIFO
  10: S_IFIFO mode:0000 dev:330,0 ino:10769 uid:501 gid:501 size:0
  14: S_IFIFO mode:0000 dev:330,0 ino:10770 uid:501 gid:501 size:0
  • サーバー・プロセスを終了すると、外部プロシージャのプロセスも終了している。
SQL> exit
-bash-3.00$ ps -ef|grep [e]xtproc

結論

  • extproc.ora を変更するとリスナーやインスタンスを再起動しなくても反映される。
  • extproc.ora 変更後にはじめてコールされた外部プロシージャから変更内容が反映される。