OCI8 和 DTrace 动态追踪

OCI8 2.0 引入了静态 DTrace 探针,可以在支持 DTrace 的操作系统上使用。请参阅 DTrace 动态追踪 以了解 PHP 和 DTrace 的概述。

安装带有 DTrace 支持的 OCI8

要在 PHP OCI8 中启用 DTrace 支持,请在设置 PHP_DTRACE 后,将 OCI8 构建为共享扩展。

$ export PHP_DTRACE=yes
$ pecl install oci8

编辑 php.ini,将 extension_dir 设置为包含创建的 oci8.so 的目录,并通过添加以下内容启用扩展:

extension=oci8.so

如果您使用 phpizeconfigure(而不是 pecl)从 PECL 安装 PHP OCI8,您仍然需要设置 PHP_DTRACE=yes。这是因为 --enable-dtrace 选项将被 PECL 包的有限 configure 脚本忽略。

请参阅 安装 PECL 扩展 以获取一般 PECL 安装说明。

PHP OCI8 中的 DTrace 静态探针

PHP OCI8 中提供了以下静态探针:
探针名称 探针描述 探针参数
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 脚本很有用。

connectionstatement 是指向用于追踪 PHP 连接和执行语句的内部结构的指针。

client_id 是由 oci_set_client_identifier() 设置的值。

核心 PHP 也具有静态探针。请参阅 核心 PHP 中的 DTrace 静态探针

OCI8 中的内部调试 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 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 终止。

另请参阅

添加笔记

用户贡献笔记

此页面没有用户贡献的笔记。
To Top