细致入微:Oracle中执行计划在Shared Pool中的存储位置探秘

这两天我一直在想一个问题,那就是 Oracle 的执行计划到底存储在什么地儿?它会是一种什么样的格式?

这里我试图对这个问题做一点我自己认为的解释,这个解释可能是有问题的。

朋友们在看这篇文章之前,应该首先熟悉如下的这张图:

怎样才叫熟悉这张图呢?我认为验证的方法就是看你是否能够仅仅看着这张图,在1个小时的时间内把这张图的内容解释清楚。

这张图也许能够用来衡量你对 library cache 的了解程度。

我们现在做的测试其实就来源于上面这张图:

首先执行一下下述的 sql:

SQL_testdb>select * from scott.emp;

接着查一下上述 sql 在 library cache中的library cache object handle 的地址,一下两种方式都可以获取 SQL 语句父游标地址:

SQL_testdb>select address,sql_text from v$sqlarea where sql_text like ‘select * from scott.emp%’;

然后我们 dump 一下 library cache,注意这里level一定要大于等于8,否则看不到heap 0的内容:

SQL_testdb>alter session set events ‘immediate trace name library_cache level 11’; Session altered. SQL_testdb>oradebug setmypid Statement processed. SQL_testdb>oradebug tracefile_name /cadrasu01/app/oracle/admin/testdb/udump/testdb_ora_4128918.trc

从上述trace文件中我们以 070000001CAE2C70 为关键字去查询,查询结果如下:

注意看上述 library cache object 的类型是 cursor,名字是 select * from scott.emp,它有一个子 cursor,其 library cache object handle 的地址是 70000001cae15e0。我们现在就以这个地址继续搜索上述 trace 文件,搜到的内容如下:

从上述内容中我们可以看到,子 cursor 是没有名字的,这个其实很正常——因为 Oracle 是通过先访问其 parent cursor 后才会来访问它。

另外,这个子 cursor 只有两个 data block,分别是 data block 0 和 data block 6,对应的就是上图中的 heap 0 和 heap 6。

我首先排除掉 heap 0,理由如下:

The data block structure for a heap, stored in heap 0, contains a pointer to the first data block that is allocated for the heap, a status indicator, the pin under which the heap is loaded, and so on.

那么剩下的就只有一种可能,就是 Oracle 把 sql 的执行计划存储在了 heap 6里。

接下来我们 dump一下 heap 6 的内容:

SQL_testdb>oradebug setmypid Statement processed. SQL_testdb>alter session set events ‘immediate trace name heapdump_addr level 2, addr0x70000001cae1328′; Session altered. SQL_testdb>oradebug tracefile_name /cadrasu01/app/oracle/admin/testdb/udump/testdb_ora_2859106.trc

从上述 trace文件中我们可以看到如下的内容:

上述 trace 文件的内容告诉我们 heap 6 实际上就是 sql area(这个和上图中描述的 heap 6是 sql context 不尽相同),剩下的内容除了我们能看出包含了表 scott.emp 的各个字段的内容之外,其他的就看不懂了。

我猜测 Oracle 把 sql 的执行计划存在了这个 sql 的子 cursor 的 heap 6(也就是 sql area)中,只不过存储的形式是编译好的二进制格式。

感谢 MOS,让我找到了如下的论据,可以在某种程度上让我自圆其说:

Parsing a cursor builds four different library cache structures, if they do not already exist, within the library cache: 1、parent cursor handle 2、parent cursor object, containing the child dependency list 3、child cursor handle, inserted in the child dependency list of the parent object 4、child cursor object, containing the compilation and run-time execution plan for the compiled SQL statement.

原文发布于微信公众号 - 数据和云(OraNews)

原文发表时间:2016-07-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏我是攻城师

Elasticsearch的Mapping之元数据类型

2906
来自专栏Spark学习技巧

Kafka源码系列之实现自己的kafka监控

一,基本思路介绍 Kafka作为一个好用的且应用很广泛的消息队列,在大数据处理系统中基本是必不可少的。当然,作为缓存消息的消息队列,我们对其进行流量监控及消费滞...

4605
来自专栏架构师之路

龙神教你“如何做系统性能优化”

性能优化的目标是什么?不外乎两个: 时间性能:减小系统执行的时间 空间性能:减小系统占用的空间 一、代码优化 做代码优化前,先了解下硬件Cache: (1)C...

2777
来自专栏北京马哥教育

SQLAlchemy基本使用

云豆贴心提醒,本文阅读时间6分钟,文末有秘密! ORM介绍 ORM(Object-Relational Mapping) 架构,采用元数据来描述对象-关系映射...

3697
来自专栏cloudskyme

C++动态链接库

动态链接库 动态链接库英文为DLL,是Dynamic Link Library 的缩写形式,DLL 是一个包含可由多个程序同时使用的代码和数据的库,DLL不是可...

3985
来自专栏学习力

《Java从入门到放弃》框架入门篇:hibernate中的多表对应关系

2027
来自专栏匠心独运的博客

消息中间件—RocketMQ消息存储(二)一、RocketMQ存储整体设计架构回顾二、RocketMQ存储关键技术—再谈Mmap与PageCache三、RocketMQ存储优化技术四、RocketMQ

文章摘要:上篇中主要介绍了RocketMQ存储部分的整体架构设计,本篇将深入分析RocketMQ存储部分的细节内容 在本篇文章中,小编将继续深入分析与介绍Ro...

892
来自专栏杨建荣的学习笔记

在线重定义的补充测试(r10笔记第26天)

在很多时候,我们都是需要保持业务的可持续性,尽管说DDL的过程持续时间很短,但是在线业务出现,就会阻塞DML,导致业务访问中断,事务收到影响,所以在有些...

3328
来自专栏架构师之路

58龙哥教你“如何做系统性能优化”(纯干货)

如何做系统性能优化 性能优化的目标是什么?不外乎两个: 时间性能:减小系统执行的时间 空间性能:减小系统占用的空间 一、代码优化 做代码优化前,先了解下硬件Ca...

2884
来自专栏美团技术团队

缓存那些事

前言 一般而言,现在互联网应用(网站或App)的整体流程,可以概括如图1所示,用户请求从界面(浏览器或App界面)到网络转发、应用服务再到存储(数据库或文件系统...

4754

扫码关注云+社区