イベントは、サーバーソースコードに追加されたインストゥルメンテーションを使用して収集されます。 インストゥルメントはイベントの時間を測定しますが、これはパフォーマンススキーマがイベントにどれくらいの時間がかかるかを知らせる方法です。 タイミング情報を収集しないようにインストゥルメントを構成することもできます。 このセクションでは、使用可能なタイマーとそれらの特性、およびイベント内のタイミング値を表す方法について説明します。
パフォーマンススキーマタイマーは、精度とオーバーヘッドの量が異なります。 使用可能なタイマーとそれらの特性を確認するには、performance_timers
テーブルをチェックしてください。
mysql> SELECT * FROM performance_schema.performance_timers;
+-------------+-----------------+------------------+----------------+
| TIMER_NAME | TIMER_FREQUENCY | TIMER_RESOLUTION | TIMER_OVERHEAD |
+-------------+-----------------+------------------+----------------+
| CYCLE | 2389029850 | 1 | 72 |
| NANOSECOND | 1000000000 | 1 | 112 |
| MICROSECOND | 1000000 | 1 | 136 |
| MILLISECOND | 1036 | 1 | 168 |
+-------------+-----------------+------------------+----------------+
特定のタイマーに関連付けられた値が NULL
の場合、そのタイマーはプラットフォームでサポートされていません。
カラムの意味は次のとおりです:
TIMER_NAME
カラムには使用可能なタイマーの名前が表示されます。CYCLE
は CPU (プロセッサ) サイクルカウンタに基づいたタイマーを表します。TIMER_FREQUENCY
は、1 秒あたりのタイマー単位数を示します。 サイクルタイマーの場合、頻度は一般に CPU 速度に関連します。 示された値は、2.4GHz プロセッサを搭載するシステムで取得されました。 ほかのタイマーは固定の数秒に基づきます。TIMER_RESOLUTION
は、タイマー値が一度に増加するタイマー単位数を示します。 タイマーの分解能が 10 の場合、その値は毎回 10 ずつ増加します。TIMER_OVERHEAD
は特定のタイマーで 1 つのタイミングを取得するためのオーバーヘッドの最小サイクル数です。 タイマーはイベントの開始と終了で呼び出されるため、イベントあたりのオーバーヘッドは表示される値の 2 倍になります。
パフォーマンススキーマは、次のようにタイマーを割り当てます:
待機タイマーは
CYCLE
を使用します。アイドルタイマー、ステージタイマー、ステートメントタイマーおよびトランザクションタイマーは、
NANOSECOND
タイマーが使用可能なプラットフォームではNANOSECOND
を使用し、それ以外の場合はMICROSECOND
を使用します。
サーバーの起動時に、パフォーマンススキーマは構築時にタイマーの割り当てに関する仮定が正しいことを検証し、タイマーが使用できない場合は警告を表示します。
待機イベントを時間するには、タイマーの精度を犠牲にしてオーバーヘッドを削減することが最も重要な基準であるため、CYCLE
タイマーを使用することをお薦めします。
ステートメント (またはステージ) の実行にかかる時間は、一般に単一の待機の実行にかかる時間より桁違いに大きくなります。 ステートメントの時間を測定するために、もっとも重要な基準は、プロセッサの周波数の変更に影響を受けない正確な測定基準を設定することであるため、サイクルに基づいていないタイマーを使用することがもっとも適切です。 ステートメントのデフォルトのタイマーは NANOSECOND
です。 CYCLE
タイマーと比較すると、余分な「「オーバーヘッド」」は重要ではありません。これは、タイマーのコールによって発生するオーバーヘッド (ステートメントの開始時に一度、終了時に一度) が、ステートメント自体の実行に使用される CPU 時間と比較して大幅に低いためです。 CYCLE
タイマーを使用することにはメリットがなく、欠点だけです。
サイクルカウンタによって提供される精度はプロセッサ速度によって異なります。 プロセッサが 1 GHz (10 億サイクル/秒) 以上で実行する場合、サイクルカウンタはナノ秒未満の精度を実現します。 サイクルカウンタを使用することは、実際の時間を取得するより、はるかに負荷が小さくなります。 たとえば、標準 gettimeofday()
関数は数百サイクルかかる可能性があり、これは 1 秒あたり数千または数百万回発生する可能性のあるデータ収集では、許容できないオーバーヘッドです。
サイクルカウンタには欠点もあります。
エンドユーザーは、何分の 1 秒などの時計の単位でタイミングを知ることを期待します。 サイクルから秒に変換することは大きな負荷がかかる可能性があります。 このため、変換はすばやいかなり概算的な乗算演算です。
ラップトップが節電モードになったときや熱の生成を抑えるために、CPU の速度が低下したときなどに、プロセッササイクルレートが変わることがあります。 プロセッサのサイクルレートが変動した場合、サイクルから実時間単位への変換でエラーが発生することがあります。
サイクルカウンタは、プロセッサやオペレーティングシステムによって、信頼できない場合や使用できない場合があります。 たとえば、Pentium では、命令は
RDTSC
(C 命令ではなくアセンブリ言語) であり、理論上オペレーティングシステムはユーザーモードプログラムのその使用を妨げることができます。異常実行またはマルチプロセッサ同期に関する一部のプロセッサの詳細により、カウンタが最大 1000 サイクルごとに高速になったり、低速になったりするように見えることがあります。
MySQL は、x386 (Windows、macOS、Linux、Solaris、その他の UNIX フレーバ)、PowerPC、IA-64 のサイクルカウンタで動作します。
現在のイベントおよび履歴イベントを格納する「パフォーマンススキーマ」テーブルの行には、タイミング情報をテーブルす 3 つのカラムがあります: TIMER_START
および TIMER_END
はイベントがいつ開始および終了したかを示し、TIMER_WAIT
はイベント期間を示します。
setup_instruments
テーブルにはイベントを収集するインストゥルメントを示す ENABLED
カラムがあります。 このテーブルには、時間が測定されるインストゥルメントを示す TIMED
カラムもあります。 インストゥルメントが有効にされていない場合、イベントを生成しません。 有効にされているインストゥルメントの時間が測定されない場合、インストゥルメントによって生成されたイベントの TIMER_START
、TIMER_END
、および TIMER_WAIT
タイマー値が NULL
になります。 これにより、サマリーテーブルの集計時間値 (合計、最小、最大および平均) の計算時にこれらの値が無視されます。
内部的には、イベント内の時間は、イベントタイミングの開始時に有効なタイマーで指定された単位で格納されます。 イベントが「パフォーマンススキーマ」テーブルから取得されたときに表示されるように、時間はピコ秒 (1 秒に 1 兆) で表示され、選択されているタイマーに関係なく標準単位に正規化されます。
サーバー起動時のパフォーマンススキーマの初期化で、タイマーベースライン (「時間ゼロ」) が発生します。 イベント内の TIMER_START
および TIMER_END
値はベースライン以降のピコ秒を表します。 TIMER_WAIT
値はピコ秒での期間です。
イベント内のピコ秒値は概算です。 それらの精度は、ある単位から別の単位への変換に伴う通常の誤差の形式に左右されます。 CYCLE
タイマーが使われ、プロセッサのレートがさまざまに異なる場合、ドリフトが発生することがあります。 このため、サーバーの起動から経過した時間の正確な測定基準として、イベントの TIMER_START
値を見ることは妥当ではありません。 一方、開始時間や期間によって、イベントを順序付けるために、ORDER BY
句に TIMER_START
値または TIMER_WAIT
値を使用することは適切です。
イベントでマイクロ秒などの値ではなく、ピコ秒を選択したことには、パフォーマンス上の根拠があります。 1 つの実装目標は、タイマーに関係なく、統一された時間単位で結果を表示することでした。 理想の世界では、この時間単位は時計の単位のように見え、適度に正確である、つまりマイクロ秒です。 ただし、サイクルまたはナノ秒をマイクロ秒に変換するには、すべてのインストゥルメンテーションで除算を実行する必要がある場合があります。 除算は多くのプラットフォームで高い負荷がかかります。 乗算は負荷が高くないため、それを使用しています。 そのため、時間単位は、大きな精度の損失がないように十分に大きな乗数を使用した、可能なかぎり最大の TIMER_FREQUENCY
値の整数の倍数です。 その結果、時間単位が「ピコ秒」になります。 この精度は疑似ですが、この決定によりオーバーヘッドを最小にすることができます。
wait、stage、statement、または transaction イベントの実行中、各 current-event テーブルには現在のイベントのタイミング情報が表示されます:
events_waits_current
events_stages_current
events_statements_current
events_transactions_current
完了していないイベントが実行されている期間を判別できるように、タイマーカラムは次のように設定されます:
TIMER_START
が移入されます。TIMER_END
には、現在のタイマー値が移入されます。TIMER_WAIT
には、これまでの経過時間 (TIMER_END
−TIMER_START
) が移入されます。
まだ完了していないイベントの END_EVENT_ID
値は NULL
です。 イベントについてこれまでに経過した時間を評価するには、TIMER_WAIT
カラムを使用します。 したがって、まだ完了しておらず、これまでに N
ピコ秒より長くかかったイベントを識別するために、モニタリングアプリケーションはクエリーで次の式を使用できます:
WHERE END_EVENT_ID IS NULL AND TIMER_WAIT > N
前述のイベント識別では、対応するインストゥルメントの ENABLED
および TIMED
が YES
に設定されており、関連するコンシューマが有効になっていることを前提としています。