【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)

大家都在看

  • 工作中常用Less知识点实践总结

    工作中常用Less知识点实践总结,帮助你更好的使用Less 我所理解的Less的一些好处 函数式编程css 自定义变量用于整体主题调整 嵌套语法简化开发复杂度 mixin的写法 ….

    数据库 2023年6月11日
    075
  • podman

    podman Podman 是一个无守护程序、开源的 Linux 原生工具,旨在使用开放容器计划 (OCI) 容器和容器映像轻松查找、运行、构建、共享和部署应用程序。Podman …

    数据库 2023年6月14日
    076
  • asyncio 异步编程

    首先了解一下协程,协程的本质就是一条线程,多个任务在一条线程上来回切换,协程的所有切换都是基于用户,只有在用户级别才能感知到的 IO 才会用协程模块来规避,在 python 中主要…

    数据库 2023年6月9日
    057
  • 第十五章 Spring动态代理开发

    创建原始对象 public class UserServiceImpl implements UserService{ @Override public void register…

    数据库 2023年6月14日
    096
  • Springboot学习笔记(一)—— 安装

    springboot越来越流行了,相比较于springMVC,springboot采用了一种约定大于配置的理念,可以一键安装,一键运行,一键部署,内置tomcat,省去了一大堆配置…

    数据库 2023年6月9日
    088
  • linux根目录无法查看文件执行ls卡死无反应执行df -h 也同样没反应的处理方法

    问题现象: 1、执行 df -h 卡死没反应,执行 df -hl 可以正常显示; 2、执行  ll / 或 ls /&…

    数据库 2023年6月11日
    079
  • Linux 添加大于2TB磁盘扩容逻辑卷

    一、查看新添加磁盘以及分区情况 # lsblk 二、使用parted进行分区 # parted /dev/sdb // /dev/sdb 为上面查看到的新添加未分区的磁盘 (par…

    数据库 2023年6月11日
    090
  • JVM详解

    一、JVM的位置及体系结构 JVM作用在操作系统之上,而Java程序作用在jvm之上,其他的程序则与jvm并列 二、类加载器,及双亲委派机制 1.类加载器 作用:加载Class文件…

    数据库 2023年6月16日
    075
  • Etcd 使用场景:通过分布式锁思路实现自动选主

    分布式锁?选主? 分布式锁可以保证当有多台实例同时竞争一把锁时,只有一个人会成功,其他的都是失败。诸如共享资源修改、幂等、频控等场景都可以通过分布式锁来实现。 还有一种场景,也可以…

    数据库 2023年6月6日
    085
  • Java List分批处理

    工作中经常遇到分批处理的问题,比如将一个List列表中的数据分批次保存至数据库中。如果列表中数据条目很大,比如1000万条以上,mysql中 max_allowed_packet …

    数据库 2023年6月14日
    091
  • DM变更表空间存放路径

    1、变更前置条件 (1)、数据库服务器提供dmdba用户权限 (2)、目标路径有足够的空间可以使用 (3)、数据库可以重启 2、变更实施过程 2.1、变更前备份变更表空间目录需要对…

    数据库 2023年6月11日
    0158
  • 银河麒麟V10安装MySQL8028

    记一次成功安装MySQL8028到银河麒麟V10,并实现远程访问的方法 工具/原料 数据库下载地址(实验版如图): [En] Download address of the dat…

    数据库 2023年5月24日
    082
  • centos系统下mysql的配置

    配置文件路径 /etc/my.cnf Hole yor life get everything if you never give up. Original: https://ww…

    数据库 2023年6月9日
    063
  • macbook air 2019 安装win10单系统

    目前不考虑写的太详细了,如果有同学遇到问题了我再完善,主要是把遇到的坑讲下第一步,准备2个U盘(如果不嫌麻烦一个也可以)1.用大白菜或者老毛桃将其中一个做成启动盘2.在window…

    数据库 2023年6月9日
    0330
  • 两表关联更新、删除-七星海棠

    两表关联更新 通用方法 update test1 set name=(select name from test2 where test2.id=test1.id), age=(s…

    数据库 2023年6月11日
    078
  • 用Python做一个中秋抢购月饼的脚本

    ; 序言 每逢佳节倍思亲,想买个东西给家里,结果发现手速不够,网速不够快,没有时间下单等等各种原因导致最后想买的东西售罄了… 甚至跟你一起抢购的可能是脚本,太真实了! …

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