引子
在使用events_statements_current的程序中發現,同一執行緒在同一時刻,可能有多條記錄,與直觀感覺不太一樣,于是跟蹤了一下內部實作,有了本文,
STATEMENT STACK的定義
STATEMENT STACK 是events_statements_current表被后用于存盤當前會話執行陳述句堆疊的資料結構,
在MySQL8中,相關定義如下:
/** Max size of the statements stack. */
uint statement_stack_max;
/** nested statement lost */
uint nested_statement_lost;
struct PFS_ALIGNED PFS_thread : PFS_connection_slice {
//...
/** Size of @c m_events_statements_stack. */
uint m_events_statements_count;
PFS_events_statements *m_statement_stack;
//...
}
其中:
- m_statement_stack 陳述句堆疊
- m_events_statements_count 陳述句堆疊堆疊頂指標
- statement_stack_max 存盤允許存盤的最大陳述句數量
- nested_statement_lost 存盤丟失的陳述句數量
STATEMENT STACK相關小實驗
1) 創建測驗存盤程序
存盤程序的功能主要是:人為等待10秒左右
-- 保存為:stat_stack.sql
USE d1;
set sql_mode=oracle;
set global log_bin_trust_function_creators = 1;
DELIMITER $$
CREATE OR REPLACE PROCEDURE p1(a INT DEFAULT 1)
AS
BEGIN
SELECT a, SLEEP(a);
END$$
CALL p1(10);
2) 啟動終端1輸入命令:
USE PERFORMANCE_SCHEMA;
-- 確認采集打開
UPDATE setup_consumers SET ENABLED='YES' WHERE name = 'events_statements_current';
-- Query OK, 0 rows affected (0.00 sec)
-- Rows matched: 1 Changed: 1 Warnings: 0
-- 查詢當前終端執行緒ID
SELECT thread_id FROM threads WHERE processlist_id=CONNECTION_ID() \G
-- thread_id: 58
-- 1 row in set (0.00 sec)
-- 查詢當前活躍陳述句,驗證環境
SELECT sql_text FROM events_statements_current WHERE thread_id = 58 \G
-- sql_text: SELECT * FROM events_statements_current WHERE thread_id = 58
-- 1 row in set (0.00 sec)
3) 啟動終端2輸入命令:
USE PERFORMANCE_SCHEMA;
-- 查詢當前終端的thread_id
SELECT THREAD_ID FROM THREADS WHERE PROCESS_LIST_ID=CONNECTION_ID() \G
thread_id: 58
1 row in set (0.00 sec)
source stmt_stack.sql
+------+----------+
| a | SLEEP(a) |
+------+----------+
| 10| 0 |
+------+----------+
1 row in set (10.01 sec)
Query OK, 0 rows affected (10.01 sec)
4) 切換終端1輸入命令:
USE PERFORMANCE_SCHEMA;
mysql> SELECT sql_text FROM events_statements_current WHERE thread_id = 58;
+--------------------+
| sql_text |
+--------------------+
| CALL p1(10) |
| SELECT a, SLEEP(a) |
+--------------------+
2 rows in set (0.01 sec)
mysql> SELECT sql_text FROM events_statements_current WHERE thread_id = 58;
+-------------+
| sql_text |
+-------------+
| CALL p1(10) |
+-------------+
1 row in set (0.00 sec)
注意:58是查到的內部執行緒號
結論:
可以看到:陳述句以及內嵌陳述句都被STATEMENT STACK捕獲,同一時刻,同個會話,多條陳述句,
STATEMENT STACK如何更新
計數器增加
pfs_get_thread_statement_locker_v2
計數器減少
pfs_end_statement_v2
限制與擴展說明
- 默認情況下: statement_stack_max = 10
- 當陳述句嵌套層級大于: statement_stack_max 的時候,嵌套的陳述句就不會記錄了,全域變數: nested_statement_lost會被更新
- 通過陳述句'show global status like "%performance_schema_nested_statement_lost%";' 可以查詢丟失陳述句的數量
Enjoy GreatSQL ??
關于 GreatSQL
GreatSQL是由萬里資料庫維護的MySQL分支,專注于提升MGR可靠性及性能,支持InnoDB并行查詢特性,是適用于金融級應用的MySQL分支版本,
相關鏈接: GreatSQL社區 Gitee GitHub Bilibili
GreatSQL社區:
捉蟲活動詳情:https://greatsql.cn/thread-97-1-1.html
社區博客有獎征稿詳情:https://greatsql.cn/thread-100-1-1.html

技術交流群:
微信:掃碼添加
GreatSQL社區助手微信好友,發送驗證資訊加群,
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/535277.html
標籤:其他
上一篇:MongoDB - 增刪改查
