作者简介


苏星开

云和恩墨南区交付技术顾问,曾服务过通信、能源生产、金融等行业客户,擅长 SQL 审核和优化,DataGuard 容灾等。


1
概述

在 Oracle 12.2 版本和新发布的18.0版本中存在一个 SQL 解析的 bug,导致了数据库后台报 ora-07445 或者 ora-00600 错误。报 ora-07445 时,可导致数据库断开当前会话连接,无法进行 SQL 操作,当报 ora-00600 时,会话没有断开,但无法完成解析返回结果。

该 bug 的发现敬请参考:http://www.hellodba.com/reader.php?ID=221&lang=CN

2
触发 Bug 的现象

2.1 报 ora-07445

后台 alert 日志:

Sqlplus 显示:

2.2 报 ora-00600

Sqlplus 显示:

该报错,是在测试重现 ora-07445 时发现的。以下我们一起来重现一下 ora-7445 的报错。

3
Bug 重现测试

读者可以按照以下的语句,可以在 Oracle 12.2 和18.0的版本中测试,重现这个 SQL 解析的 bug,观察报错情况。重现这个 bug 重点符合以下条件:

  1. 表中有一个运行为空的字段;

  2. 该字段的统计信息被收集过;

  3. 该字段中存在空值和非空值。

3.1 创建测试表并插入测试数据


create table tt1 (c1 number, c2 date);

insert into tt1 values(1, sysdate);

insert into tt1 values(1, null);

commit;

3.2 收集表的统计信息


exec dbms_stats.gather_table_stats('SYS', 'TT1', METHOD_OPT=>'for all columns');

3.3 尝试解析以下语句


explain plan for

with

ut as (select c1

from tt1

where nvl (c2 ,

trunc (sysdate ) ) >= trunc (sysdate ) ),

txo as (select distinct c1

from ut , dual),

u as (select * from ut)

select * from u , txo  ;

读者可以按照这个测试过程,在自己的测试环境重现 ora-07445 报错,记住,决不能在生产环境的 12.2 的库上测试。

4
报错的信息追踪和影响

[oracle@susu ~]$ oerr ora 07445

07445, 00000, "exception encountered: core dump [%s] [%s] [%s] [%s] [%s] [%s]"

// *Cause: An operating system exception occurred which should result in the

//         creation of a core file.  This is an internal error.

通过服务器上看这个 ora-07445 为核心存储内部的错误。

4.1 后台日志报错

4.2 使用 adrci 工具分析

1> show incident 查看报错信息摘要:

adrci> show incident

2> 查看比较接近的一个 incident_id 的摘要详情:

adrci> show incident -mode detail -p "incident_id=155499"

4.3 语句的执行计划

这个执行计划是从 Oracle 12.1.0.2 版本中取得的,只作为参考。测试数据为根据上述条件创建的。

with

sal  as (select empno,name,salary from mytest

where nvl(signdate,trunc (sysdate ) ) >= trunc (sysdate ) ),

inc  as (select distinct salary from sal,dual),

mark as (select empno,name from sal)

select * from inc,mark;


Oracle 12.1中基于成本模式的 SQL 执行计划:

4.4 Oracle 官网对报错号的描写

通过 Oracle 官网文档 ORA-600/ORA-7445/ORA-700 Error Look-up Tool (Doc ID 153788.1)查看报错号对应的 bug 信息,发现官网未对 oracle 12.2 或者 18.0 这个 SQL 解析的 bug 作发布,如下:

ORA-07445: exception encountered: core dump [__intel_ssse3_rep_memcpy()+8260] in oracle 12.2.0.1

An Error document for ORA-7445 [type:] is not registered with the tool.

Your request for information on this error has been recorded and will be used for publishing prioritization.

Things to try:

Check the error message and confirm that this is an ORA-7445 error and not an ORA-600 or ORA-700 error.

Use 'Do a general Search for Knowledge' to begin a search for any published documents and bugs that mention the error.

由于这个 ora-07445 报错出现在之前的多个版本的不同场景,以下为12.1版本中有类似的 bug 可以参考一下:

Bug 18463985 - ORA-7445 [__intel_ssse3_rep_memcpy()+8912] for stmt with adaptive plans and cfb (Doc ID 18463985.8)

以及官网文档:

Bug 21856417 - Wrong Result: null values with partial join evaluation , Filter Push Down and fix for bug 18463985 (Doc ID 21856417.8)

两篇文章中分别提到了:查询当中循环多次使用到某个对象,以及空值参与到了部分连判断运算。

4.5 该 SQL 解析 bug 的影响

