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

news/2024/10/4 23:24:49

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-100-1-1.html

image-20230105161905827

技术交流群:

微信:扫码添加GreatSQL社区助手微信好友,发送验证信息加群

image-20221030163217640

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ryyt.cn/news/28843.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

对于习惯使用ftp传输的企业,如何寻找最佳的替代方案?

FTP协议广泛应用各行业的文件传输场景中,对于很多企业而言,由于FTP传输应用获取门槛低、使用普遍,因此,有较为稳定的FTP使用习惯,但即便如此,也不得不面对,FTP应用存在着严重缺陷: 传输效率问题:FTP协议作为最早的互联网文件传输协议,虽然解决了传输协议有无的问题,…

Keil编译后的Code,RO,RW,ZI等相关

在使用keil开发STM32应用程序时,点击Build后在Build Output窗口中经常会有如下信息:以前一直好奇这几个参数和实际使用的STM32芯片中Flash和SRAM的对应关系,于是上网搜了一圈,做如下总结:这些参数的单位是Byte 图中几个参数分别代表 Code:代码的大小 RO:常量所占空间(加…

团队项目第一阶段评分及其点评

1组:调用对话接口,但内容太少,页面不美观 2组:页面不行,作品阶段质量太差 3组:内容太少 4组:页面整体可以,内容可以 5组:页面整体美观,内容较好 6组:内容较多,质量可以 7组:质量较好 8组:内容太少,质量差 9组:内容可以,质量较好 10组:内容多,质量好 11组:创…

Windows下使用ONNXRuntime的GPU进行推理时提示cudnn64_8.dll异常

一、问题复现 将模型放到GPU上推理时时发生的异常。 OrtSessionOptionsAppendExecutionProvider_CUDA(session_options, 0);...ort_outputs = session_.Run(Ort::RunOptions{ nullptr }, inputNames.data(), &input_tensor_, 1, outNames.data(), outNames.size());二、解决…

攻防世界 easyphp

打开场景 这种难度为1的题目,可能是把代码都放前端,让我们读。可以看到要传3个参数a、b、c a满足:转换为整数后大于6000000&&长度<=3,1e7 1e8 1e9都可以 b满足:md5加密后,后6位是8b184b,这里暴力枚举一下就行 c满足:json格式的数组,有两个索引c[m],c[n]。c…

k8s——核心概念篇

服务的分类 有状态代表应用nginx apache优点对客户端透明,无依赖关系,可以高效实现扩容,迁移缺点不能存储数据,需要额外的数据服务支撑无状态代表应用MYSQL Redis优点可以独立存储数据,实现数据管理缺点集群环境下需要实现主从,数据同步,备份,水平扩容负载。资源和对象…

轻量化城市三维模型CIM的主要技术方法

三维工厂K3DMaker是一款三维模型浏览、分析、轻量化、顶层合并构建、几何校正、格式转换、调色裁切等功能专业处理软件。可以进行三维模型的网格简化、纹理压缩、层级优化等操作,从而实现三维模型轻量化。轻量化压缩比大,模型轻量化效率高,自动化处理能力高;采用多种算法对…

一个小工具识别哪个docker占用gpu

我们经常会为了组内谁在占用某块gpu卡而不使用 烦恼,通过简单的代码就能快速识别到这块卡上面的进程是哪个容器的。 下面的代码会给出如下图这样的结果#! /miniconda3/bin/python # -*- coding: utf-8 -*- import psutil import subprocess as spdef pre():ans = sp.check_out…