草庐IT

有趣的statement stack

GreatSQL 2023-03-28 原文

引子

在使用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社区助手微信好友,发送验证信息加群

)

有关有趣的statement stack的更多相关文章

  1. javascript - addEventListener ("loadedmetadata",有趣)没有正确运行,Firefox 错过事件 - 2

    我写了一个页面,发现addEventListener("loadedmetadata",fun)在firefox上运行不正确我正在尝试修复一个旧软件的错误。在加载视频和页面时,该软件尝试在页面上绘制一些播放器Controller。它在Chrome和IE上运行良好,但无法绘制一些播放器Controller在Firefox上。我尝试调试几天,直到发现问题可以像这样简化:YourbrowserdoesnotsupportHTML5video.varvid=document.getElementById("myVideo");alert("Thevid");vid.addEventListen

  2. javascript - 具有自定义 eval 函数的 Node.js REPL 有趣行为 - 2

    似乎Node.js(版本v0.10.13)返回包裹在(和\n)之间的命令,这是一个最小的例子:require('repl').start({'eval':function(cmd,context,filename,callback){callback(null,cmd);}});行为如下:$noderepl.js>asd'(asd\n)'>这是为什么呢?如果这个特征是documented然后我找不到它。另外,如果这是预期的行为,是否有比cmd=cmd.slice(1,-2);更好的解决方案? 最佳答案 该问题已得到解决(请参阅201

  3. javascript - Babel 的有趣导入 - 2

    因为我知道目前没有浏览器实现ES6模块接口(interface)——但转译器实现了——我用这个简单的例子测试了babelimport{getUsefulContents}from"file.js";getUsefulContents("http://www.example.com",data=>{doSomethingUseful(data);});我只是想看看它是如何转换这些行的。令我惊讶的是,它产生了以下输出:"usestrict";var_fileJs=require("file.js");(0,_fileJs.getUsefulContents)("http://www.exa

  4. javascript - 有趣的 Javascript RegExp 测试 - 2

    这个问题在这里已经有了答案:WhydoesaRegExpwithglobalflaggivewrongresults?(7个答案)关闭7年前。我写了一个JavascriptRegExp测试来检测日期字符串格式,我错误地添加了一个多余的“g”标志,发现了一些有趣的东西。vars="2009/03/10";varregex=/^\d{4}[/]\d{2}[/]\d{2}$/g;alert(regex.test(s));alert(regex.test(s));alert(regex.test(s));alert(regex.test(s));我得到一个“真”,然后是一个“假”,然后是另一个

  5. .net - "Type not expected",使用 DataContractSerializer - 但它只是一个简单的类,没有什么有趣的东西? - 2

    我正在重构我的XML序列化,并认为我会尝试使用DataContractSerializer。一切顺利,直到需要序列化这个类:usingSystem;usingSystem.Runtime.Serialization;namespaceVDB_Sync.Model{[DataContract(Name="Konstant")]publicclassKonstant:DataFelt{[DataMember]privateMySqlDbTypemydataType;[DataMember]privateobjectvalue;publicKonstant(stringnavn,MySqlD

  6. windows - Cygwin 64 位 C 编译器缓存有趣(并且提前结束) - 2

    我们一直在使用CygWin(/usr/bin/x86_64-w64-mingw32-gcc)来生成Windows64位可执行文件,昨天它一直运行良好。今天它以一种奇怪的方式停止工作——它“缓存”标准输出直到程序结束。我写了一个六行的例子那做了同样的事情。由于我们批量使用代码,所以我不会担心,除非我在现在奇怪地缓存的可执行文件上运行测试用例,它会打开输出文件,提前结束,并且不会用数据填充它们。(相同的代码在Linux上运行良好,但这些人使用的是Windows。)我知道这不是华丽的代码,但它证明了我的问题,仅在之后打印数字“12345678910”我按下了键。#includemain(){

  7. c++ - 你能推荐一个有趣的适合新手的驱动程序吗? - 2

    关闭。这个问题不符合StackOverflowguidelines.它目前不接受答案。我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。关闭6个月前。Improvethisquestion我是驱动程序开发的新手,开始寻找有趣的驱动程序相关任务。

  8. c# - 有趣的 Lucene.net 异常 - 2

    根据this或this,我通过多个线程使用相同的索引搜索器。但是当我从FsDirectory切换到MMapDirectory时,我遇到了有趣的异常。这个工作正常:staticvoidMain(string[]args){DirectoryInfodirectoryInfo=newDirectoryInfo(@"C:\Users\Tams\Desktop\new\");vardirectory=FSDirectory.Open(directoryInfo);varindexSearcher=newIndexSearcher(directory);constinttimes=100;con

  9. C# DateTime ToString ("MM-dd-yyyy") 返回有趣的日期值 - 2

    我在ASP.Net页面的代码隐藏文件中有以下代码txtStartDate.Text=DateTime.Today.ToString("MM-dd-yyyy");我希望返回“09-11-2009”。但是,当我在开发服务器上运行该页面时,我在文本框中看到“09-00-2009”。我看不出有任何原因,所以我显然遗漏了一些东西。有人知道吗? 最佳答案 我不明白为什么它会显示00,但作为一个随机建议,您可以尝试:...=DateTime.Today.ToString("MM-dd-yyyy",CultureInfo.InvariantCult

  10. 如何用代码来实现电脑中“病毒”----关机小程序。 代码的有趣应用~ - 2

    1.基本知识shutdown-s-t60-s是设置关机-t是设置时间关机60是60s后关机shutdown-a取消关机可以win+r,输入cmd,进去输入上面的,也可以2.代码实践 3.源码:#define_CRT_SECURE_NO_WARNINGS1#include   //来引入打印函数printf#include //声明生成随机数字的函数rand/system执行系统命令的函数intmain(){   system("shutdown-s-t120");   charinput[20]={0};   while(1)   {      printf("电脑将会在2分钟内关机\n想取消

随机推荐