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 *
會剖析但會因未使用任何表格
錯誤而失敗。在這種情況下,會使用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
)彙總統計資料,因為沒有任何語句會使用抽象工具作為最終語句名稱進行分類。