在使用events_statements_current的过程中发现,同一线程在同一时刻,可能有多条记录,与直观感觉不太一样,于是跟踪了一下内部实现,有了本文。
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;
//...
}
其中:
存储过程的功能主要是:人为等待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);
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)
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)
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捕获,同一时刻,同个会话,多条语句。
pfs_get_thread_statement_locker_v2
pfs_end_statement_v2
Enjoy GreatSQL :)
GreatSQL是由万里数据库维护的MySQL分支,专注于提升MGR可靠性及性能,支持InnoDB并行查询特性,是适用于金融级应用的MySQL分支版本。
相关链接: GreatSQL社区 Gitee GitHub Bilibili
捉虫活动详情:https://greatsql.cn/thread-97-1-1.html
社区博客有奖征稿详情:https://greatsql.cn/thread-100-1-1.html