OCI8 2.0 引入了静态 DTrace 探针,可以在支持 DTrace 的操作系统上使用。请参阅 DTrace 动态追踪 以了解 PHP 和 DTrace 的概述。
要在 PHP OCI8 中启用 DTrace 支持,请在设置 PHP_DTRACE
后,将 OCI8 构建为共享扩展。
$ export PHP_DTRACE=yes $ pecl install oci8
编辑 php.ini,将 extension_dir 设置为包含创建的 oci8.so 的目录,并通过添加以下内容启用扩展:
extension=oci8.so
如果您使用 phpize 和 configure(而不是 pecl)从 PECL 安装 PHP OCI8,您仍然需要设置 PHP_DTRACE=yes
。这是因为 --enable-dtrace
选项将被 PECL 包的有限 configure 脚本忽略。
请参阅 安装 PECL 扩展 以获取一般 PECL 安装说明。
探针名称 | 探针描述 | 探针参数 |
---|---|---|
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 进程,然后运行
# 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 探针。
此示例展示了 DTrace D 脚本语言的基础知识。
示例 #1 user_oci8_probes.d 用于使用 DTrace 追踪所有用户级 PHP OCI8 静态探针
#!/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); }
此脚本使用 -Z
选项来运行 dtrace,使其能够在没有执行 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
当监控完成后,D 脚本可以使用 CTRL+C 终止。