事件是透過新增至伺服器原始碼的儀器來收集的。儀器會計時事件,這就是 Performance Schema 如何提供事件耗時長度的概念。也可以設定儀器不收集計時資訊。本節討論可用的計時器及其特性,以及計時值在事件中的表示方式。
Performance Schema 計時器的精確度和額外負荷量各不相同。若要查看有哪些可用的計時器及其特性,請查看 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 |
| THREAD_CPU | 339101694 | 1 | 798 |
+-------------+-----------------+------------------+----------------+
如果與指定計時器名稱相關聯的值是 NULL
,則表示您的平台上不支援該計時器。
這些欄位具有下列意義
TIMER_NAME
欄位會顯示可用的計時器名稱。CYCLE
指的是以 CPU (處理器) 週期計數器為基礎的計時器。TIMER_FREQUENCY
指示每秒的計時器單位數。對於週期計時器,頻率通常與 CPU 速度有關。顯示的值是在具有 2.4GHz 處理器的系統上取得的。其他計時器則是以固定的秒數分數為基礎。TIMER_RESOLUTION
指示計時器值一次增加的計時器單位數。如果計時器的解析度為 10,則其值每次會增加 10。TIMER_OVERHEAD
是使用指定計時器取得一次計時的最小週期額外負荷數。每個事件的額外負荷是顯示值的兩倍,因為計時器是在事件開始和結束時叫用的。
Performance Schema 會依下列方式指派計時器
等候計時器使用
CYCLE
。閒置、階段、陳述式和交易計時器在
NANOSECOND
計時器可用的平台上使用NANOSECOND
,否則使用MICROSECOND
。
在伺服器啟動時,Performance Schema 會驗證在建置期間對計時器指派所做的假設是否正確,如果計時器不可用,則會顯示警告。
若要計時等候事件,最重要的準則是減少額外負荷,可能會犧牲計時器的精確度,因此使用 CYCLE
計時器是最佳選擇。
一個陳述式(或階段)的執行時間通常比單次等待的執行時間大幾個數量級。要測量陳述式的時間,最重要的標準是要有一個精確的測量值,不會受到處理器頻率變化的影響,因此最好使用非基於週期的計時器。陳述式的預設計時器是 NANOSECOND
。相較於 CYCLE
計時器,額外的 “開銷” 並不顯著,因為呼叫計時器兩次(陳述式開始時一次,結束時一次)所造成的開銷,與執行陳述式本身所使用的 CPU 時間相比,小了幾個數量級。在這裡使用 CYCLE
計時器沒有任何好處,只有缺點。
週期計數器提供的精確度取決於處理器速度。如果處理器以 1 GHz(每秒十億個週期)或更高的速度運行,週期計數器可以提供亞奈秒級的精確度。使用週期計數器比取得實際日期時間便宜得多。例如,標準的 gettimeofday()
函式可能需要數百個週期,這對於可能每秒發生數千或數百萬次資料收集來說,是一個無法接受的開銷。
週期計數器也有缺點
終端使用者期望看到以實際時間單位(例如秒的分數)表示的時間。將週期轉換為秒的分數可能很耗費資源。因此,轉換是一個快速且相當粗略的乘法運算。
處理器週期速率可能會改變,例如當筆記型電腦進入省電模式或 CPU 為了減少熱量產生而降低速度時。如果處理器的週期速率波動,則從週期轉換為實際時間單位可能會產生誤差。
週期計數器可能會不可靠或不可用,具體取決於處理器或作業系統。例如,在 Pentium 上,指令是
RDTSC
(一個組合語言而非 C 語言指令),理論上作業系統可以阻止使用者模式程式使用它。一些與亂序執行或多處理器同步相關的處理器細節可能會導致計數器看起來快或慢高達 1000 個週期。
MySQL 在 x386(Windows、macOS、Linux、Solaris 和其他 Unix 風格的系統)、PowerPC 和 IA-64 上使用週期計數器。
效能架構表中儲存目前事件和歷史事件的列具有三個欄位來表示計時資訊:TIMER_START
和 TIMER_END
表示事件開始和結束的時間,而 TIMER_WAIT
表示事件持續時間。
setup_instruments
表格有一個 ENABLED
欄位來指示要收集哪些工具的事件。該表格還有一個 TIMED
欄位來指示哪些工具要計時。如果一個工具未啟用,則它不會產生任何事件。如果一個啟用的工具沒有計時,則該工具產生的事件的 TIMER_START
、TIMER_END
和 TIMER_WAIT
計時器值會是 NULL
。這反過來會導致在計算摘要表格中的總計時間值(總和、最小值、最大值和平均值)時忽略這些值。
在內部,事件中的時間以事件計時開始時生效的計時器給定的單位儲存。為了在從效能架構表格檢索事件時顯示,時間以皮秒(秒的萬億分之一)顯示,以將它們標準化為標準單位,而不管選擇哪個計時器。
計時器基準線(“時間零點”)發生在伺服器啟動期間的效能架構初始化時。事件中的 TIMER_START
和 TIMER_END
值表示自基準線以來的皮秒數。TIMER_WAIT
值是以皮秒為單位的持續時間。
事件中的皮秒值是近似值。它們的準確性會受到從一個單位轉換為另一個單位時常見的誤差形式的影響。如果使用 CYCLE
計時器且處理器速率發生變化,則可能會出現漂移。由於這些原因,將事件的 TIMER_START
值視為自伺服器啟動以來經過的時間的準確測量值是不合理的。另一方面,在 ORDER BY
子句中使用 TIMER_START
或 TIMER_WAIT
值來按開始時間或持續時間對事件進行排序是合理的。
在事件中選擇皮秒而不是微秒之類的值具有效能基礎。一個實作目標是以統一的時間單位顯示結果,而不管計時器為何。在理想的情況下,這個時間單位看起來像一個實際時間單位並且相當精確;換句話說,就是微秒。但是,要將週期或奈秒轉換為微秒,有必要對每個儀器執行除法。在許多平台上,除法很耗費資源。乘法並不耗費資源,因此這是所使用的方法。因此,時間單位是最高可能的 TIMER_FREQUENCY
值的整數倍,使用足夠大的乘數以確保不會有重大的精度損失。結果是時間單位是 “皮秒。” 這種精度是虛假的,但此決定能夠將開銷降至最低。
當等待、階段、陳述式或交易事件正在執行時,各自的目前事件表格會顯示目前事件的計時資訊
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
,並且已啟用相關的使用者。