Performance Schema 會檢測語句執行。語句事件發生在事件階層的較高層級。在事件階層中,等候事件會巢狀在階段事件內,而階段事件會巢狀在語句事件內,而語句事件會巢狀在交易事件內。
這些表格會儲存語句事件
events_statements_current
:每個執行緒的目前語句事件。events_statements_history
:每個執行緒已結束的最新語句事件。events_statements_history_long
:已在全域(跨所有執行緒)結束的最新語句事件。prepared_statements_instances
:預備語句執行個體和統計資訊
以下章節將說明語句事件表格。還有摘要表格會彙總關於語句事件的資訊;請參閱第 29.12.20.3 節, 「語句摘要表格」。
如需關於三個 events_statements_
事件表格之間關聯的詳細資訊,請參閱第 29.9 節, 「Performance Schema 用於目前和歷史事件的表格」。xxx
設定語句事件收集
若要控制是否收集語句事件,請設定相關儀器和消費者的狀態
setup_instruments
表格包含名稱開頭為statement
的儀器。使用這些儀器來啟用或停用個別語句事件類別的收集。setup_consumers
表格包含與目前和歷史語句事件表格名稱,以及語句摘要消費者對應的消費者值。使用這些消費者來篩選語句事件和語句摘要的收集。
語句儀器預設為啟用,且 events_statements_current
、events_statements_history
和 statements_digest
語句消費者預設為啟用
mysql> SELECT NAME, ENABLED, TIMED
FROM performance_schema.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 |
+---------------------------------------------+---------+-------+
mysql> SELECT *
FROM performance_schema.setup_consumers
WHERE NAME LIKE '%statements%';
+--------------------------------+---------+
| NAME | ENABLED |
+--------------------------------+---------+
| events_statements_current | YES |
| events_statements_history | YES |
| events_statements_history_long | NO |
| statements_digest | YES |
+--------------------------------+---------+
若要在伺服器啟動時控制語句事件收集,請在您的 my.cnf
檔案中使用類似以下的行
啟用
[mysqld] performance-schema-instrument='statement/%=ON' performance-schema-consumer-events-statements-current=ON performance-schema-consumer-events-statements-history=ON performance-schema-consumer-events-statements-history-long=ON performance-schema-consumer-statements-digest=ON
停用
[mysqld] performance-schema-instrument='statement/%=OFF' performance-schema-consumer-events-statements-current=OFF performance-schema-consumer-events-statements-history=OFF performance-schema-consumer-events-statements-history-long=OFF performance-schema-consumer-statements-digest=OFF
若要在執行時間控制語句事件收集,請更新 setup_instruments
和 setup_consumers
表格
啟用
UPDATE performance_schema.setup_instruments SET ENABLED = 'YES', TIMED = 'YES' WHERE NAME LIKE 'statement/%'; UPDATE performance_schema.setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE '%statements%';
停用
UPDATE performance_schema.setup_instruments SET ENABLED = 'NO', TIMED = 'NO' WHERE NAME LIKE 'statement/%'; UPDATE performance_schema.setup_consumers SET ENABLED = 'NO' WHERE NAME LIKE '%statements%';
若要僅收集特定語句事件,請僅啟用對應的語句儀器。若要僅針對特定語句事件表格收集語句事件,請啟用語句儀器,但僅啟用與所需表格對應的語句消費者。
關於設定事件收集的更多資訊,請參閱第 29.3 節「效能架構啟動設定」和第 29.4 節「效能架構執行階段設定」。
陳述式監控
陳述式監控從伺服器看到在執行緒上請求活動的那一刻開始,到所有活動停止的那一刻結束。通常,這表示從伺服器收到來自用戶端的第一個封包時,到伺服器完成傳送回應時。儲存程式內的陳述式會像其他陳述式一樣受到監控。
當效能架構檢測請求(伺服器命令或 SQL 陳述式)時,它會使用從更一般(或「抽象」)到更具體階段的方式來進行檢測名稱,直到到達最終的檢測名稱。
最終的檢測名稱對應於伺服器命令和 SQL 陳述式。
伺服器命令對應於在
mysql_com.h
標頭檔案中定義並在sql/sql_parse.cc
中處理的COM_
。例如xxx
程式碼COM_PING
和COM_QUIT
。命令的檢測名稱以statement/com
開頭,例如statement/com/Ping
和statement/com/Quit
。SQL 陳述式以文字表示,例如
DELETE FROM t1
或SELECT * FROM t2
。SQL 陳述式的檢測名稱以statement/sql
開頭,例如statement/sql/delete
和statement/sql/select
。
某些最終的檢測名稱是針對錯誤處理的。
statement/com/Error
用於記錄伺服器接收到的帶外訊息。它可以偵測用戶端傳送但伺服器無法理解的命令。這可能對以下目的有幫助:識別組態錯誤或使用比伺服器更新版本的 MySQL 用戶端,或嘗試攻擊伺服器的用戶端。statement/sql/error
用於記錄無法剖析的 SQL 陳述式。它可以偵測用戶端傳送的格式不正確的查詢。無法剖析的查詢與剖析成功但由於執行期間發生錯誤而失敗的查詢不同。例如,SELECT * FROM
是格式不正確,並使用statement/sql/error
檢測。相反地,SELECT *
會剖析成功,但會因No tables used
錯誤而失敗。在這種情況下,會使用statement/sql/select
,並且陳述式事件包含資訊來指出錯誤的性質。
可以從以下任何來源取得請求:
來自用戶端的命令或陳述式請求,用戶端會以封包形式傳送請求
從複本上的中繼日誌讀取的陳述式字串
來自事件排程器的事件
請求的詳細資訊一開始是未知的,效能架構會按照取決於請求來源的順序,從抽象到具體的檢測名稱進行。
對於從用戶端收到的請求:
當伺服器在通訊端層級偵測到新的封包時,會使用
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/scheduler/event
進行檢測。這是最終名稱。
在事件主體內執行的陳述式會使用 statement/sql/*
名稱進行檢測,而不會使用任何先前的抽象檢測。事件是儲存程式,而且儲存程式在執行之前會預先編譯到記憶體中。因此,執行階段沒有剖析,而且在執行時知道每個陳述式的類型。
在事件主體內執行的陳述式是子陳述式。例如,如果事件執行 INSERT
陳述式,則事件本身的執行是父系,使用 statement/scheduler/event
進行檢測,而 INSERT
是子系,使用 statement/sql/insert
進行檢測。父/子關係存在於不同的檢測作業之間。這與單一檢測作業內發生的精簡順序不同,後者是從抽象到最終的檢測名稱。
若要收集陳述式的統計資料,只啟用個別陳述式類型所使用的最終 statement/sql/*
檢測是不夠的。也必須啟用抽象 statement/abstract/*
檢測。這通常不應該是問題,因為預設會啟用所有陳述式檢測。但是,選擇性地啟用或停用陳述式檢測的應用程式必須考慮到,停用抽象檢測也會停用個別陳述式檢測的統計資料收集。例如,若要收集 INSERT
陳述式的統計資料,必須啟用 statement/sql/insert
,以及 statement/abstract/new_packet
和 statement/abstract/Query
。同樣地,若要檢測複寫的陳述式,必須啟用 statement/abstract/relay_log
。
不會針對抽象檢測(例如 statement/abstract/Query
)彙總任何統計資料,因為沒有任何陳述式會以抽象檢測作為最終陳述式名稱進行分類。