Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >GreatSQL的sp中添加新的sp_instr引入的bug解析

GreatSQL的sp中添加新的sp_instr引入的bug解析

作者头像
GreatSQL社区
发布于 2024-05-11 09:52:44
发布于 2024-05-11 09:52:44
1290
举报

* GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。 一、问题发现 在一次开发中用到的sp需要添加新的sp_instr以满足需求,但是添加了数个sp_instr以后发现执行新的sp会发生core。 注:本次使用的GreatSQL 8.0.32-25 1、sp_head.cc的init_sp_psi_keys()代码里面添加10个新的sp_instr: void init_sp_psi_keys() { mysql_statement_register(category, &sp_instr_stmt1::psi_info, 1); mysql_statement_register(category, &sp_instr_stmt2::psi_info, 1); mysql_statement_register(category, &sp_instr_stmt3::psi_info, 1); ...... mysql_statement_register(category, &sp_instr_stmt10::psi_info, 1); } 2、sp_instr.cc里面添加新的sp_instr_stmt相关实现代码,其中sql_yacc.yy和sql_lex.cc需要相应添加新的语法。 3、sp_rcontext.h处在·class sp_rcontext里面添加几个新的成员变量。下面代码只是示例,不具有实际使用价值。 Field *m_return_value_fld_tmp{m_return_value_fld}; Field *m_return_value_fld_tmp1{m_return_value_fld}; Field *m_return_value_fld_tmp2{m_return_value_fld}; 4、创建新的sp,里面包含新的sp_instr_stmt的内容,然后call该sp,结果发现代码逻辑处因为一个list里面member的值被清空了,然后导致crash。下面是相关的堆栈。因为涉及代码机密,只截图开源部分相关堆栈。 #0 0x0000555558f3f3d9 in base_list_iterator::next_fast (this=0x7fffe01e9de0) at /sql/sql_list.h:371 #1 0x0000555558fc59b7 in List_iterator_fast<Create_field>::operator++ (this=0x7fffe01e9de0) at /sql/sql_list.h:605 #2 0x0000555559753ea2 in create_tmp_table_from_fields (thd=0x7fff20001050, field_list=..., is_virtual=false, select_options=0, alias=0x0) at /sql/sql_tmp_table.cc:2131 #3 0x0000555559084a09 in Item_xx::val_str (this=0x7fff20b673c8) at /sql/item_func.cc:10796 #4 0x0000555558fa408b in Item::save_in_field_inner (this=0x7fff20b673c8, field=0x7fff20b9b1a8, no_conversions=false) at /sql/item.cc:8202 #5 0x0000555558fa3c43 in Item::save_in_field (this=0x7fff20b673c8, field=0x7fff20b9b1a8, no_conversions=false) at /sql/item.cc:8144 #6 0x0000555559400322 in sp_eval_expr (thd=0x7fff20001050, result_field=0x7fff20b9b1a8, expr_item_ptr=0x7fff20b67620) at /sql/sp.cc:3613 #7 0x000055555943b1d1 in sp_rcontext::set_variable (this=0x7fff20b85d80, thd=0x7fff20001050, field=0x7fff20b9b1a8, value=0x7fff20b67620) at /sql/sp_rcontext.cc:1023 #8 0x0000555558fc3a8e in sp_rcontext::set_variable (this=0x7fff20b85d80, thd=0x7fff20001050, var_idx=1, value=0x7fff20b67620) at /sql/sp_rcontext.h:176 打印crash处的信息,发现list里面的值被清空了。 (gdb) p tmp $1 = (list_node *) 0x0 二、问题调查过程 1、仔细检查代码发现代码逻辑没有问题,list的值确实都有成功赋值,但是运行时候却发现list被清空,显然这是别的地方内存泄漏或者内存溢出导致list的元素空间被占用了或者被清空了。把sp的代码换成别的,有时候会crash有时候不会crash,触发机制也不明朗,不知道具体哪句代码导致的内存泄漏。 2、于是回头继续看刚开始添加代码的地方,猜想是不是跟我添加了10个sp_instr_stmt有关,因为相关的数组或者内存没有添加扩容,很有可能因为这个导致内存溢出。 3、定位出疑似问题地方,就可以着手开始调查相关代码了。查看相关添加sp_instr的代码。 添加sp_instr实现代码如下: mysql_statement_register(category, &sp_instr_stmt1::psi_info, 1); 于是继续往下面调查mysql_statement_register实现的代码, 看到这里果然用到了statement_class_max: PFS_statement_key register_statement_class(const char *name, uint name_length, PSI_statement_info *info) { /* See comments in register_mutex_class */ uint32 index; PFS_statement_class *entry; REGISTER_CLASS_BODY_PART(index, statement_class_array, statement_class_max, name, name_length) 接着查看statement_class_max的赋值的地方: int init_statement_class(uint statement_class_sizing) { int result = 0; statement_class_dirty_count = statement_class_allocated_count = 0; statement_class_max = statement_class_sizing; 通过搜索代码查到statement_class_sizing相关的参数配置的地方, 看到这里有一个SP_PSI_STATEMENT_INFO_COUNT宏定义,这个值跟sp_instr的数量有关。 static Sys_var_ulong Sys_pfs_max_statement_classes( "performance_schema_max_statement_classes", "Maximum number of statement instruments.", READ_ONLY GLOBAL_VAR(pfs_param.m_statement_class_sizing), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 256), DEFAULT((ulong)SQLCOM_END + (ulong)COM_END + 5 + SP_PSI_STATEMENT_INFO_COUNT + CLONE_PSI_STATEMENT_COUNT), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES); 继续全文搜索,发现在sp_head.h定义了,这里的值为16, 数了一下现存的sp_instr个数刚好为16个,至此问题原因发现, 因为我加了10个sp_instr,而这个宏定义的值没有跟着增加,导致内存溢出。 #define SP_PSI_STATEMENT_INFO_COUNT 16 三、问题解决方案 通过以上代码解析后,就可以修改相关问题代码,只要作如下修改即可。重新编译完,问题解决。 sp_head.h修改SP_PSI_STATEMENT_INFO_COUNT宏定义(这里的26=16+10): #define SP_PSI_STATEMENT_INFO_COUNT 26 因为增加了Sys_pfs_max_statement_classes的default值, 因此相关配置范围也要跟着增加,因此把range相应加大。 static Sys_var_ulong Sys_pfs_max_statement_classes( "performance_schema_max_statement_classes", "Maximum number of statement instruments.", READ_ONLY GLOBAL_VAR(pfs_param.m_statement_class_sizing), CMD_LINE(REQUIRED_ARG), VALID_RANGE(0, 256 * 2), DEFAULT((ulong)SQLCOM_END + (ulong)COM_END + 5 + SP_PSI_STATEMENT_INFO_COUNT + CLONE_PSI_STATEMENT_COUNT), BLOCK_SIZE(1), PFS_TRAILING_PROPERTIES); 四、问题总结 在GreatSQL的sp添加新的sp_instr需要相应增加对应的参数值以防止内存溢出,如果其他的功能也要做类似的修改,也要先仔细调查一下有没有涉及相关的参数配置或者宏定义,不然就会遇到各种莫名其妙的问题,调查起来也很花时间。 这次发现的问题属于新添加功能带入的bug,在实际开发应用中类似的问题也要注意,一不小心就会踩坑。 上述问题在MySQL/Percona中同样存在。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-05-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 GreatSQL社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
MySQL的match函数在sp中使用的BUG解析
在一次开发中在sp中使用MySQL PREPARE以后,使用match AGAINST语句作为prepare stmt的参数后,发现执行第二遍call会导致数据库crash,于是开始动手调查问题发生的原因。
GreatSQL社区
2023/08/11
2790
MySQL的match函数在sp中使用的BUG解析
MySQL中sp运行check表版本更新流程解析
MySQL的sp运行SQL语句需要执行2个步骤:prepare和execute。第一次执行的时候先执行prepare,进行相关语句parse、itemize、fix_fields等操作,然后才开始进行execute操作。等第二次再执行该sp的时候就直接运行execute而不需要再次进行重复的prepare操作,这样可以节省sp运行时候重复prepare的开销。但是,对于表操作就有一个问题产生,那就是如果执行第二遍的时候表的结构发生改变了,那么不进行reprepare而直接execute是会发生错误的。因此,本文章的目的在于寻找sp多次运行时候如何确认表版本更新并进行正确的操作。
GreatSQL社区
2023/02/22
1K0
MySQL 存储过程运行的内存管理
MySQL的存储过程在运行过程中的内存管理跟table等运行时候是不一样的,它涉及多层内存管理,在开发时候如果不注意内存管理很容易造成内存泄露。接下来我用以下function的例子来说明,procedure的也是类似的,只是少了return result的过程。
GreatSQL社区
2023/02/23
1.7K0
MySQL 的prepare使用中的bug解析过程
在一次开发中使用 MySQL PREPARE 以后,从 prepare 直接取 name 赋值给 lex->prepared_stmt_name 然后给 EXECUTE 用,发现有一定概率找不到 prepare stmt 的 name,于是开始动手调查问题发生的原因。
GreatSQL社区
2022/05/07
7120
MySQL DBA如何利用strace/pstack/gdb来定位问题
strace是Linux环境下的一款程序调试工具,用来监察一个应用程序所使用的系统调用。 Strace是一个简单的跟踪系统调用执行的工具。在其最简单的形式中,它可以从开始到结束跟踪二进制的执行,并在进程的生命周期中输出一行具有系统调用名称,每个系统调用的参数和返回值的文本行。
老叶茶馆
2020/06/24
2.3K0
时间精度引起MySQL主从不一致问题剖析
1. 主从数据不一致          近日接报某实例一个datetime字段主从数据不一致,其它数据暂未发现异常。第一反应可能是人为修改,如果用户有高权限帐号,是可以做到的,但检查所有帐号权限排除了这种可能。难道有黑客入侵?神经一下绷紧,仔细排查各种系统状态,很快也排除了这种可能。同时分析业务类型,有问题的值都是从机都是比主机少一秒,时间戳被改小一秒不能带来任何收益,被非法篡改的可能性基本排除。 2. 初步分析          对比数据发现从机比主机少一秒的数据经常出现,但主从复制状态一直正常,主机b
腾讯数据库技术
2018/11/29
2.6K0
时间精度引起MySQL主从不一致问题剖析
MySQL Update执行流程解读
一、update跟踪执行配置 使用内部程序堆栈跟踪工具path_viewer,跟踪mysql update 一行数据的执行过程,配置执行脚本:call_update.sh DROP DATABASE IF EXISTS d1; CREATE DATABASE d1; use d1; drop table if exists test; CREATE TABLE test (c0 int NOT NULL AUTO_INCREMENT,c1 date DEFAULT NULL,c2 time DEFA
GreatSQL社区
2022/04/01
2.2K1
MySQL慢查询记录原理和内容解析
本文并不准备说明如何开启记录慢查询,只是将一些重要的部分进行解析。如何记录慢查询可以自行参考官方文档:
用户2781897
2021/09/02
4K0
MySQL源码分析之SQL函数执行
一条包含函数的SQL语句,在MySQL中会经过: 客户端发送,服务器连接,语法解析,语句执行的过程。
GreatSQL社区
2023/02/23
8650
MySQL客户端显示binary字符代码改造
MySQL最新版本有一个新功能,在使用客户端的时候,最后加上--skip-binary-as-hex选项可以直接显示二进制值对应的字符串,不加该选项就可以按照原来的设置格式显示。先来看一下以下的varbinary的显示例子。
GreatSQL社区
2023/02/23
1K0
MySQL科学计数法展示解惑
今天遇到一个很奇怪的问题,在MySQL客户端输入,用不同科学计数法表示的数值,展示效果却截然不同:
老叶茶馆
2023/02/18
1.3K0
MySQL科学计数法展示解惑
慢查询日志中的 Lock_time 从哪里来?
经常关注慢查询日志的读者,和 Lock_time 应该算是老相识了,大家对这位老相识了解有多少呢?
csch
2023/05/24
6420
慢查询日志中的 Lock_time 从哪里来?
sqlalchemy的基本使用
https://docs.sqlalchemy.org/en/14/orm/session_basics.html#querying-1-x-style
崔哥
2023/10/23
4100
sp_executesql介绍和使用
execute相信大家都用的用熟了,简写为exec,除了用来执行存储过程,一般都用来执行动态Sql
全栈程序员站长
2022/08/25
1.2K0
show status和set gtid_mode 导致线程死锁案例
我们数据库组今年上半年的计划之一是将所有数据库实例打开GTID特性。在线上进行灰度开启GITD过程中遇到数据库hang。具体表现是执行如下命令时:
用户1278550
2019/05/07
9910
show status和set gtid_mode 导致线程死锁案例
events scheduler导致MGR节点退出详解及修复
* GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源。
GreatSQL社区
2023/02/23
3300
如果MySQL事务中发生了网络异常?
在我们运维MySQL的时候,总会遇到各种情况导致程序和MySQL之间的会话异常中断,比如
用户1278550
2020/10/10
3.5K0
如果MySQL事务中发生了网络异常?
fsync操作
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/138197.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/04
4730
MySQL中dd::columns表结构转table过程以及应用
MySQL的dd表是用来存放表结构和各种建表信息的,客户端建的表都存在mysql.table和mysql.columns表里,还有一个表mysql.column_type_elements比较特殊,用来存放SET和ENUM类型的字段集合值信息。看一下下面这张表的mysql.columns表和mysql.column_type_elements信息。为了缩短显示长度,这里只展示几个重要的值。
GreatSQL社区
2023/02/23
8550
MySQL resource group详解
提示:公众号展示代码会自动折行,建议横屏阅读 「第一部分 资源组简介」 MySQL-8.0中新增了resource group资源组的功能。MySQL资源组的想法来源很简单:每个资源组是一个资源独立的单位,每个资源组能够容纳一个或者多个MySQL线程。拥有设置资源组权限的DBA们能够创建、配置资源组以及指定、切换MySQL线程从属的资源组,从而更加精准地管控MySQL。 每个MySQL资源组的属性包括: Name:资源组名 CPU affinity:可以使用的VCPU编号,系统可用的VCPU编号可以通
腾讯数据库技术
2021/08/04
9640
相关推荐
MySQL的match函数在sp中使用的BUG解析
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档