事件是透過新增至伺服器原始碼的儀器來收集的。儀器會對事件進行計時,這也是 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(每秒 10 億個週期)或更高的速度運行,則週期計數器可提供亞奈秒級的精確度。使用週期計數器比獲取實際日期時間便宜得多。例如,標準的 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
,並且相關的消費者已啟用。