这个 SQL 解析的 bug 的影响可以从两方面来看。

4.5.1 SQL 层面

SQL 层面的影响就是不能解析执行的 SQL,没有返回结果。当报 ora-07445 时候,还中断了当前的会话。

4.5.2 系统层面

经过多次的测试实验的观察,在解析语句到会话中断这个过程,消耗比较多的 CPU 资源和内存资源,如果在比较繁忙的生成系统,有可能导致数据库被 hang 住,影响生产。

5
避开解析 Bug 的方法

根据上述的条件,经过另外的测试数据,使用变量控制法,模拟了一系列的测试实验得出触发该解析 bug 同时满足以下条件:

  1. 为 with 子句形式;

  2. where 子句中字段的统计信息被收集过;

  3. 数据库表 D 的字段可以不存在空值,但在临时表 A 从表 D 获取数据的 where 字句中存在关于 null 判断运算。则上述中分别为:decode(d1,null,val1,val2[,...]),nvl(expr1,expr2)或者nvl2(expr1,expr2,expr3);

  4. decode、nvl 或者 nvl2 内嵌套有 Oracle 数据库内部函数,如to_number,round,trunc 等;

  5. With 子句结构中,临时表 B 和临时表 C 都经临时表A产生;

  6. 临时表 B 和临时表 C 中有至少有一个临时表 A 和伪表 dual 构成笛卡尔连接查询,并且通过 distinct 去重;

  7. 最终的结果通过临时表 B 和临时表 C 做连接查询而得。

语句形式:

with

A  as (select d1,d2,d3,[...] from D where [decode] nvl(d3,trunc (val1 ) ) >= [trunc (]val2 ) ),

B  as (* from A,dual),

C  as (select * from A)

select * from B,C [where B.b1=C.c1];

5.1 方法一:避开触发条件法

根据上述触发该 bug 的条件,要同时满足那些条件,才能触发,这还是比较容易避开的。也就是说,在日常遇到这个 Oracle12.2 的解析 bug,是比较难的事情。比如以下两个例子:

例1:上述条件6,将伪表 dual 和 distinct 分别放在两个临时表中:

例2:上述条件4,nvl() 函数内不嵌套 Oracle 内部函数,直接使用标量 5100:

5.2 方法二:设置参数法

在当前测试版本的数据库,优化器默认是使用基于成本的模式,而使用基于规则的模式可以避开该解析 bug,成功解析语句。

默认优化模式参数:

调整该优化参数为 rule:

Alter session set optimizer_mode=RULE;

解析一语句已成功解析:

解析二语句已成功解析:

这里跟上述,同样的语句,但看不到报 ora-00600 的错。

5.3 方法三:添加 hint 指示法

当前会话的优化模式为 ALL_ROWS,同样使用以上两个语句进行测试验证。

解析一:


解析二:

以上两个语句使用了 hint 指示之后,原来不能正常解析的,没有触发正常解析,其实原理和方法二是类似的。

6
总结

以上展示部分的测试实验情况,没有完全展现出来。本次的测试使用了变量控制法,逐个因素地测试,尝试找出触发 Oracle 12.2 SQL 解析 bug 的条件。个人技术知识方面有限,难免还存在一些不足,希望得到更多一些的指点。虽然目前未能很准确定位该 bug,目前我们能够确定的就是以上几个条件,能触发这个解析的 bug,相信在日常生产的业务应用中,是很难遇到这个 bug 的。就算你很幸运在维护数据库中遇到 SQL 解析的 bug,不妨可以尝试按照以上介绍的三种方法,去绕开这个 bug。可以是在 session 级别设置 optimizer_mode 参数值为 RULE,也可以是加上 RULE 指示,最终这两个的作用是一样的。

资源下载

关注公众号:数据和云(OraNews)回复关键字获取

2017DTC,2017 DTC 大会 PPT

DBALIFE,“DBA 的一天”海报

DBA04,DBA 手记4 经典篇章电子书

RACV1, RAC 系列课程视频及 PPT

122ARCH,Oracle 12.2 体系结构图

2017OOW,Oracle OpenWorld 资料

PRELECTION,大讲堂讲师课程资料

