2024 年 PHP Conference Japan

OCI8 與 DTrace 動態追蹤

OCI8 2.0 引入了可在支援 DTrace 的作業系統上使用的靜態 DTrace 探針。有關 PHP 和 DTrace 的概述,請參閱 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。這是因為 PECL 套件的精簡版 configure 腳本會忽略 --enable-dtrace 選項。

有關一般 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

「提供者」欄位的值包含 phpoci 和目前正在執行的 PHP 程序的程序 ID。

「函式」欄位指的是 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);
}

此腳本使用 -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

監控完成後,可以使用 CTRL+C 終止 D 腳本。

另請參閱

新增註解

使用者貢獻的註解

此頁面沒有使用者貢獻的註解。
To Top