OCI8 および DTrace 動的トレーシング
OCI8 2.0 では、DTrace をサポートする OS 上で使用できる 静的な DTrace プローブが導入されました。 PHP および DTrace の概要については、DTrace 動的トレーシング をご覧ください。
DTrace サポート付きで OCI8 をインストール
PHP OCI8 で DTrace のサポートを有効にするには、
PHP_DTRACE
を設定後、
OCI8 を共用拡張モジュールとしてビルドします。
$ export PHP_DTRACE=yes $ pecl install oci8
php.ini を編集し、作成された oci8.so がある ディレクトリを extension_dir に 設定します。 さらに以下のように追加してその拡張モジュールを有効にします。
extension=oci8.so
もし、phpize および configure を
( pecl の代わりに)
使用して PECL から PHP OCI8 をインストールする場合、
さらに PHP_DTRACE=yes
を設定する必要があります。
それは、--enable-dtrace
オプションが、PECL バンドルの
制限された configure スクリプトにより
無視されるからです。
一般的な PECL インストール手順については、PECL 拡張モジュールのインストール をご覧ください。
PHP OCI8 の DTrace 静的プローブ
プローブ名 | プローブの説明 | プローブの引数 |
---|---|---|
oci8-connect-entry |
oci_connect()、oci_pconnect() および oci_new_connect() により開始されます。データベース接続が確立する前に発射されます。 | char *username, char *dbname, char *charset, long session_mode, int persistent, int exclusive |
oci8-connect-return |
接続終了時に発射されます。 | void *connection |
oci8-check-connection |
Oracle のエラーにより、接続が不正になったかもしれない場合に発射されます。 | void *connection, char *client_id, int is_open, long errcode, unsigned long server_status |
oci8-sqltext |
oci_parse() が実行された際に発射されます。 | void *connection, char *client_id, void *statement, char *sql |
oci8-connection-close |
データベースへの接続が完全に破壊された際に発射されます。 | void *connection |
oci8-error |
Oracle のエラーが生じた場合に発射されます。 | int status, long errcode |
oci8-execute-mode |
実行モードを示す oci_execute() のたびに発射されます。 | void *connection, char *client_id, void *statement, unsigned int mode |
これらのプローブは、OCI8 スクリプトのトレーシングで有用です。
connection および statement は、 PHP の接続および実行されたステートメントを追跡するために使用される内部構造への ポインタです。
client_id は、 oci_set_client_identifier() により設定される値です。
コア PHP にも静的プローブがあります。 コア PHP の DTrace 静的プローブ をご覧ください。
プローブ名 |
---|
oci8-connect-expiry |
oci8-connect-lookup |
oci8-connect-p-dtor-close |
oci8-connect-p-dtor-release |
oci8-connect-type |
oci8-sesspool-create |
oci8-sesspool-stats |
oci8-sesspool-type |
これらのプローブは、OCI8 メンテナにとって有用です。 引数およびいつ発射されるかについては、OCI8 のソースコードを参照ください。
PHP OCI8 の DTrace 静的プローブ一覧
使用できるプローブを一覧表示するには、 PHP プロセスを開始して以下のように実行します。
# dtrace -l
出力は以下のようになります。
ID PROVIDER MODULE FUNCTION NAME [ . . . ] 17 phpoci22116 oci8.so php_oci_dtrace_check_connection oci8-check-connection 18 phpoci22116 oci8.so php_oci_do_connect oci8-connect-entry 19 phpoci22116 oci8.so php_oci_persistent_helper oci8-connect-expiry 20 phpoci22116 oci8.so php_oci_do_connect_ex oci8-connect-lookup 21 phpoci22116 oci8.so php_oci_pconnection_list_np_dtor oci8-connect-p-dtor-close 22 phpoci22116 oci8.so php_oci_pconnection_list_np_dtor oci8-connect-p-dtor-release 23 phpoci22116 oci8.so php_oci_do_connect oci8-connect-return 24 phpoci22116 oci8.so php_oci_do_connect_ex oci8-connect-type 25 phpoci22116 oci8.so php_oci_connection_close oci8-connection-close 26 phpoci22116 oci8.so php_oci_error oci8-error 27 phpoci22116 oci8.so php_oci_statement_execute oci8-execute-mode 28 phpoci22116 oci8.so php_oci_create_spool oci8-sesspool-create 29 phpoci22116 oci8.so php_oci_create_session oci8-sesspool-stats 30 phpoci22116 oci8.so php_oci_create_session oci8-sesspool-type 31 phpoci22116 oci8.so php_oci_statement_create oci8-sqltext
PROVIDER 列の値は、phpoci
および
現在実行中の PHP プロセスのプロセス ID から構成されます。
FUNCTION 列は、各プロバイダが配置された PHP 内部の C 実装関数名を参照します。
PHP プロセスが実行されていない場合、PHP プローブは表示されません。
PHP OCI8 についての DTrace の例
この例では、DTrace の D スクリプト言語の基本を示します。
例1 DTrace を使用して すべてのユーザーレベルの PHP OCI8 静的プローブをトレースするための user_oci8_probes.d
#!/usr/sbin/dtrace -Zs #pragma D option quiet php*:::oci8-connect-entry { printf("%lld: PHP connect-entry\n", walltimestamp); printf(" credentials=\"%s@%s\"\n", arg0 ? copyinstr(arg0) : "", arg1 ? copyinstr(arg1) : ""); printf(" charset=\"%s\"\n", arg2 ? copyinstr(arg2) : ""); printf(" session_mode=%ld\n", (long)arg3); printf(" persistent=%d\n", (int)arg4); printf(" exclusive=%d\n", (int)arg5); } php*:::oci8-connect-return { printf("%lld: PHP oci8-connect-return\n", walltimestamp); printf(" connection=0x%p\n", (void *)arg0); } php*:::oci8-connection-close { printf("%lld: PHP oci8-connect-close\n", walltimestamp); printf(" connection=0x%p\n", (void *)arg0); } php*:::oci8-error { printf("%lld: PHP oci8-error\n", walltimestamp); printf(" status=%d\n", (int)arg0); printf(" errcode=%ld\n", (long)arg1); } php*:::oci8-check-connection { printf("%lld: PHP oci8-check-connection\n", walltimestamp); printf(" connection=0x%p\n", (void *)arg0); printf(" client_id=\"%s\"\n", arg1 ? copyinstr(arg1) : ""); printf(" is_open=%d\n", arg2); printf(" errcode=%ld\n", (long)arg3); printf(" server_status=%lu\n", (unsigned long)arg4); } php*:::oci8-sqltext { printf("%lld: PHP oci8-sqltext\n", walltimestamp); printf(" connection=0x%p\n", (void *)arg0); printf(" client_id=\"%s\"\n", arg1 ? copyinstr(arg1) : ""); printf(" statement=0x%p\n", (void *)arg2); printf(" sql=\"%s\"\n", arg3 ? copyinstr(arg3) : ""); } php*:::oci8-execute-mode { printf("%lld: PHP oci8-execute-mode\n", walltimestamp); printf(" connection=0x%p\n", (void *)arg0); printf(" client_id=\"%s\"\n", arg1 ? copyinstr(arg1) : ""); printf(" statement=0x%p\n", (void *)arg2); printf(" mode=0x%x\n", arg3); }
このスクリプトは、dtrace に対して
-Z
オプションを使用します。
それにより、実行中の PHP プロセスがない場合に実行できるようになります。
もしこのオプションが書き落とされた場合、
モニターされているプローブがどれも存在しないことがわかっているので、
PHP の実行可能ファイルが実行されていない場合、
スクリプトは即座に終了します。
マルチ CPU マシンでは、プローブの順序は規則的に連続して表示されないことがあります。 これは、どの CPU がプローブを処理し、 CPU の間をスレッドがどのように移動したかに依存します。 プローブのタイムスタンプを表示すると、 混乱を減らすことができます。
スクリプトは、PHP スクリプト実行中の期間全体にわたって、 すべてのユーザーレベルの PHP OCI8 静的プローブ・ポイントをトレースします。 D スクリプトを実行します。
# ./user_oci8_probes.d
PHP スクリプトまたはアプリケーションを実行します。 モニタリングの D スクリプトは、各プローブが発射されるたびに その引数を出力します。 例えば、テーブルを照会する単純な PHP スクリプトにより 以下のトレース出力がもたらされるでしょう。
1381794982092854582: PHP connect-entry credentials="hr@localhost/pdborcl" charset="" session_mode=0 persistent=0 exclusive=0 1381794982183158766: PHP oci8-connect-return connection=0x7f4a7907bfb8 1381794982183594576: PHP oci8-sqltext connection=0x7f4a7907bfb8 client_id="Chris" statement=0x7f4a7907c2a0 sql="select * from employees" 1381794982183783706: PHP oci8-execute-mode connection=0x7f4a7907bfb8 client_id="Chris" statement=0x7f4a7907c2a0 mode=0x20 1381794982444344390: PHP oci8-connect-close connection=0x7f4a7907bfb8
モニタリングが完了した際には、CTRL+C を使用して D スクリプトを終わらせることができます。