18C 也不能避免 SQL 解析的 Bug相关推荐

  1. 【原创】大数据基础之Hive(2)Hive SQL执行过程之SQL解析过程

    Hive SQL解析过程 SQL->AST(Abstract Syntax Tree)->Task(MapRedTask,FetchTask)->QueryPlan(Task集合)- ...

  2. CowNew开源-sql解析引擎和cownewsql阶段成果汇报

    很多关心CowNew的朋友纷纷给我发email或者qq留言,说看到最近CowNew开源项目没有动静了,问我是不是虎头蛇尾死掉了.谢谢大家的关心,CowNew没有停止进步的步伐,最近一段时间没有动静是因 ...

  3. SQL解析在美团的应用

    数据库作为核心的基础组件,是需要重点保护的对象.任何一个线上的不慎操作,都有可能给数据库带来严重的故障,从而给业务造成巨大的损失.为了避免这种损失,一般会在管理上下功夫.比如为研发人员制定数据库开发规 ...

  4. SQL解析在美团点评中的应用

    数据库作为核心的基础组件,是需要重点保护的对象.任何一个线上的不慎操作,都有可能给数据库带来严重的故障,从而给业务造成巨大的损失.为了避免这种损失,一般会在管理上下功夫.比如为研发人员制定数据库开发规 ...

  5. TANX英文翻译软件测试工资,ktanx-jdbc 1.0.5发布,增加自定义sql解析及部分方法修改...

    版本 1.0.5 更新内容: 增加自定义sql解析转换,使用native方式执行自定义sql时可以在sql中使用类名和类属性了. resultClass方法增强,支持JavaBean外的基本类型,例如 ...

  6. SQL 解析原理和使用场景

    SQL解析是一项复杂的技术,一般都是由数据库厂商来掌握,由于这几年MySQL数据库中间件的兴起,需要支持读写分离.分库分表等功能,就必须从SQL中抽出表名.库名以及相关字段的值.因此像Java语言编写 ...

  7. Spark之SQL解析(源码阅读十)

    如何能更好的运用与监控sparkSQL?或许我们改更深层次的了解它深层次的原理是什么.之前总结的已经写了传统数据库与Spark的sql解析之间的差别.那么我们下来直切主题~ 如今的Spark已经支持多 ...

  8. bs架构与cs架构的区别_Oracle vs Mysql--架构、sql查询执行流程及SQL解析顺序区别说明...

    概述 之前分享的主要是Oracle上的一些内容,那么mysql又有哪些地方不一样呢?下面从MySQL总体架构.sql查询执行流程和语句执行顺序来看一下.. 01 架构总览 下面看一下mysql的架构图 ...

  9. sharding-jdbc源码解析之sql解析

    2019独角兽企业重金招聘Python工程师标准>>> 说在前面 本文转自"天河聊技术"微信公众号 本次介绍的是sharding-jdbc的源码解析部分的sql解 ...

最新文章

  1. Markdown 语法说明
  2. [python网络编程]DNSserver
  3. 运行sp_xp_cmdshell_proxy_account 出现的错误
  4. oracle 27140,ORA-27140 ORA-27300 ORA-27301
  5. 【项目管理】工具--数据收集
  6. Android开发中依赖注入的应用
  7. python最大分词_中文分词算法之最大正向匹配算法(Python版)
  8. ubuntu下iptables的用法
  9. SRMD:Learning a Single Convolutional Super-Resolution Network for Multiple Degradations
  10. ANSYS19.0安装(无比详细的图文示范教程)
  11. mysql 存储用户头像_微信授权后用户头像保存到服务器实现方法
  12. C语言谭浩强第三版第八章例题及课后题:函数
  13. Flutter:文件与网络操作摘要
  14. Java 生成订单号
  15. 如何区分电梯卡为id卡ic卡_门禁卡ID卡和IC卡从外表怎么区分?
  16. 视频编码第一节:H.265/HEVC原理——入门
  17. Nature综述:宏基因组测序研究耐药基因的方法和资源
  18. hive-创建数据库-创建表--hive版本3.1.2
  19. 多多情报通:拼多多发布机会商品是谁发货?该怎么发货?
  20. 【仅售9.9元】石杉老师最新出品:C2C电商系统微服务架构120天实战训练营

热门文章

  1. 为什么Python 4.0不会像Python 3.0
  2. HTML5 canvas 阴影
  3. mysql sillyr x.so_mysql2.so:libmysqlclient_r.so.15:无法打开共享对象文件:没有这样的文件或目录...
  4. CAN笔记(20) 过程数据对象
  5. CAN笔记(11) 位时序
  6. 用linux上网有什么优点,Linux系统的介绍,有什么优点,怎么使用
  7. mysql 大量数据 更改索引_一文看懂ICP原理--MySQL用索引去表里取数据的一种优化...
  8. 重构—改善既有代码的设计4——构筑测试体系
  9. 【操作系统】多道程序的理解
  10. CSS3中的border-radius兼容IE低版本解决方法