【StoneDB研发日志】union功能bug记录

1、问题现象

create database syw_mtr;
use syw_mtr;
CREATE TABLE t1 (f1 VARCHAR(255) CHARACTER SET utf8)engine=tianmu;
CREATE TABLE t2 AS SELECT LEFT(f1,171) AS f2 FROM t1 UNION SELECT LEFT(f1,171) AS f2 FROM t1;
ERROR 2013 (HY000): Lost connection to MySQL server during query

问题issue:https://github.com/stoneatom/stonedb/issues/226

2、问题原因

bug代码行

Query_result_create::prepare (sql_insert.cc:2753)

create_table->table不为空

assert(create_table->table == NULL);

stonedb堆栈

    libc.so.6!raise (未知源:0)
    libc.so.6!abort (未知源:0)
    libc.so.6!__assert_fail_base (未知源:0)
    libc.so.6!__assert_fail (未知源:0)
    Query_result_create::prepare(Query_result_create * const this, List & values, SELECT_LEX_UNIT * u) (\opt\litaihong\stonedb\sql\sql_insert.cc:2753)
    st_select_lex::prepare(st_select_lex * const this, THD * thd) (\opt\litaihong\stonedb\sql\sql_resolver.cc:361)
    st_select_lex_unit::prepare_fake_select_lex(st_select_lex_unit * const this, THD * thd_arg) (\opt\litaihong\stonedb\sql\sql_union.cc:441)
    st_select_lex_unit::optimize_for_stonedb(st_select_lex_unit * const this) (\opt\litaihong\stonedb\storage\stonedb\core\engine_execute.cpp:586)
    stonedb::core::Engine::HandleSelect(stonedb::core::Engine * const this, THD * thd, LEX * lex, Query_result *& result, ulong setup_tables_done_option, int & res, int & optimize_after_sdb, int & sdb_free_join, int with_insert) (\opt\litaihong\stonedb\storage\stonedb\core\engine_execute.cpp:181)
    stonedb::dbhandler::SDB_HandleSelect(THD * thd, LEX * lex, Query_result *& result, ulong setup_tables_done_option, int & res, int & optimize_after_sdb, int & sdb_free_join, int with_insert) (\opt\litaihong\stonedb\storage\stonedb\handler\ha_rcengine.cpp:82)
    mysql_execute_command(THD * thd, bool first_level) (\opt\litaihong\stonedb\sql\sql_parse.cc:3265)
    mysql_parse(THD * thd, Parser_state * parser_state) (\opt\litaihong\stonedb\sql\sql_parse.cc:5621)
    dispatch_command(THD * thd, const COM_DATA * com_data, enum_server_command command) (\opt\litaihong\stonedb\sql\sql_parse.cc:1495)
    do_command(THD * thd) (\opt\litaihong\stonedb\sql\sql_parse.cc:1034)
    handle_connection(void * arg) (\opt\litaihong\stonedb\sql\conn_handler\connection_handler_per_thread.cc:313)
    pfs_spawn_thread(void * arg) (\opt\litaihong\stonedb\storage\perfschema\pfs.cc:2197)
    libpthread.so.0!start_thread (未知源:0)
    libc.so.6!clone (未知源:0)

分析过程

assert(create_table->table == NULL);

Query_result_create::prepare (sql_insert.cc:2753)函数prepare阶段和optimize阶段在被调用了两次

1、stonedb::core::Engine::HandleSelect函数首先调用

st_select_lex_unit::prepare->prepare_fake_select_lex ->Query_result_create::prepare

此时create_table->table 是NULL。

2、然后调用

st_select_lex_unit::optimize_for_stonedb -> prepare_fake_select_lex -> Query_result_create::prepare

此时create_table->table不为NULL,assert(create_table->table == NULL); 导致数据库异常退出。

问题出现原因

分析st_select_lex_unit::optimize_for_stonedb函数发现是来源于MySQL的st_select_lex_unit::exec()函数

3、解决办法

mysql的handle_query函数先有prepare然后是optimize函数,但我们stonedb的optimize函数是根据MySQL的st_select_lex_unit::exec()写的,不知道为啥没有正常的optimize流程

【StoneDB研发日志】union功能bug记录

两种解决方案:

1、修改抛异常的代码行Query_result_create::prepare (sql_insert.cc:2753)函数

assert(create_table->table == NULL);

2、重写stonedb的st_select_lex_unit::optimize_for_stonedb函数,改动比较大,涉及功能多。

解决方案更新:

A:我们发现,这个问题是由于在优化器的代码中,Lex unit 两次prepare造成的。

