怎么找出解析失败的sql
本文由我和公司同事问心共同测试分析完成。
很多时候我们会有这样一个误区,语法错误或者对象不存在应该在语法语义检查这个步骤就结束了,怎么还会存在共享池里面呢?带着这个几个问题我们做几个简单的测试。
我们先了解下什么是解析失败的 SQL?
1、SQL语法错误
2、访问的对象不存在
3、没有权限
那么怎么证明有哪些解析失败的SQL
我们知道 SQL 语句必须至少是一个父游标一个子游标存在的,当然生产中很多情况下都是一父多子的情况。
父游标与子游标结构是一样的,区别在于sql解析相关信息存储在父游标对应的heap 0中,而sql的执行计划等信息存储在子
游标对应的库缓存对象heap 6内存空间中。另外父游标的 heap 0中存储着子游标的句柄地址。如果解析错误的SQL在共
享池中存储的话那么必然要产生一个父游标然后父游标里面存储的有相关的解析信息,但是子游标的?既然解析失败那么就
没有产生执行计划。
则利用这一点可以找到解析失败的语句。
父游标句柄对地址可以在 x$kglob 视图中查询到,KGLHDPAR=KGLHDADR 的记录为父游标,
而KGLHDPAR<>KGLHDADR为子游标
X$KGLOB
该视图定义为 [K]ernel[G]eneric [L]ibrary Cache Manager
KGLHDADR RAW(4|8) Address of kglhd for this object
可以看到:
KGLOBHD0 RAW(4|8) Address of heap 0 descriptor
KGLOBHD6 RAW(4|8) Address of heap 6 descriptor
SQL> select * from scott.emp;
SQL> col kglnaobj for a50;
SQL> select kglnaobj,kglnatim,kglhdpar,kglhdadr,KGLOBHD0,KGLOBHD6 from x$kglob where KGLNAOBJ='select * from scott.emp';
KGLNAOBJ KGLNATIM KGLHDPAR KGLHDADR KGLOBHD0 KGLOBHD6
-------------------------------------------------- ------------------- ---------------- ---------------- ---------------- ----------------
select * from scott.emp 2017-07-07 14:54:52 0000000096AE88B0 00000000958B9A40 0000000096AE85D8 000000007713C758
select * from scott.emp 2017-07-07 14:54:52 0000000096AE88B0 0000000096AE88B0 0000000095871858 00
x$kglcursor_child_sqlid (只包含子游标信息)
SQL> select kglnaobj,kglnatim,kglhdpar,kglhdadr,KGLOBHD0,KGLOBHD6 from x$kglcursor_child_sqlid where KGLNAOBJ='select * from scott.emp';
KGLNAOBJ KGLNATIM KGLHDPAR KGLHDADR KGLOBHD0 KGLOBHD6
-------------------------------------------------- ------------------- ---------------- ---------------- ---------------- ----------------
select * from scott.emp 2017-07-07 14:54:52 0000000096AE88B0 00000000958B9A40 0000000096AE85D8 000000007713C758
0000000096AE88B0 为select * from scott.emp; 父游标句柄地址,00000000958B9A40为子游标句柄地址
子游标heap 6(KGLOBHD6)的地址为000000007713C758,句柄中存储的也就是执行计划相关的信息。
通过以上测试我们很容易找到sql的父游标的句柄还有子游标的句柄在内存中的地址。
下面做另外一个简单的测试解析错误的SQL是否有父游标和子游标生成。
SQL> select * from test;
select * from test
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> select kglnaobj,kglnatim,kglhdpar,kglhdadr,KGLOBHD0,KGLOBHD6 from x$kglob where KGLNAOBJ='select * from test';
KGLNAOBJ KGLNATIM KGLHDPAR KGLHDADR KGLOBHD0 KGLOBHD6
-------------------------------------------------- ------------------- ---------------- ---------------- ---------------- ----------------
select * from test 2017-07-07 15:06:28 0000000097DDC190 0000000097F941F8 00 00
select * from test 2017-07-07 15:06:28 0000000097DDC190 0000000097DDC190 000000009E035698 00
SQL> select kglnaobj,kglnatim,kglhdpar,kglhdadr,KGLOBHD0,KGLOBHD6 from x$kglcursor_child_sqlid where KGLNAOBJ='select * from test';
no rows selected
可以看到没有子游标生成,因为该SQL执行错误不会有执行计划相关信息。
从x$kglob 也可以查到 kglobhd0、kglobhd6 都为空(NULL)。
在 x$kglcursor_child 视图也查不到任何信息的,v$sql v$sqlare 类似的视图也就查不到解析错误的 SQL 了。
关于解析失败的SQL还是需要获取latch,其实从上面的测试已经证明了还是要获取 shared pool 的 latch的,因为生成了父游标。
通过以上测试说明解析失败的sql只生成了父游标,而没有生成子游标和执行计划信息。
也可以用一下sql查出当前数据库中所有解析失败的sql
select kglnaobj,kglnatim,kglhdpar,kglhdadr,KGLOBHD0,KGLOBHD6 from x$kglob where kglhdpar<>kglhdadr
and KGLOBHD6='00' and KGLOBHD0='00' order by kglnatim desc;
从整个过程来看即使解析失败父游标是需要分配空间的,如果没有使用绑定变量的情况下需要大量的分配
内存空间来保存这些解析失败语句的父游标,它不仅会持有latch:libary cache而且会持有latch:shared
pool.
最后猜测一下:
KGLNAOBJ KGLNATIM KGLHDPAR KGLHDADR KGLOBHD0 KGLOBHD6
-------------------------------------------------- ------------------- ---------------- ---------------- ---------------- ----------------
select * from scott.emp 2017-07-07 14:54:52 0000000096AE88B0 00000000958B9A40 0000000096AE85D8 000000007713C758
SQL> select ksmchptr,ksmchcom,ksmchcls,ksmchsiz from x$ksmsp where KSMCHPAR='0000000096AE85D8';
KSMCHPTR KSMCHCOM KSMCHCLS KSMCHSIZ
---------------- ------------------------------------------------ ------------------------ ----------
000000007713AFD8 KGLH0^31fa0cc recr 4096(chunk 大小)
如上:
KGLHDADR:应该为整个游标结构体(句柄)的虚拟内存地址其地址为00000000958B9A40
KGLHDPAR:为父游标构体(句柄的)的虚拟内存地址其地址为0000000096AE88B0
而父游标的KGLHDPAR和KGLHDADR相等,子游标KGLHDPAR为父游标构体(句柄的)的虚拟内存地址,KGLHDADR为自己的
游标构体(句柄的)的虚拟内存地址
在这个结构体中有一根指针指向void* p 指向heap 0 ds描述符的内存空间,虚拟内存地址为0000000096AE85D8
ds描述符:应该也是一个结构体其中又有一根指针void* p 指向heap 0实际的虚拟内存地址为000000007713AFD8
那么heap0实际的地址为000000007713AFD8
比如:
struct ds
{
KSMCHCOM;
KSMCHCLS;
KSMCHSIZ;
.........
void* p;
}
怎么找出解析失败的sql的更多相关文章
- SQLServer找出执行慢的SQL语句
SELECT (total_elapsed_time / execution_count)/1000 N'平均时间ms' ,total_elapsed_time/1000 N'总花费时间ms' , ...
- MySQL Innodb如何找出阻塞事务源头SQL
在MySQL数据库中出现了阻塞问题,如何快速查找定位问题根源?在实验开始前,我们先梳理一下有什么工具或命令查看MySQL的阻塞,另外,我们也要一一对比其优劣,因为有些命令可能在实际环境下可能并不适用. ...
- Oracle DB 12.2(12cR2)的一个新特性:硬解析失败的SQL语句(需要符合一定条件)打印到alert_sid.log中.
How to Identify Hard Parse Failures (Doc ID 1353015.1)Bug 16945190 - Diagnostic enhancement to dump ...
- 在百万数据中找出重复的数据sql
select * from (select count(name) as isone, name from tbl_org_departments group by name) t where t.i ...
- (转载)处理SQL解析失败导致share pool 的争用
通过关联x$kglcursorx$kglcursor_child_sqlid视图: 通过使用Oracle10035Event事件可以找到解析失败的SQL: 通过oraclesystemdump也可以找 ...
- 在一个SQL Server表中的多个列找出最大值
在一个SQL Server表中一行的多个列找出最大值 有时候我们需要从多个相同的列里(这些列的数据类型相同)找出最大的那个值,并显示 这里给出一个例子 IF (OBJECT_ID('tempdb..# ...
- 如何找出你性能最差的SQL Server查询
我经常会被反复问到这样的问题:”我有一个性能很差的SQL Server.我如何找出最差性能的查询?“.因此在今天的文章里会给你一些让你很容易找到问题答案的信息向导. 问SQL Server! SQL ...
- [SQL]透過redgate SQL Monitor 來找出 ASYNC_NETWORK_IO 問題
原文:[SQL]透過redgate SQL Monitor 來找出 ASYNC_NETWORK_IO 問題 最近因為在查一個SQL的效能問題,透過 sys.dm_os_wait_stats 來取得To ...
- 找出sql脚本中需要创建的表空间名称和数据库用户名
测试的工作中,经常会遇到项目交接或者搭建一个新的测试环境,而创建oracle数据库用户及表空间时,需要提前找出脚本中的 数据库用户名和表空间名,所以自己写了一个python脚本,自动找出sql脚本中的 ...
随机推荐
- linux—jdk 安装步骤
1. 查看现有版本 java -version 2. 查看jdk的具体版本 rpm –qa| grep jdk rpm –qa| grep gcj 3. ...
- C++ STL标准模板库(queue)
//queue的使用 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<queue> using name ...
- 什么是ORM,以及在php上的使用?
ORM:object relation mapping,即对象关系映射,简单的说就是对象模型和关系模型的一种映射.为什么要有这么一个映射?很简单,因为现在的开发语言基本都是oop的,但是传统的数据库却 ...
- Yii2 选择布局的方式
方案1:控制器内成员变量 public $layout = false; //不使用布局 public $layout = "main"; //设置使用的布局文件 方案2:控制器成 ...
- js禁止别人查看源码
1.直接按F12 2.Ctrl+Shift+I查看 3.鼠标点击右键查看 4.Ctrl+u=view-source:+url 把以上三种状态都屏蔽掉就可以了,document有onkeydown(键盘 ...
- Oozie安装与部署
原创文章,转载请注明: 转载自http://www.cnblogs.com/tovin/p/3885162.html 安装基础环境: Hadoop – 2.2.0 Linux – Centos 6. ...
- WPF界面框架的设计
http://www.cnblogs.com/baihmpgy/p/osgi_muinavtree_fx.html
- 使用 Visual Studio 2015 编译 QT 工程
简单进行一下几步就可以了 1.下载源代码 qt-everywhere-opensource-src-5.6.0-alpha.7z .解压到 D:\ToolKits\5.6.0\src 目录下2.网站 ...
- 【BZOJ4367】[IOI2014]holiday假期 分治+主席树
[BZOJ4367][IOI2014]holiday假期 Description 健佳正在制定下个假期去台湾的游玩计划.在这个假期,健佳将会在城市之间奔波,并且参观这些城市的景点.在台湾共有n个城市, ...
- Thrift初试
Restful 基于 Http 进行通讯. 开放.标准.简单.兼容性升级容易: 性能略低.在 QPS 高或者对响应时间要求苛刻的服务上,可以用 RPC,RPC采用二进制传输.TCP 通讯,所以通常性能 ...