このドキュメントで説明するソフトウェアは、Extended SupportまたはSustaining Supportのいずれかにあります。 詳細は、https://www.oracle.com/us/support/library/enterprise-linux-support-policies-069172.pdfを参照してください。
Oracleでは、このドキュメントに記載されているソフトウェアをできるだけ早くアップグレードすることをお薦めします。

機械翻訳について

11.8 ユーザー領域アプリケーションのトレース

MySQLやPHPなど、多くのDTrace対応アプリケーションは、DTrace 0.4のリリース以降に使用できるようになります。 これらのアプリケーションは、静的に定義されたDTraceプローブを含むようにインストゥルメント化されています。 MySQLのプローブの詳細はhttp://dev.mysql.com/doc/refman/5.5/en/dba-dtrace-mysqld-ref.htmlを、PHPのプローブの詳細はhttp://php.net/manual/features.dtrace.phpを参照してください。

MySQL問合せのプローブであるquery-start(queryconnectioniddatabaseuserhost)およびquery-done(status)は、MySQLサーバーが問合せを受け取るとき、および問合せが完了してサーバーが正常に情報をクライアントに送信したときに起動されます。

たとえば、次のスクリプトは、各データベース問合せの実行時間をレポートします。

#!/usr/sbin/dtrace -qs

dtrace:::BEGIN
{
   printf("%-20s %-10s %-40s %-9s\n", "Who", "Database", "Query", "Time(microseconds)");
}

mysql*:::query-start
{
   self->query = copyinstr(arg0);
   self->connid = arg1;
   self->db    = copyinstr(arg2);
   self->who   = strjoin(copyinstr(arg3),strjoin("@",copyinstr(arg4)));
   self->querystart = timestamp;
}

mysql*:::query-done
{
   printf("%-20s %-10s %-40s %-9d\n",self->who,self->db,self->query,
          (timestamp - self->querystart) / 1000);
}

このスクリプトのサンプル出力を次に示します。

# ./query.d
Who                 Database   Query                                   Time(microseconds)
webuser@localhost   namedb     select * from table1 order by n ASC     1135     
webuser@localhost   namedb     delete from table1 where n='Bill'       10383        

MySQL問合せの解析プローブであるquery-parse-start(query)およびquery-parse-done(status)は、MySQLがSQL文を解析する前と後に即座に起動されます。 たとえば、次のスクリプトを使用して、問合せの解析の実行時間を監視できます。

#!/usr/sbin/dtrace -qs

mysql*:::query-parse-start
{
  self->parsestart = timestamp;
  self->parsequery = copyinstr(arg0);
}

mysql*:::query-parse-done
/arg0 == 0/
{
  printf("Parsing %s: %d microseconds\n", self->parsequery,
    ((timestamp - self->parsestart)/1000));
}

mysql*:::query-parse-done
/arg0 != 0/
{
  printf("Error parsing %s: %d microseconds\n", self->parsequery,
    ((timestamp - self->parsestart)/1000));
}

このスクリプトのサンプル出力を次に示します。

# ./query-parse.d
Parsing select * from table1 where n like 'B%' order by n ASC: 29 microseconds
Error parsing select from table1 join (table2) on (table1.i = table2.i)
    order by table1.s,table1.i limit 10: 36 microseconds

次のスクリプトでは、PHPプローブerror(error_messagerequest_fileline_number)を使用してPHPエラーをレポートします。

#!/usr/sbin/dtrace -qs

php*:::error
{
    printf("PHP error\n");
    printf("  error message             %s\n", copyinstr(arg0));
    printf("  request file              %s\n", copyinstr(arg1));
    printf("  line number               %d\n\n", (int)arg2);
}

たとえば、PHP trigger_error()関数を使用すると、MySQL関数によってエラーが返された場合にPHPエラーを起動できます。

<?php
ini_set('error_reporting', E_ALL); /* Report all errors */
ini_set('display_errors', 'Off');  /* but do not display them */
...
  $mysqli->query($QUERY) or trigger_error($mysqli->error."[$QUERY]",E_USER_ERROR);
...
?>

スクリプトを使用して、不適切な問合せまたはSQLインジェクション攻撃の試みを示す次のようなエラーをレポートできます。

# ./php_error.d
...
PHP error
  error message             You have an error in your SQL syntax; check the manual that
                            corresponds to your MySQL server version for the right syntax
                            to use near '='1'; --'' at line 1[select * from table1 where n 
                            like 'B%' or '1'='1'; --']
  request file              /var/www/html/example.php
  line number               61

...
PHP error
  error message             You have an error in your SQL syntax; check the manual that
                            corresponds to your MySQL server version for the right syntax
                            to use near 'drop table table1; --'' at line 1[select * from
                            table1 where n like 'B%';drop table table1; --']
  request file              /var/www/html/example.php
  line number               61
...