首先我们抛弃了对assert语句修改的考虑,因为那里判断表没有创建是合理的。

于是解决方案有两种,

1:考虑在lex unit 的prepare里加入 is_prepared的判断。但这个方案,影响面很大,因为这个函数所有的语法都会影响到。

2:针对,select union 或者 select join,以及他们出现的复杂的组合做修改。发现了三处异常点需要进行is_prepared判断。1:union处。2:join处。3:fake_lex_prepare处。

B:针对我们的修改添加了相应mtr语句进行覆盖。一并记录在issue226中。

https://github.com/stoneatom/stonedb/issues/226

ADD test cases to cover these ctas queries for the following reason.

1: From code perspective. There are enough evidences that we want to support these ctas.

2: Our fix can cover these related queries.

CREATE TABLE t2 AS SELECT LEFT(f1,171) AS f2 FROM t1 UNION SELECT LEFT(f1,171) AS f2 FROM t1;

CREATE TABLE t3 AS SELECT t1.f1 AS f3 FROM t1 LEFT JOIN t2 ON t1.f1 = t2.f2;

CREATE TABLE t4 AS SELECT t1.f1 AS f4 FROM t1 INNER JOIN t2 ON t1.f1 = t2.f2;

CREATE TABLE t5 AS SELECT t1.f1 AS f5 FROM t1 RIGHT JOIN t2 ON t1.f1 = t2.f2;

CREATE TABLE t6 AS SELECT t1.f1 AS f6 FROM t1 UNION SELECT t2.f2 AS f6 FROM t2 LEFT JOIN t3 ON t2.f2 = t3.f3;

CREATE TABLE t7 AS SELECT t1.f1 AS f7 FROM t1 UNION SELECT t2.f2 AS f7 FROM t2 INNER JOIN t3 ON t2.f2 = t3.f3;

CREATE TABLE t8 AS SELECT t1.f1 AS f8 FROM t1 UNION SELECT t2.f2 AS f8 FROM t2 RIGHT JOIN t3 ON t2.f2 = t3.f3;

CREATE TABLE t9 AS SELECT t1.f1 AS f9 FROM t1 INNER JOIN t3 ON t1.f1 = t3.f3 UNION SELECT t2.f2 AS f9 FROM t2;

4、MySQL正常流程堆栈

Query_result_create::prepare(Query_result_create * const this, List & values, SELECT_LEX_UNIT * u) (\opt\litaihong\stonedb\sql\sql_insert.cc:2750)
st_select_lex::prepare(st_select_lex * const this, THD * thd) (\opt\litaihong\stonedb\sql\sql_resolver.cc:361)
st_select_lex_unit::prepare_fake_select_lex(st_select_lex_unit * const this, THD * thd_arg) (\opt\litaihong\stonedb\sql\sql_union.cc:441)
st_select_lex_unit::prepare(st_select_lex_unit * const this, THD * thd_arg, Query_result * sel_result, ulonglong added_options, ulonglong removed_options) (\opt\litaihong\stonedb\sql\sql_union.cc:670)
handle_query(THD * thd, LEX * lex, Query_result * result, ulonglong added_options, ulonglong removed_options, int optimize_after_bh, int free_join_from_bh) (\opt\litaihong\stonedb\sql\sql_select.cc:150)
mysql_execute_command(THD * thd, bool first_level) (\opt\litaihong\stonedb\sql\sql_parse.cc:3266)
mysql_parse(THD * thd, Parser_state * parser_state) (\opt\litaihong\stonedb\sql\sql_parse.cc:5621)
dispatch_command(THD * thd, const COM_DATA * com_data, enum_server_command command) (\opt\litaihong\stonedb\sql\sql_parse.cc:1495)
do_command(THD * thd) (\opt\litaihong\stonedb\sql\sql_parse.cc:1034)
handle_connection(void * arg) (\opt\litaihong\stonedb\sql\conn_handler\connection_handler_per_thread.cc:313)
pfs_spawn_thread(void * arg) (\opt\litaihong\stonedb\storage\perfschema\pfs.cc:2197)
libpthread.so.0!start_thread (未知源:0)
libc.so.6!clone (未知源:0)

