GreatSQL的sp中添加新的sp_instr引入的bug解析
GreatSQL的sp中添加新的sp_instr引入的bug解析
一、问题发现
在一次开发中用到的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宏定义: #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中同样存在。
Enjoy GreatSQL :)
关于 GreatSQL
GreatSQL是适用于金融级应用的国内自主开源数据库,具备高性能、高可靠、高易用性、高安全等多个核心特性,可以作为MySQL或Percona Server的可选替换,用于线上生产环境,且完全免费并兼容MySQL或Percona Server。
相关链接: GreatSQL社区 Gitee GitHub Bilibili
GreatSQL社区:
社区有奖建议反馈: https://greatsql.cn/thread-54-1-1.html
社区博客有奖征稿详情: https://greatsql.cn/thread-100-1-1.html
(对文章有疑问或者有独到见解都可以去社区官网提出或分享哦~)
技术交流群:
微信&QQ群:
QQ群:533341697
微信群:添加GreatSQL社区助手(微信号:wanlidbc
)好友,待社区助手拉您进群。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
无需重启 NGINX 开源版即可实现 SSL/TLS 证书轮换
原文作者:Maxim Ivanitskiy of F5 原文链接:无需重启 NGINX 开源版即可实现 SSL/TLS 证书轮换 转载来源:NGINX 开源社区 NGINX 唯一中文官方社区 ,尽在nginx.org.cn 在高性能 Web 服务器领域,NGINX是一个广受欢迎的选择,因为其轻便高效的架构支持它处理大量流量。通过在NGINX JavaScript 模块(njs)中引入共享字典(shared dictionary)功能,NGINX 的性能更上一层楼。 在本文中,我们将探讨 njs 共享字典的功能和优势,并展示如何设置 NGINX 开源版,以无需重启即可轮换 SSL/TLS 证书。 共享字典简介及其优势 新js_shared_dict_zone指令允许 NGINX 开源版用户启用共享内存区,在 worker 进程之间高效交换数据。 这些共享内存区充当键值字典,存储着可实时访问和修改的动态配置设置。 共享字典的主要优势包括: 开销极少且易于使用 –直接内置在 njs 中,得益于直观的 API 和简单的实现,可轻松配置和使用。它还能够帮助您简化 worker 进程之间的数据管理...
- 下一篇
揭露 FileSystem 引起的线上 JVM 内存溢出问题
作者:来自 vivo 互联网大数据团队-Ye Jidong 本文主要介绍了由FileSystem类引起的一次线上内存泄漏导致内存溢出的问题分析解决全过程。 内存泄漏定义(memory leak):一个不再被程序使用的对象或变量还在内存中占有存储空间,JVM不能正常回收改对象或者变量。一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出。 内存溢出(out of memory):是指在程序运行过程中,由于分配的内存空间不足或使用不当等原因,导致程序无法继续执行的一种错误,此时就会报错OOM,即所谓的内存溢出。 一、背景 周末小叶正在王者峡谷乱杀,手机突然收到大量机器CPU告警,CPU使用率超过80%就会告警,同时也收到该服务的Full GC告警。该服务是小叶项目组非常重要的服务,小叶赶紧放下手中的王者荣耀打开电脑查看问题。 图1.1 CPU告警 Full GC告警 二、问题发现 2.1 监控查看 因为服务CPU和Full GC告警了,打开服务监控查看CPU监控和Full GC监控,可以看到两个监控在同一时间点都有一个异常凸起,可以看到在CPU告警的时候,Full GC特别...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- CentOS7安装Docker,走上虚拟化容器引擎之路
- Hadoop3单机部署,实现最简伪集群
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- CentOS8编译安装MySQL8.0.19
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Red5直播服务器,属于Java语言的直播服务器
- CentOS关闭SELinux安全模块
- CentOS7,CentOS8安装Elasticsearch6.8.6