MySQL 5.6.3 現在、パフォーマンススキーマはステートメント実行をインストゥルメントします。ステートイベントイベントはイベント階層の高いレベルで発生します。待機イベントはステージイベント内にネストし、ステージイベントはステートメントイベント内にネストします。
これらのテーブルはステートメントイベントを格納します。
events_statements_current
: 現在のステートメントイベントevents_statements_history
: 各スレッドの最新のステートメントイベントevents_statements_history_long
: 全体の最新のステートメントイベント
次のセクションでそれらのテーブルについて説明します。ステートメントイベントに関する情報を集計するサマリーテーブルもあります。セクション22.9.9.3「ステートメントサマリーテーブル」を参照してください。
ステートメントイベント構成
ステートメントイベントの収集を有効にするには、関連インストゥルメントとコンシューマを有効にします。
setup_instruments
テーブルには、statement
で始まる名前を持つインストゥルメントが格納されます。これらのインストゥルメントはデフォルトで有効にされています。
mysql> SELECT * FROM setup_instruments WHERE NAME LIKE 'statement/%';
+---------------------------------------------+---------+-------+
| NAME | ENABLED | TIMED |
+---------------------------------------------+---------+-------+
| statement/sql/select | YES | YES |
| statement/sql/create_table | YES | YES |
| statement/sql/create_index | YES | YES |
...
| statement/sp/stmt | YES | YES |
| statement/sp/set | YES | YES |
| statement/sp/set_trigger_field | YES | YES |
| statement/scheduler/event | YES | YES |
| statement/com/Sleep | YES | YES |
| statement/com/Quit | YES | YES |
| statement/com/Init DB | YES | YES |
...
| statement/abstract/Query | YES | YES |
| statement/abstract/new_packet | YES | YES |
| statement/abstract/relay_log | YES | YES |
+---------------------------------------------+---------+-------+
ステートメントイベントの収集を変更するには、関連インストゥルメントの ENABLED
および TIMING
カラムを変更します。例:
mysql> UPDATE setup_instruments SET ENABLED = 'NO'
-> WHERE NAME LIKE 'statement/com/%';
setup_consumers
テーブルには現在および最近のステートメントイベントテーブル名に対応する名前を持つコンシューマ値とステートメントダイジェストコンシューマが格納されます。これらのコンシューマはステートメントイベントのコレクションとステートメントダイジェストをフィルタ処理するために使用できます。events_statements_current
と statements_digest
のみがデフォルトで有効にされています。
mysql> SELECT * FROM setup_consumers WHERE NAME LIKE '%statements%';
+--------------------------------+---------+
| NAME | ENABLED |
+--------------------------------+---------+
| events_statements_current | YES |
| events_statements_history | NO |
| events_statements_history_long | NO |
| statements_digest | YES |
+--------------------------------+---------+
すべてのステートメントコンシューマを有効にするには、次を実行します。
mysql> UPDATE setup_consumers SET ENABLED = 'YES'
-> WHERE NAME LIKE '%statements%';
setup_timers
テーブルには、ステートメントイベントのタイミングの単位を示す statement
の NAME
値のある行が格納されます。デフォルトの単位は NANOSECOND
です。
mysql> SELECT * FROM setup_timers WHERE NAME = 'statement';
+-----------+------------+
| NAME | TIMER_NAME |
+-----------+------------+
| statement | NANOSECOND |
+-----------+------------+
タイミングの単位を変更するには、TIMER_NAME
値を変更します。
mysql> UPDATE setup_timers SET TIMER_NAME = 'MICROSECOND'
-> WHERE NAME = 'statement';
イベント収集の構成に関する追加情報については、セクション22.2「パフォーマンススキーマ構成」を参照してください。
ステートメントモニタリング
ステートメントのモニタリングは、サーバーがスレッドに対してアクティビティーがリクエストされていることを確認した時点から、すべてのアクティビティーが終了した時点までに開始されます。一般に、これはサーバーがクライアントから最初のパケットを受け取ったときから、サーバーが応答の送信を終了したときまでを意味します。モニタリングは、トップレベルステートメントに対してのみ行われます。ストアドプログラムとサブクエリー内のステートメントは別々に見られません。
パフォーマンススキーマがリクエスト (サーバーコマンドまたは SQL ステートメント) をインストゥルメントする場合、最終的なインストゥルメント名に到達するまで、より一般的 (または「抽象的」) から、より具体的へと段階を追って進むインストゥルメント名を使用します。
最終インストゥルメント名はサーバーコマンドと SQL ステートメントに対応します。
サーバーコマンドは
mysql_com.h
ヘッダーファイルに定義され、sql/sql_parse.cc
で処理されるCOM_
に対応します。例はxxx
codesCOM_PING
とCOM_QUIT
です。コマンドのインストゥルメントは、statement/com/Ping
やstatement/com/Quit
などのstatement/com
から始まる名前を持ちます。SQL ステートメントは
DELETE FROM t1
またはSELECT * FROM t2
などのテキストとして表されます。SQL ステートメントのインストゥルメントは、statement/sql/delete
やstatement/sql/select
などのstatement/sql
から始まる名前を持ちます。
いくつかの最終インストゥルメント名はエラー処理に固有です。
statement/com/Error
は帯域外のサーバーによって受信されたメッセージから構成されます。これはサーバーが理解しないクライアントによって送信されたコマンドを検出するために使用できます。これは、構成が誤っているか、サーバーよりも新しい MySQL のバージョンを使用しているクライアントや、サーバーへの攻撃を試みているクライアントの識別などの目的で役に立つことがあります。statement/sql/error
は解析に失敗した SQL ステートメントから構成されます。これはクライアントによって送信された不正な形式のクエリーを検出するために使用できます。解析に失敗するクエリーは、解析するが、実行中のエラーのために失敗するクエリーと異なります。たとえば、SELECT * FROM
は不正な形式で、statement/sql/error
インストゥルメントが使用されます。対照的にSELECT *
は解析しますが、「表が指定されていません」
エラーを伴って失敗します。この場合、statement/sql/select
が使用され、ステートメントイベントにはエラーの性質を示す情報が含まれます。
リクエストはこれらの任意のソースから取得できます。
リクエストをパケットとして送信するクライアントからのコマンドまたはステートメントリクエストとして
レプリケーションスレーブ上のリレーログから読み取られたステートメント文字列として (MySQL 5.6.13 以降)
リクエストの詳細は最初は不明で、パフォーマンススキーマはリクエストのソースに依存する順序で、抽象から特定のインストゥルメント名に進みます。
クライアントから受信したリクエストの場合:
サーバーがソケットレベルで新しいパケットを検出すると、新しいステートメントが
statement/abstract/new_packet
の抽象インストゥルメント名で開始されます。サーバーはパケット番号を読み取ると、受信したリクエストの種類について詳しく知り、パフォーマンススキーマがインストゥルメント名を絞り込みます。たとえば、リクエストが
COM_PING
パケットの場合、インストゥルメント名はstatement/com/Ping
になり、それが最終名になります。リクエストがCOM_QUERY
パケットの場合、それは SQL ステートメントに対応するが、特定のステートメントの種類ではないことがわかります。この場合、インストゥルメントはある抽象名から、やや具体的だが、まだ抽象名であるstatement/abstract/Query
に変更され、リクエストはさらに分類する必要があります。リクエストがステートメントである場合、ステートメントテキストが読み取られ、パーサーに提供されます。解析後、正確なステートメントの種類が認識されます。リクエストがたとえば
INSERT
ステートメントの場合、パフォーマンススキーマはインストゥルメント名をstatement/abstract/Query
から最終名であるstatement/sql/insert
に絞り込みます。
レプリケーションスレーブ上のリレーログからステートメントとして読み取られるリクエストの場合:
リレーログ内のステートメントはテキストとして保存され、そのように読み取られます。ネットワークプロトコルはないため、
statement/abstract/new_packet
インストゥルメントは使用されません。代わりに、初期インストゥルメントはstatement/abstract/relay_log
になります。ステートメントが解析されると、正確なステートメントの種類が認識されます。リクエストがたとえば
INSERT
ステートメントの場合、パフォーマンススキーマはインストゥルメント名をstatement/abstract/Query
から最終名であるstatement/sql/insert
に絞り込みます。
先述の説明はステートメントベースのレプリケーションにのみ適用されます。行ベースのレプリケーションでは、行の変更を処理しながら、スレーブで実行されるテーブル I/O をインストゥルメントできますが、リレーログ内の行イベントは、個別のステートメントとして表示されません。
ステートメントに対して収集される統計の場合、各ステートメントの種類に使用される最終 statement/sql/*
インストゥルメントを有効にするだけでは十分ではありません。抽象 statement/abstract/*
インストゥルメントも有効にする必要があります。すべてのステートメントインストゥルメントがデフォルトで有効にされるため、これは通常問題にならないはずです。ただし、ステートメントインストゥルメントを選択して有効または無効にするアプリケーションは、抽象インストゥルメントを無効にすると、個々のステートメントインストゥルメントの統計収集も無効になることを考慮する必要があります。たとえば、INSERT
ステートメントの統計を収集するには、statement/sql/insert
を有効にする必要がありますが、statement/abstract/new_packet
と statement/abstract/Query
も有効にする必要があります。同様に、レプリケートされたステートメントをインストゥルメントするには、statement/abstract/relay_log
が有効にされている必要があります。
ステートメントが最終ステートメント名として抽象インストゥルメントに分類されることはないため、statement/abstract/Query
などの抽象インストゥルメントに対して統計は集計されません。
先述の説明の抽象インストゥルメント名は MySQL 5.6.15 現在です。5.6 より前では、それらの名前が決定されるまでに、いくらかの名前の変更がありました。
MySQL 5.6.14 では
statement/abstract/new_packet
はstatement/com/
で、MySQL 5.6.13 ではstatement/com/new_packet
で、それ以前はstatement/com/
でした。MySQL 5.6.15 より前では、
statement/abstract/Query
はstatement/com/Query
でした。MySQL 5.6.13 から 5.6.14 では
statement/abstract/relay_log
はstatement/rpl/relay_log
で、それより前は存在していませんでした。