Original: https://www.cnblogs.com/yangwilly/p/16591385.html
Author: 来来士
Title: 【StoneDB研发日志】union功能bug记录

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/505020/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Mybatis的级联查询,分步查询,一对一,一对多和多对一

    配置和代码目录 ***util配置 ***log4j配置 –可以打印入日志,也可以使用系统自带的STDOUT_LOGGING个人喜欢log4j ***mybatis-c…

    数据库 2023年6月16日
    0133
  • FastDFS安装和简介详细总结

    1、fastDFS简介 1 FastDFS是用c语言编写的一款开源的分布式文件系统。 2 FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用…

    数据库 2023年6月14日
    0148
  • MyBatis(二)-CURD (ResultMap 一对一,一对多)

    1、insert 标签 1.1 获取SqlSessionFactory 对象的通用方法 方便后面分测试; //获取SqlSessionFactory 对象的通用方法 public …

    数据库 2023年6月16日
    0161
  • 小公司比较吃亏的两道微服务面试题

    其实选择工作的时候,很多技术牛人都会选择一些小而美的公司,技术全面,能够以一个更全面的视角看整个公司的运作,人和人之间的相处也很简单。但是,有两道微服务的面试题,小公司的朋友们会比…

    数据库 2023年6月6日
    0184
  • SpringMvc(二)- 请求处理参数 和 响应数据处理

    1、请求处理参数 1.1 请求参数 @RequestParam 1.1.1 不使用 @RequestParam 注解 请求参数处理, 不使用参数注解:1.如果 请求参数名和请求处理…

    数据库 2023年6月16日
    0120
  • 9、IDEA回退Git版本

    转载自 在工作中有时候会要求我们将以前提交的代码新开一个分支,而把之前提交的分支回退到以前某个版本 。 方法一: 1、通过IDEA查看Git历史记录,复制当前版本号。 2、 记录当…

    数据库 2023年6月6日
    0164
  • 一个小工具帮你搞定实时监控Nginx服务器

    Linux运维工程师的首要职责就是保证业务7 x 24小时稳定的运行,监控Web服务器对于查看网站上发生的情况至关重要。关注最多的便是日志变动,查看实时日志文件变动大家第一反应应该…

    数据库 2023年6月9日
    0199
  • 内嵌h5调试神器-vConsole

    vConsole 一个轻量、可拓展、针对手机网页的前端开发者调试面板,可用于APP内嵌H5及其他调试H5的地方。 使用 方法一:cdn 方式引入 // 引入 // 初始化 var …

    数据库 2023年6月11日
    0116
  • Python接口自动化——文件上传/下载接口

    转载请注明出处❤️ 你好,我是测试蔡坨坨。 我们在做接口自动化测试的时候,经常会碰到 文件上&#x4F20…

    数据库 2023年6月11日
    0133
  • google浏览器个人常用快捷键

    分享一下个人常用快捷键。 说明:字母排序规则遵循字母表(a->z) 快捷键 介绍 ctrl+0 恢复页面到100% ctrl+数字(1~9) 切换至序号对应的标签页 ctrl…

    数据库 2023年6月14日
    0129
  • 推荐几款最好用的MySQL开源客户端,建议收藏!

    一、摘要 众所周知,MYSQL 是目前使得最广泛、最流行的数据库技术之一,为了更方便的管理数据库,市场上出现了大量软件公司和个人开发者研发的客户端工具,比如我们所熟知的比较知名的客…

    数据库 2023年6月14日
    0175
  • 不同分层中的对象的使用

    在项目中,控制层,业务层,数据层,视图层(返回值)。中分别使用了的对象,暂时不太理解这样做的好处,先记录下来。 如下: 控制层:也可以叫做入参对象, UserQuery userQ…

    数据库 2023年6月11日
    0113
  • Excel文件校验

    工作中,经常存在excel文件的导入导出的相关工作,因此正确的文件格式校验成为必须。不合适的文件校验方式会导致非法文件跳过校验,从而产生不必要的麻烦。比如,通过文件后缀名的方式进行…

    数据库 2023年6月14日
    0202
  • 线程池使用InheritableThreadLocal出现数据脏乱分析和解决方案

    背景 在测试环境上遇到一个诡异的问题,某些业务场景需要记录操作日志,有段时间发现记录的数据会被覆盖,例如当前用户的操作记录会被其他用户覆盖;这个现象是每次重启服务后一小段时间内就正…

    数据库 2023年6月6日
    0179
  • 开源之夏 2022 与您相约

    活动简介 “开源之夏(英文简称 OSPP)”是中科院软件所”开源软件供应链点亮计划”指导下的一项面向高校学生的暑期活动,由中国科学院…

    数据库 2023年5月24日
    0172
  • 自然对数

    https://zhuanlan.zhihu.com/p/71928040自然对数 https://www.youtube.com/watch?v=mZE0RmCbDe8 本文来自…

    数据库 2023年6月11日
    0162
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球